Skip to content

Tilesets native zoom #792

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

Merged
merged 7 commits into from
Dec 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions folium/folium.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class Map(MacroElement):
Minimum allowed zoom level for the tile layer that is created.
max_zoom: int, default 18
Maximum allowed zoom level for the tile layer that is created.
max_native_zoom: int, default None
The highest zoom level at which the tile server can provide tiles.
If provided you can zoom in past this level. Else tiles will turn grey.
zoom_start: int, default 10
Initial zoom level for the map.
attr: string, default None
Expand Down Expand Up @@ -166,7 +169,7 @@ class Map(MacroElement):
def __init__(self, location=None, width='100%', height='100%',
left='0%', top='0%', position='relative',
tiles='OpenStreetMap', API_key=None, max_zoom=18, min_zoom=0,
zoom_start=10, world_copy_jump=False,
max_native_zoom=None, zoom_start=10, world_copy_jump=False,
no_wrap=False, attr=None, min_lat=-90, max_lat=90,
min_lon=-180, max_lon=180, max_bounds=False,
detect_retina=False, crs='EPSG3857', control_scale=False,
Expand Down Expand Up @@ -216,7 +219,7 @@ def __init__(self, location=None, width='100%', height='100%',
if tiles:
self.add_tile_layer(
tiles=tiles, min_zoom=min_zoom, max_zoom=max_zoom,
no_wrap=no_wrap, attr=attr,
max_native_zoom=max_native_zoom, no_wrap=no_wrap, attr=attr,
API_key=API_key, detect_retina=detect_retina,
subdomains=subdomains
)
Expand Down Expand Up @@ -312,7 +315,7 @@ def _repr_png_(self):

def add_tile_layer(self, tiles='OpenStreetMap', name=None,
API_key=None, max_zoom=18, min_zoom=0,
attr=None, active=False,
max_native_zoom=None, attr=None, active=False,
detect_retina=False, no_wrap=False, subdomains='abc',
**kwargs):
"""
Expand All @@ -321,6 +324,7 @@ def add_tile_layer(self, tiles='OpenStreetMap', name=None,
"""
tile_layer = TileLayer(tiles=tiles, name=name,
min_zoom=min_zoom, max_zoom=max_zoom,
max_native_zoom=max_native_zoom,
attr=attr, API_key=API_key,
detect_retina=detect_retina,
subdomains=subdomains,
Expand Down
43 changes: 22 additions & 21 deletions folium/raster_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,22 @@ class TileLayer(Layer):
tiles: str, default 'OpenStreetMap'
Map tileset to use. Can choose from this list of built-in tiles:
- "OpenStreetMap"
- "Mapbox Bright" (Limited levels of zoom for free tiles)
- "Mapbox Control Room" (Limited levels of zoom for free tiles)
- "Stamen" (Terrain, Toner, and Watercolor)
- "Stamen Terrain", "Stamen Toner", "Stamen Watercolor"
- "CartoDB positron", "CartoDB dark_matter"
- "Mapbox Bright", "Mapbox Control Room" (Limited zoom)
- "Cloudmade" (Must pass API key)
- "Mapbox" (Must pass API key)
- "CartoDB" (positron and dark_matter)

You can pass a custom tileset to Folium by passing a Leaflet-style
URL to the tiles parameter: ``http://{s}.yourtiles.com/{z}/{x}/{y}.png``
You must then also provide attribution, use the `attr` keyword.
min_zoom: int, default 0
Minimum allowed zoom level for this tile layer.
max_zoom: int, default 18
Maximum allowed zoom level for this tile layer.
max_native_zoom: int, default None
The highest zoom level at which the tile server can provide tiles.
If provided you can zoom in past this level. Else tiles will turn grey.
attr: string, default None
Map tile attribution; only required if passing custom tile URL.
API_key: str, default None
Expand All @@ -63,8 +66,8 @@ class TileLayer(Layer):

"""
def __init__(self, tiles='OpenStreetMap', min_zoom=0, max_zoom=18,
attr=None, API_key=None, detect_retina=False,
name=None, overlay=False,
max_native_zoom=None, attr=None, API_key=None,
detect_retina=False, name=None, overlay=False,
control=True, no_wrap=False, subdomains='abc'):
self.tile_name = (name if name is not None else
''.join(tiles.lower().strip().split()))
Expand All @@ -73,33 +76,31 @@ def __init__(self, tiles='OpenStreetMap', min_zoom=0, max_zoom=18,
self._name = 'TileLayer'
self._env = ENV

options = {
'minZoom': min_zoom,
'maxZoom': max_zoom,
'noWrap': no_wrap,
'attribution': attr,
'subdomains': subdomains,
'detectRetina': detect_retina,
}
options = {'minZoom': min_zoom,
'maxZoom': max_zoom,
'maxNativeZoom': max_native_zoom or max_zoom,
'noWrap': no_wrap,
'attribution': attr,
'subdomains': subdomains,
'detectRetina': detect_retina}
self.options = json.dumps(options, sort_keys=True, indent=2)

self.tiles = ''.join(tiles.lower().strip().split())
if self.tiles in ('cloudmade', 'mapbox') and not API_key:
tiles_flat = ''.join(tiles.lower().strip().split())
if tiles_flat in ('cloudmade', 'mapbox') and not API_key:
raise ValueError('You must pass an API key if using Cloudmade'
' or non-default Mapbox tiles.')
templates = list(self._env.list_templates(
filter_func=lambda x: x.startswith('tiles/')))
tile_template = 'tiles/'+self.tiles+'/tiles.txt'
attr_template = 'tiles/'+self.tiles+'/attr.txt'
tile_template = 'tiles/' + tiles_flat + '/tiles.txt'
attr_template = 'tiles/' + tiles_flat + '/attr.txt'

if tile_template in templates and attr_template in templates:
self.tiles = self._env.get_template(tile_template).render(API_key=API_key) # noqa
self.attr = self._env.get_template(attr_template).render()
else:
self.tiles = tiles
if not attr:
raise ValueError('Custom tiles must'
' also be passed an attribution.')
raise ValueError('Custom tiles must have an attribution.')
if isinstance(attr, binary_type):
attr = text_type(attr, 'utf8')
self.attr = attr
Expand All @@ -111,7 +112,7 @@ def __init__(self, tiles='OpenStreetMap', min_zoom=0, max_zoom=18,
{{ this.options }}
).addTo({{this._parent.get_name()}});
{% endmacro %}
""") # noqa
""")


class WmsTileLayer(Layer):
Expand Down
11 changes: 10 additions & 1 deletion tests/test_raster_layers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-

"""
Test ImageOverlay
Test raster_layers
-----------------

"""
Expand Down Expand Up @@ -36,6 +36,15 @@ def test_tile_layer():
assert bounds == [[None, None], [None, None]], bounds


def _is_working_zoom_level(zoom, tiles, session):
"""Check if the zoom level works for the given tileset."""
url = tiles.format(s='a', x=0, y=0, z=zoom)
response = session.get(url, timeout=5)
if response.status_code < 400:
return True
return False


def test_custom_tile_subdomains():
"""Test custom tile subdomains."""

Expand Down