Skip to content

Support xyzservices.TileProvider as an input of tiles #1497

@martinfleis

Description

@martinfleis

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()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions