Skip to content

Commit

Permalink
Simplify max_zoom logics in Map and TileLayer
Browse files Browse the repository at this point in the history
  • Loading branch information
HaudinFlorence committed Apr 16, 2022
1 parent 98d570e commit 371b654
Show file tree
Hide file tree
Showing 8 changed files with 434 additions and 30 deletions.
3 changes: 2 additions & 1 deletion docs/source/layers/tile_layer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ Sometimes one could want to specify the date of the given images, for instance w
Attributes and methods
----------------------

Note that if you want to display a high resolution layer with a quite large zoom, you have to set ``max_zoom`` and ``max_native_zoom`` with equal value.
An example is given here (to be added).
.. autoclass:: ipyleaflet.leaflet.TileLayer
:members:

113 changes: 113 additions & 0 deletions examples/Max_zoom_tests.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"id": "202a6acf-96fc-4632-bcd3-7e7156cbec51",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "26f3895c081d435b8d54e8715868ffc5",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Map(center=[18.025455316051108, -63.04952812733164], controls=(ZoomControl(options=['position', 'zoom_in_text'…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# TEST ON THE MAP ALONE\n",
"from localtileserver import examples, get_leaflet_tile_layer, TileClient\n",
"from ipyleaflet import Map\n",
"\n",
"# Create a tile server from an raster URL\n",
"oam = TileClient('https://oin-hotosm.s3.amazonaws.com/59c66c5223c8440011d7b1e4/0/7ad397c0-bba2-4f98-a08a-931ec3a6e943.tif')\n",
"\n",
"# Create ipyleaflet map, add layers, add controls, and display\n",
"m1 = Map(center=oam.center(),zoom=18, max_zoom=24)\n",
"m1"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "3d28ceb8-50ea-457e-896b-672870ea9573",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "eb394a9e3f734fefb2d7f713bff5bddd",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Map(center=[18.025455316051108, -63.04952812733164], controls=(ZoomControl(options=['position', 'zoom_in_text'…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from localtileserver import examples, get_leaflet_tile_layer, TileClient\n",
"from ipyleaflet import Map\n",
"\n",
"# Create a tile server from an raster URL\n",
"oam = TileClient('https://oin-hotosm.s3.amazonaws.com/59c66c5223c8440011d7b1e4/0/7ad397c0-bba2-4f98-a08a-931ec3a6e943.tif')\n",
"\n",
"# Create ipyleaflet TileLayer from that server\n",
"# Please note that all extra kwargs are passed to `TileLayer`\n",
"oam_layer = get_leaflet_tile_layer(oam, max_zoom=30, max_native_zoom=30, show_loading=True)\n",
"\n",
"# Create ipyleaflet map, add layers, add controls, and display\n",
"m = Map(center=oam.center(), zoom=18, max_zoom=30)\n",
"m.add_layer(oam_layer)\n",
"m"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ce2d1bfb-25f8-4f13-a500-5db618583781",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "144dde31-cb4a-4755-a98f-17fcf4c805e0",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
6 changes: 3 additions & 3 deletions examples/MeasureControl.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -77,9 +77,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
"version": "3.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}
33 changes: 17 additions & 16 deletions ipyleaflet/leaflet.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def basemap_to_tiles(basemap, day=yesterday, **kwargs):

return TileLayer(
url=url,
max_zoom=basemap.get('max_zoom', 19),
max_zoom=basemap.get('max_zoom', 18),
min_zoom=basemap.get('min_zoom', 1),
attribution=basemap.get('html_attribution', '') or basemap.get('attribution', ''),
name=basemap.get('name', ''),
Expand Down Expand Up @@ -549,11 +549,13 @@ class TileLayer(RasterLayer):
url: string, default "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
Url to the tiles service.
min_zoom: int, default 0
Minimum zoom for this tile service.
The minimum zoom level down to which this layer will be displayed (inclusive).
max_zoom: int, default 18
Maximum zoom for this tile service.
min_native_zoom: int, default 0
max_native_zoom: int, default 18
The maximum zoom level up to which this layer will be displayed (inclusive).
min_native_zoom: int, default None
Minimum zoom number the tile source has available. If it is specified, the tiles on all zoom levels lower than minNativeZoom will be loaded from minNativeZoom level and auto-scaled.
max_native_zoom: int, default None
Maximum zoom number the tile source has available. If it is specified, the tiles on all zoom levels higher than maxNativeZoom will be loaded from maxNativeZoom level and auto-scaled.
bounds: list or None, default None
List of SW and NE location tuples. e.g. [(50, 75), (75, 120)].
tile_size: int, default 256
Expand All @@ -580,8 +582,8 @@ class TileLayer(RasterLayer):
url = Unicode('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').tag(sync=True)
min_zoom = Int(0).tag(sync=True, o=True)
max_zoom = Int(18).tag(sync=True, o=True)
min_native_zoom = Int(0).tag(sync=True, o=True)
max_native_zoom = Int(18).tag(sync=True, o=True)
min_native_zoom = Int(default_value=None, allow_none=True).tag(sync=True, o=True)
max_native_zoom = Int(default_value=None, allow_none=True).tag(sync=True, o=True)
bounds = List(default_value=None, allow_none=True, help='list of SW and NE location tuples').tag(sync=True, o=True)
tile_size = Int(256).tag(sync=True, o=True)
attribution = Unicode('Map data (c) <a href="https://openstreetmap.org">OpenStreetMap</a> contributors').tag(
Expand Down Expand Up @@ -2007,13 +2009,13 @@ class Map(DOMWidget, InteractMixin):
The list of layers that are currently on the map.
controls: list of Control instances
The list of controls that are currently on the map.
center: list, default [0, 0]
center: list, default None
The current center of the map.
zoom: float, default 12
zoom: float, default None
The current zoom value of the map.
max_zoom: int, default 18
max_zoom: float, default None
Maximal zoom value.
min_zoom: int, default 1
min_zoom: float, default None
Minimal zoom value.
zoom_snap: float, default 1
Forces the map’s zoom level to always be a multiple of this.
Expand Down Expand Up @@ -2070,11 +2072,10 @@ class Map(DOMWidget, InteractMixin):
window_url = Unicode(read_only=True).tag(sync=True)

# Map options
center = List(def_loc).tag(sync=True, o=True)
zoom_start = CFloat(12).tag(sync=True, o=True)
zoom = CFloat(12).tag(sync=True, o=True)
max_zoom = CFloat(18).tag(sync=True, o=True)
min_zoom = CFloat(1).tag(sync=True, o=True)
center = List(default_value=None, allow_none=True).tag(sync=True, o=True)
zoom = CFloat(default_value=None, allow_none=True).tag(sync=True, o=True)
max_zoom = CFloat(default_value=None, allow_none=True).tag(sync=True, o=True)
min_zoom = CFloat(default_value=None, allow_none=True).tag(sync=True, o=True)
zoom_delta = CFloat(1).tag(sync=True, o=True)
zoom_snap = CFloat(1).tag(sync=True, o=True)
interpolation = Unicode('bilinear').tag(sync=True, o=True)
Expand Down
36 changes: 30 additions & 6 deletions js/src/Map.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { TileLayer } from 'leaflet';

const widgets = require('@jupyter-widgets/base');
const L = require('./leaflet.js');
const utils = require('./utils.js');
Expand Down Expand Up @@ -36,11 +38,10 @@ export class LeafletMapModel extends widgets.DOMWidgetModel {
_model_name: 'LeafletMapModel',
_model_module: 'jupyter-leaflet',
_view_module: 'jupyter-leaflet',
center: DEFAULT_LOCATION,
zoom_start: 12,
zoom: 12,
max_zoom: 18,
min_zoom: 1,
center: null,
zoom: null,
max_zoom: null,
min_zoom: null,
dragging: true,
touch_zoom: true,
zoom_delta: 1,
Expand Down Expand Up @@ -352,7 +353,30 @@ export class LeafletMapView extends utils.LeafletDOMWidgetView {
this.dirty = false;
}
this.model.update_bounds().then(() => {
this.touch();
this.listenTo(
this.model,
'change:zoom',
function () {
if (!this.dirty) {
this.dirty = true;
// Using flyTo instead of setZoom to adjust for potential
// sub-pixel error in leaflet object's center.
//
// Disabling animation on updates from the model because
// animation triggers a `moveend` event in an animationFrame,
// which causes the center to bounce despite of the dirty flag
// which is set back to false synchronously.
this.obj.flyTo(this.model.get('center'), this.model.get('zoom'), {
animate: false
});
this.dirty = false;
}
this.model.update_bounds().then(() => {
this.touch();
});
},
this
); this.touch();
});
},
this
Expand Down
2 changes: 2 additions & 0 deletions js/src/layers/TileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export class LeafletTileLayerModel extends rasterlayer.LeafletRasterLayerModel {
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
min_zoom: 0,
max_zoom: 18,
min_native_zoom: null,
max_native_zoom: null,
bounds: null,
tile_size: 256,
attribution:
Expand Down
4 changes: 3 additions & 1 deletion js/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class leafletViewCommon {
for (var i = 0; i < o.length; i++) {
key = o[i];
// Convert from foo_bar to fooBar that Leaflet.js uses
options[camel_case(key)] = this.model.get(key);
if (this.model.get(key) !== null) {
options[camel_case(key)] = this.model.get(key);
}
}
return options;
}
Expand Down
Loading

0 comments on commit 371b654

Please sign in to comment.