Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support xyzservices.TileProvider as an input of tiles #1497

Closed
martinfleis opened this issue Aug 7, 2021 · 2 comments · Fixed by #1498
Closed

Support xyzservices.TileProvider as an input of tiles #1497

martinfleis opened this issue Aug 7, 2021 · 2 comments · Fixed by #1498

Comments

@martinfleis
Copy link
Collaborator

Is your feature request related to a problem? Please describe.

With the @geopandas team, we have built a new package called xyzservices to serve as a unified place for XYZ tile management. The idea behind this is that other packages will depend on that instead of having their own system and list of supported tiles hard-coded. It would be great to have folium on board with the idea, by supporting xyzservices.TileProvider as an input of tiles.

xyzservices itself does not have any dependencies which makes it a non-problematic dependency.

It is worth mentioning that xyzservices stores providers' metadata in JSON under share, accessible for anyone if you have a use case for that.

I am happy to do any changes in xyzservices needed to make it as useful for you as possible if that allows centralising maintenance of providers in one place.

Describe the solution you'd like

I'd like to see the support of TileProvider as an input of tiles and TileLayer.

import xyzservices.providers as xyz

m = folium.Map(
    location=[53.4108, -2.9358],
    tiles=xyz.CartoDB.Positron,
)
folium.TileLayer(tiles=xyz.CartoDB.Positron).add_to(m)

All the info TileLayer require can be fetched from the TileProvider object under the hood.

Describe alternatives you've considered

You can pass individual attributes manually as we currently do in xyzservices docs but it can be streamlined with a built-in support.

tiles = xyz.CartoDB.Positron

folium.Map(
    location=[53.4108, -2.9358],
    tiles=tiles.build_url(scale_factor="@2x"),
    attr=tiles.html_attribution,
)

Additional context

Support of xyzservices is being implemented across the ecosystem, from geopandas' own packages (new built-in foilum-based plotting (geopandas/geopandas#1953) and contextily) to leafmap (opengeos/leafmap#91), ipyleaflet (jupyter-widgets/ipyleaflet#854) and holoviews (holoviz/holoviews#5057) (+ hopefully more).

If there's anything we would need to implement in xyzservices to make all this work, I am all ears.

Implementation

I am happy to contribute this as a PR.

In this case, it is actually quite simple and can be done without importing xyzservices as TileProvider is a subclass of dict. Something along this:

if isinstance(tiles, dict):
     attr = attr if attr else tiles.html_attribution
     min_zoom = tiles.get("min_zoom", 0)
     max_zoom = tiles.get("max_zoom", 18)
     tiles = tiles.build_url()
@ocefpaf
Copy link
Member

ocefpaf commented Aug 7, 2021

I am happy to contribute this as a PR.

I've been planning to open this issue since you announced xyzservices on Twitter :-)

If you have the time for the PR please do send it in our way! It will be an awesome addition to folium.

@Insighttful
Copy link

I came here to see if folium supported xyzservices - and it now does. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants