22Wraps leaflet TileLayer, WmsTileLayer (TileLayer.WMS), ImageOverlay, and VideoOverlay
33
44"""
5- from typing import TYPE_CHECKING , Any , Callable , Optional , Union
5+ from typing import Any , Callable , Optional , Union
66
7+ import xyzservices
78from branca .element import Element , Figure
8- from jinja2 import Environment , PackageLoader , Template
9+ from jinja2 import Template
910
1011from folium .map import Layer
1112from folium .utilities import (
1617 parse_options ,
1718)
1819
19- if TYPE_CHECKING :
20- import xyzservices
21-
22-
23- ENV = Environment (loader = PackageLoader ("folium" , "templates" ))
24-
2520
2621class TileLayer (Layer ):
2722 """
@@ -30,9 +25,14 @@ class TileLayer(Layer):
3025 Parameters
3126 ----------
3227 tiles: str or :class:`xyzservices.TileProvider`, default 'OpenStreetMap'
33- Map tileset to use. Can choose from this list of built-in tiles:
28+ Map tileset to use. Folium has built-in all tilesets
29+ available in the ``xyzservices`` package. For example, you can pass
30+ any of the following to the "tiles" keyword:
31+
3432 - "OpenStreetMap"
35- - "CartoDB positron", "CartoDB dark_matter"
33+ - "CartoDB Positron"
34+ - "CartoBD Voyager"
35+ - "NASAGIBS Blue Marble"
3636
3737 You can pass a custom tileset to Folium by passing a
3838 :class:`xyzservices.TileProvider` or a Leaflet-style
@@ -90,7 +90,7 @@ class TileLayer(Layer):
9090
9191 def __init__ (
9292 self ,
93- tiles : Union [str , " xyzservices.TileProvider" ] = "OpenStreetMap" ,
93+ tiles : Union [str , xyzservices .TileProvider ] = "OpenStreetMap" ,
9494 min_zoom : int = 0 ,
9595 max_zoom : int = 18 ,
9696 max_native_zoom : Optional [int ] = None ,
@@ -104,14 +104,26 @@ def __init__(
104104 subdomains : str = "abc" ,
105105 tms : bool = False ,
106106 opacity : float = 1 ,
107- ** kwargs
107+ ** kwargs ,
108108 ):
109- # check for xyzservices.TileProvider without importing it
110- if isinstance (tiles , dict ):
109+ if isinstance (tiles , str ):
110+ if tiles .lower () == "openstreetmap" :
111+ tiles = "OpenStreetMap Mapnik"
112+ if name is None :
113+ name = "openstreetmap"
114+ try :
115+ tiles = xyzservices .providers .query_name (tiles )
116+ except ValueError :
117+ # no match, likely a custom URL
118+ pass
119+
120+ if isinstance (tiles , xyzservices .TileProvider ):
111121 attr = attr if attr else tiles .html_attribution # type: ignore
112122 min_zoom = tiles .get ("min_zoom" , min_zoom )
113123 max_zoom = tiles .get ("max_zoom" , max_zoom )
114124 subdomains = tiles .get ("subdomains" , subdomains )
125+ if name is None :
126+ name = tiles .name .replace ("." , "" ).lower ()
115127 tiles = tiles .build_url (fill_subdomain = False , scale_factor = "{r}" ) # type: ignore
116128
117129 self .tile_name = (
@@ -122,27 +134,9 @@ def __init__(
122134 )
123135 self ._name = "TileLayer"
124136
125- tiles_flat = "" .join (tiles .lower ().strip ().split ())
126- if tiles_flat in {"cloudmade" , "mapbox" , "mapboxbright" , "mapboxcontrolroom" }:
127- # added in May 2020 after v0.11.0, remove in a future release
128- raise ValueError (
129- "Built-in templates for Mapbox and Cloudmade have been removed. "
130- "You can still use these providers by passing a URL to the `tiles` "
131- "argument. See the documentation of the `TileLayer` class."
132- )
133- templates = list (
134- ENV .list_templates (filter_func = lambda x : x .startswith ("tiles/" ))
135- )
136- tile_template = "tiles/" + tiles_flat + "/tiles.txt"
137- attr_template = "tiles/" + tiles_flat + "/attr.txt"
138-
139- if tile_template in templates and attr_template in templates :
140- self .tiles = ENV .get_template (tile_template ).render ()
141- attr = ENV .get_template (attr_template ).render ()
142- else :
143- self .tiles = tiles
144- if not attr :
145- raise ValueError ("Custom tiles must have an attribution." )
137+ self .tiles = tiles
138+ if not attr :
139+ raise ValueError ("Custom tiles must have an attribution." )
146140
147141 self .options = parse_options (
148142 min_zoom = min_zoom ,
@@ -154,7 +148,7 @@ def __init__(
154148 detect_retina = detect_retina ,
155149 tms = tms ,
156150 opacity = opacity ,
157- ** kwargs
151+ ** kwargs ,
158152 )
159153
160154
@@ -219,7 +213,7 @@ def __init__(
219213 overlay : bool = True ,
220214 control : bool = True ,
221215 show : bool = True ,
222- ** kwargs
216+ ** kwargs ,
223217 ):
224218 super ().__init__ (name = name , overlay = overlay , control = control , show = show )
225219 self .url = url
@@ -231,7 +225,7 @@ def __init__(
231225 transparent = transparent ,
232226 version = version ,
233227 attribution = attr ,
234- ** kwargs
228+ ** kwargs ,
235229 )
236230 if cql_filter :
237231 # special parameter that shouldn't be camelized
@@ -309,7 +303,7 @@ def __init__(
309303 overlay : bool = True ,
310304 control : bool = True ,
311305 show : bool = True ,
312- ** kwargs
306+ ** kwargs ,
313307 ):
314308 super ().__init__ (name = name , overlay = overlay , control = control , show = show )
315309 self ._name = "ImageOverlay"
@@ -406,7 +400,7 @@ def __init__(
406400 overlay : bool = True ,
407401 control : bool = True ,
408402 show : bool = True ,
409- ** kwargs : TypeJsonValue
403+ ** kwargs : TypeJsonValue ,
410404 ):
411405 super ().__init__ (name = name , overlay = overlay , control = control , show = show )
412406 self ._name = "VideoOverlay"
0 commit comments