2
2
Wraps leaflet TileLayer, WmsTileLayer (TileLayer.WMS), ImageOverlay, and VideoOverlay
3
3
4
4
"""
5
- from typing import TYPE_CHECKING , Any , Callable , Optional , Union
5
+ from typing import Any , Callable , Optional , Union
6
6
7
+ import xyzservices
7
8
from branca .element import Element , Figure
8
- from jinja2 import Environment , PackageLoader , Template
9
+ from jinja2 import Template
9
10
10
11
from folium .map import Layer
11
12
from folium .utilities import (
16
17
parse_options ,
17
18
)
18
19
19
- if TYPE_CHECKING :
20
- import xyzservices
21
-
22
-
23
- ENV = Environment (loader = PackageLoader ("folium" , "templates" ))
24
-
25
20
26
21
class TileLayer (Layer ):
27
22
"""
@@ -30,9 +25,14 @@ class TileLayer(Layer):
30
25
Parameters
31
26
----------
32
27
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
+
34
32
- "OpenStreetMap"
35
- - "CartoDB positron", "CartoDB dark_matter"
33
+ - "CartoDB Positron"
34
+ - "CartoBD Voyager"
35
+ - "NASAGIBS Blue Marble"
36
36
37
37
You can pass a custom tileset to Folium by passing a
38
38
:class:`xyzservices.TileProvider` or a Leaflet-style
@@ -90,7 +90,7 @@ class TileLayer(Layer):
90
90
91
91
def __init__ (
92
92
self ,
93
- tiles : Union [str , " xyzservices.TileProvider" ] = "OpenStreetMap" ,
93
+ tiles : Union [str , xyzservices .TileProvider ] = "OpenStreetMap" ,
94
94
min_zoom : int = 0 ,
95
95
max_zoom : int = 18 ,
96
96
max_native_zoom : Optional [int ] = None ,
@@ -104,14 +104,26 @@ def __init__(
104
104
subdomains : str = "abc" ,
105
105
tms : bool = False ,
106
106
opacity : float = 1 ,
107
- ** kwargs
107
+ ** kwargs ,
108
108
):
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 ):
111
121
attr = attr if attr else tiles .html_attribution # type: ignore
112
122
min_zoom = tiles .get ("min_zoom" , min_zoom )
113
123
max_zoom = tiles .get ("max_zoom" , max_zoom )
114
124
subdomains = tiles .get ("subdomains" , subdomains )
125
+ if name is None :
126
+ name = tiles .name .replace ("." , "" ).lower ()
115
127
tiles = tiles .build_url (fill_subdomain = False , scale_factor = "{r}" ) # type: ignore
116
128
117
129
self .tile_name = (
@@ -122,27 +134,9 @@ def __init__(
122
134
)
123
135
self ._name = "TileLayer"
124
136
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." )
146
140
147
141
self .options = parse_options (
148
142
min_zoom = min_zoom ,
@@ -154,7 +148,7 @@ def __init__(
154
148
detect_retina = detect_retina ,
155
149
tms = tms ,
156
150
opacity = opacity ,
157
- ** kwargs
151
+ ** kwargs ,
158
152
)
159
153
160
154
@@ -219,7 +213,7 @@ def __init__(
219
213
overlay : bool = True ,
220
214
control : bool = True ,
221
215
show : bool = True ,
222
- ** kwargs
216
+ ** kwargs ,
223
217
):
224
218
super ().__init__ (name = name , overlay = overlay , control = control , show = show )
225
219
self .url = url
@@ -231,7 +225,7 @@ def __init__(
231
225
transparent = transparent ,
232
226
version = version ,
233
227
attribution = attr ,
234
- ** kwargs
228
+ ** kwargs ,
235
229
)
236
230
if cql_filter :
237
231
# special parameter that shouldn't be camelized
@@ -309,7 +303,7 @@ def __init__(
309
303
overlay : bool = True ,
310
304
control : bool = True ,
311
305
show : bool = True ,
312
- ** kwargs
306
+ ** kwargs ,
313
307
):
314
308
super ().__init__ (name = name , overlay = overlay , control = control , show = show )
315
309
self ._name = "ImageOverlay"
@@ -406,7 +400,7 @@ def __init__(
406
400
overlay : bool = True ,
407
401
control : bool = True ,
408
402
show : bool = True ,
409
- ** kwargs : TypeJsonValue
403
+ ** kwargs : TypeJsonValue ,
410
404
):
411
405
super ().__init__ (name = name , overlay = overlay , control = control , show = show )
412
406
self ._name = "VideoOverlay"
0 commit comments