From f19044abd65928c05c25737ce9392f9859075d1a Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Fri, 28 Jun 2024 10:14:54 -0700 Subject: [PATCH 01/12] Add renderer_factory option --- python/ipyleaflet/ipyleaflet/leaflet.py | 2 ++ python/jupyter_leaflet/src/layers/VectorTileLayer.ts | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index f68039dc..8efa8650 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1110,6 +1110,7 @@ class VectorTileLayer(Layer): Opacity of the layer between 0. (fully transparent) and 1. (fully opaque). visible: boolean, default True Whether the layer is visible or not. + renderer_factory: rendererFactory option ('svg' or 'canvas') for L.VectorGrid, default 'svg' """ _view_name = Unicode("LeafletVectorTileLayerView").tag(sync=True) @@ -1125,6 +1126,7 @@ class VectorTileLayer(Layer): max_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) + renderer_factory = Unicode('svg').tag(sync=True, o=True) def redraw(self): """Force redrawing the tiles. diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 6866d045..834c9aee 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -20,6 +20,7 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { interactive: true, visible: true, opacity: 1.0, + renderer_factory: 'svg', }; } } @@ -31,7 +32,12 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { let options = { ...this.get_options(), }; - options['rendererFactory'] = L.canvas.tile; + let r: any = options['rendererFactory']; + if (r === 'canvas') { + options['rendererFactory'] = L.canvas.tile; + } else { + options['rendererFactory'] = L.svg.tile; + } let x: any = options['vectorTileLayerStyles']; if (typeof x === 'string') { From 6ffcaefee99cebcf70f26f3f88a0b3758349c4cb Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Tue, 2 Jul 2024 09:56:44 -0700 Subject: [PATCH 02/12] Update docstring for interactive, default False --- python/ipyleaflet/ipyleaflet/leaflet.py | 7 +++++-- python/jupyter_leaflet/src/layers/VectorTileLayer.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index 8efa8650..5b46cedf 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1111,6 +1111,8 @@ class VectorTileLayer(Layer): visible: boolean, default True Whether the layer is visible or not. renderer_factory: rendererFactory option ('svg' or 'canvas') for L.VectorGrid, default 'svg' + interactive: boolean, default False + Whether the layer is interactive or not. """ _view_name = Unicode("LeafletVectorTileLayerView").tag(sync=True) @@ -1120,8 +1122,9 @@ class VectorTileLayer(Layer): attribution = Unicode().tag(sync=True, o=True) vector_tile_layer_styles = Union([Dict(), Unicode()]).tag(sync=True, o=True) - opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True) - visible = Bool(True).tag(sync=True) + opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True,o=True) + visible = Bool(True).tag(sync=True, o=True) + interactive = Bool(False).tag(sync=True, o=True) min_zoom = Int(0).tag(sync=True, o=True) max_zoom = Int(18).tag(sync=True, o=True) min_native_zoom = Int(default_value=None, allow_none=True).tag(sync=True, o=True) diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 834c9aee..92677c4c 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -17,7 +17,7 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { max_zoom: 18, min_native_zoom: null, max_native_zoom: null, - interactive: true, + interactive: false, visible: true, opacity: 1.0, renderer_factory: 'svg', From 66e6a921f6f85df38b80ba565403b689b6caf3db Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Tue, 2 Jul 2024 10:03:46 -0700 Subject: [PATCH 03/12] Optional get_feature_id --- python/ipyleaflet/ipyleaflet/leaflet.py | 3 +++ python/jupyter_leaflet/src/layers/VectorTileLayer.ts | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index 5b46cedf..32763bea 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1113,6 +1113,8 @@ class VectorTileLayer(Layer): renderer_factory: rendererFactory option ('svg' or 'canvas') for L.VectorGrid, default 'svg' interactive: boolean, default False Whether the layer is interactive or not. + get_feature_id: string, default None + Optional attribute name of a unique feature identifier. """ _view_name = Unicode("LeafletVectorTileLayerView").tag(sync=True) @@ -1130,6 +1132,7 @@ class VectorTileLayer(Layer): 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) renderer_factory = Unicode('svg').tag(sync=True, o=True) + get_feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) def redraw(self): """Force redrawing the tiles. diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 92677c4c..57d7e2a2 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -21,6 +21,7 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { visible: true, opacity: 1.0, renderer_factory: 'svg', + get_feature_id: null }; } } @@ -32,7 +33,16 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { let options = { ...this.get_options(), }; + + if ('getFeatureId' in options) { + let idVar = options['getFeatureId']; + options['getFeatureId'] = function (feat: any) { + return feat.properties[idVar]; + }; + } + let r: any = options['rendererFactory']; + if (r === 'canvas') { options['rendererFactory'] = L.canvas.tile; } else { From fd3083571367019d4d3cad89549a561d61e56bcb Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Tue, 2 Jul 2024 10:11:58 -0700 Subject: [PATCH 04/12] Send propagatedForm properties and options --- .../jupyter_leaflet/src/layers/VectorTileLayer.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 57d7e2a2..793667e7 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -67,6 +67,19 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { this.obj = L.vectorGrid.protobuf(this.model.get('url'), options); this.model.on('msg:custom', this.handle_message.bind(this)); + + this.obj.on( + 'click mouseover mouseout' as any, + (event: LeafletMouseEvent) => { + this.send({ + event: 'interaction', + type: event.type, + coordinates: [event.latlng.lat, event.latlng.lng], + properties: event.propagatedFrom.properties, + options: event.propagatedFrom.options, + }); + } + ); } model_events() { From c20ba8fdd3245fd1bcea906ac45e99734b18112c Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Tue, 2 Jul 2024 10:35:27 -0700 Subject: [PATCH 05/12] Add set_feature_style and reset_feature_style --- python/ipyleaflet/ipyleaflet/leaflet.py | 35 ++++++++++++++++++- .../src/layers/VectorTileLayer.ts | 21 ++++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index 32763bea..3ce348a1 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1110,7 +1110,8 @@ class VectorTileLayer(Layer): Opacity of the layer between 0. (fully transparent) and 1. (fully opaque). visible: boolean, default True Whether the layer is visible or not. - renderer_factory: rendererFactory option ('svg' or 'canvas') for L.VectorGrid, default 'svg' + renderer_factory: string, default 'svg' + Engine for rendering VectorTileLayers; either 'canvas' or 'svg'. Use 'svg' for interactive layers. interactive: boolean, default False Whether the layer is interactive or not. get_feature_id: string, default None @@ -1142,6 +1143,38 @@ def redraw(self): """ self.send({"msg": "redraw"}) + def set_feature_style(self, id:Int, layer_style:Dict): + """Re-symbolize one feature. + + Given the unique ID for a vector features, re-symbolizes that feature across all tiles it appears in. + Reverts the effects of a previous set_feature_style call. get_feature_id must be defined for + set_feature_style to work. + + Attributes + ---------- + id: int + The unique identifier for the feature to re-symbolize + layer_styles: dict + Style to apply to the feature + """ + self.send({"msg": + {"setFeatureStyle": + {"id":id, "layerStyle":layer_style}} + }) + + def reset_feature_style(self, id:Int): + """Reset feature style + + Reverts the style to the layer's deafult. + + Attributes + ---------- + id: int + The unique identifier for the feature to re-symbolize + """ + self.send({"msg": {"resetFeatureStyle":{"id":id}}}) + + class PMTilesLayer(Layer): """PMTilesLayer class, with Layer as parent class. diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 793667e7..89a58c24 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -1,7 +1,7 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { VectorGrid } from 'leaflet'; +import { LeafletMouseEvent, VectorGrid } from 'leaflet'; import L from '../leaflet'; import { LeafletLayerModel, LeafletLayerView } from './Layer'; @@ -21,7 +21,7 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { visible: true, opacity: 1.0, renderer_factory: 'svg', - get_feature_id: null + get_feature_id: null, }; } } @@ -101,9 +101,20 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { }); } - handle_message(content: { msg: string }) { - if (content.msg == 'redraw') { - this.obj.redraw(); + handle_message(content: { msg: any }) { + if (typeof content.msg === 'string') { + if (content.msg == 'redraw') { + this.obj.redraw(); + } + } else { + if ('setFeatureStyle' in content.msg) { + let options = content.msg.setFeatureStyle; + this.obj.setFeatureStyle(options.id, options.layerStyle); + } + if ('resetFeatureStyle' in content.msg) { + let options = content.msg.resetFeatureStyle; + this.obj.resetFeatureStyle(options.id); + } } } } From 56b56b9d28883e23eb7e927c83418515ee0a3d36 Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Thu, 11 Jul 2024 15:35:11 -0700 Subject: [PATCH 06/12] feature_style as traitlets property --- python/ipyleaflet/ipyleaflet/leaflet.py | 10 ++----- .../src/layers/VectorTileLayer.ts | 30 ++++++++++--------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index 3ce348a1..cdd759d4 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1134,6 +1134,7 @@ class VectorTileLayer(Layer): max_native_zoom = Int(default_value=None, allow_none=True).tag(sync=True, o=True) renderer_factory = Unicode('svg').tag(sync=True, o=True) get_feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) + feature_style = Dict().tag(sync=True) def redraw(self): """Force redrawing the tiles. @@ -1157,10 +1158,7 @@ def set_feature_style(self, id:Int, layer_style:Dict): layer_styles: dict Style to apply to the feature """ - self.send({"msg": - {"setFeatureStyle": - {"id":id, "layerStyle":layer_style}} - }) + self.feature_style = {"id": id, "layerStyle": layer_style, "reset": False} def reset_feature_style(self, id:Int): """Reset feature style @@ -1172,9 +1170,7 @@ def reset_feature_style(self, id:Int): id: int The unique identifier for the feature to re-symbolize """ - self.send({"msg": {"resetFeatureStyle":{"id":id}}}) - - + self.feature_style = {"id": id, "reset": True} class PMTilesLayer(Layer): """PMTilesLayer class, with Layer as parent class. diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 89a58c24..be17bc26 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -68,6 +68,19 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { this.obj = L.vectorGrid.protobuf(this.model.get('url'), options); this.model.on('msg:custom', this.handle_message.bind(this)); + this.model.on('change:feature_style', () => { + const feature_style = this.model.get('feature_style'); + const reset = feature_style['reset']; + if (reset) { + this.obj.resetFeatureStyle(feature_style['id']); + } else { + this.obj.setFeatureStyle( + feature_style['id'], + feature_style['layerStyle'] + ); + } + }); + this.obj.on( 'click mouseover mouseout' as any, (event: LeafletMouseEvent) => { @@ -101,20 +114,9 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { }); } - handle_message(content: { msg: any }) { - if (typeof content.msg === 'string') { - if (content.msg == 'redraw') { - this.obj.redraw(); - } - } else { - if ('setFeatureStyle' in content.msg) { - let options = content.msg.setFeatureStyle; - this.obj.setFeatureStyle(options.id, options.layerStyle); - } - if ('resetFeatureStyle' in content.msg) { - let options = content.msg.resetFeatureStyle; - this.obj.resetFeatureStyle(options.id); - } + handle_message(content: { msg: string }) { + if (content.msg == 'redraw') { + this.obj.redraw(); } } } From 44c5099994b9fae32bdfac284fccaea6f929268e Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Thu, 11 Jul 2024 15:36:37 -0700 Subject: [PATCH 07/12] setOpacity to 0 if VTL initialized with visible=False --- python/jupyter_leaflet/src/layers/VectorTileLayer.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index be17bc26..28db0af1 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -68,6 +68,10 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { this.obj = L.vectorGrid.protobuf(this.model.get('url'), options); this.model.on('msg:custom', this.handle_message.bind(this)); + if (this.model.get('visible') == false) { + this.obj.setOpacity(0); + } + this.model.on('change:feature_style', () => { const feature_style = this.model.get('feature_style'); const reset = feature_style['reset']; From 65b1fbfbc522f8d62e1125c2b1f04561123aa1eb Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Thu, 11 Jul 2024 15:52:59 -0700 Subject: [PATCH 08/12] Rename vector_tile_layer_styles to layer_styles in python --- python/ipyleaflet/ipyleaflet/leaflet.py | 4 +-- .../src/layers/VectorTileLayer.ts | 29 ++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index cdd759d4..a726d28e 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1096,7 +1096,7 @@ class VectorTileLayer(Layer): Url to the vector tile service. attribution: string, default "" Vector tile service attribution. - vector_tile_layer_styles: dict or string, default {}. If string, it will be parsed as a javascript object (useful for defining styles that depend on properties and/or zoom). + layer_styles: dict or string, default {}. If string, it will be parsed as a javascript object (useful for defining styles that depend on properties and/or zoom). CSS Styles to apply to the vector data. min_zoom: int, default 0 The minimum zoom level down to which this layer will be displayed (inclusive). @@ -1124,7 +1124,7 @@ class VectorTileLayer(Layer): url = Unicode().tag(sync=True, o=True) attribution = Unicode().tag(sync=True, o=True) - vector_tile_layer_styles = Union([Dict(), Unicode()]).tag(sync=True, o=True) + layer_styles = Union([Dict(), Unicode()]).tag(sync=True, o=True) opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True,o=True) visible = Bool(True).tag(sync=True, o=True) interactive = Bool(False).tag(sync=True, o=True) diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 28db0af1..515bc423 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -49,19 +49,22 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { options['rendererFactory'] = L.svg.tile; } - let x: any = options['vectorTileLayerStyles']; - if (typeof x === 'string') { - try { - let blobCode = `const jsStyle=${x}; export { jsStyle };`; - - const blob = new Blob([blobCode], { type: 'text/javascript' }); - const url = URL.createObjectURL(blob); - const module = await import(/* webpackIgnore: true*/ url); - const jsStyle = module.jsStyle; - - options['vectorTileLayerStyles'] = jsStyle; - } catch (error) { - options['vectorTileLayerStyles'] = {}; + if ('layerStyles' in options) { + let x: any = options['layerStyles']; + options['vectorTileLayerStyles'] = x; + if (typeof x === 'string') { + try { + let blobCode = `const jsStyle=${x}; export { jsStyle };`; + + const blob = new Blob([blobCode], { type: 'text/javascript' }); + const url = URL.createObjectURL(blob); + const module = await import(/* webpackIgnore: true*/ url); + const jsStyle = module.jsStyle; + + options['vectorTileLayerStyles'] = jsStyle; + } catch (error) { + options['vectorTileLayerStyles'] = {}; + } } } From 4b0320d245968e2f5364402aeff8387bf1e2ed0c Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Thu, 11 Jul 2024 15:55:39 -0700 Subject: [PATCH 09/12] Rename renderer_factory to renderer in python --- python/ipyleaflet/ipyleaflet/leaflet.py | 4 ++-- .../jupyter_leaflet/src/layers/VectorTileLayer.ts | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index a726d28e..0aab6c48 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1110,7 +1110,7 @@ class VectorTileLayer(Layer): Opacity of the layer between 0. (fully transparent) and 1. (fully opaque). visible: boolean, default True Whether the layer is visible or not. - renderer_factory: string, default 'svg' + renderer: string, default 'svg' Engine for rendering VectorTileLayers; either 'canvas' or 'svg'. Use 'svg' for interactive layers. interactive: boolean, default False Whether the layer is interactive or not. @@ -1132,7 +1132,7 @@ class VectorTileLayer(Layer): max_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) - renderer_factory = Unicode('svg').tag(sync=True, o=True) + renderer = Unicode('svg').tag(sync=True, o=True) get_feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) feature_style = Dict().tag(sync=True) diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 515bc423..07c32d07 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -20,7 +20,7 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { interactive: false, visible: true, opacity: 1.0, - renderer_factory: 'svg', + rendererFactory: L.svg.tile, get_feature_id: null, }; } @@ -41,12 +41,13 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { }; } - let r: any = options['rendererFactory']; - - if (r === 'canvas') { - options['rendererFactory'] = L.canvas.tile; - } else { - options['rendererFactory'] = L.svg.tile; + if ('renderer' in options) { + let r: any = options['renderer']; + if (r === 'canvas') { + options['rendererFactory'] = L.canvas.tile; + } else { + options['rendererFactory'] = L.svg.tile; + } } if ('layerStyles' in options) { From 8376c7422e7036be93f01b46003c1bb491dd0cc2 Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Thu, 11 Jul 2024 15:57:51 -0700 Subject: [PATCH 10/12] Rename get_feature_id to feature_id in python --- python/ipyleaflet/ipyleaflet/leaflet.py | 4 ++-- python/jupyter_leaflet/src/layers/VectorTileLayer.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index 0aab6c48..fc4ac335 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1114,7 +1114,7 @@ class VectorTileLayer(Layer): Engine for rendering VectorTileLayers; either 'canvas' or 'svg'. Use 'svg' for interactive layers. interactive: boolean, default False Whether the layer is interactive or not. - get_feature_id: string, default None + feature_id: string, default None Optional attribute name of a unique feature identifier. """ @@ -1133,7 +1133,7 @@ class VectorTileLayer(Layer): 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) renderer = Unicode('svg').tag(sync=True, o=True) - get_feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) + feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) feature_style = Dict().tag(sync=True) def redraw(self): diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 07c32d07..083647ae 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -21,7 +21,7 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { visible: true, opacity: 1.0, rendererFactory: L.svg.tile, - get_feature_id: null, + getFeatureId: null, }; } } @@ -34,8 +34,8 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { ...this.get_options(), }; - if ('getFeatureId' in options) { - let idVar = options['getFeatureId']; + if ('featureId' in options) { + let idVar = options['featureId']; options['getFeatureId'] = function (feat: any) { return feat.properties[idVar]; }; From aaf60207591771076b66fe1668226faa21a3e453 Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Fri, 12 Jul 2024 13:00:03 -0700 Subject: [PATCH 11/12] backwards compatibility for vector_tile_layer_styles --- python/ipyleaflet/ipyleaflet/leaflet.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index fc4ac335..3a645482 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1125,6 +1125,7 @@ class VectorTileLayer(Layer): attribution = Unicode().tag(sync=True, o=True) layer_styles = Union([Dict(), Unicode()]).tag(sync=True, o=True) + vector_tile_layer_styles = Union([Dict(), Unicode()], allow_none=True, default_value=None) opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True,o=True) visible = Bool(True).tag(sync=True, o=True) interactive = Bool(False).tag(sync=True, o=True) @@ -1136,6 +1137,13 @@ class VectorTileLayer(Layer): feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) feature_style = Dict().tag(sync=True) + def __init__(self, **kwargs): + super(VectorTileLayer, self).__init__(**kwargs) + # Backwards compatibility: allow vector_tile_layer_styles as input: + vtl_style = getattr(self, "vector_tile_layer_styles") + if(vtl_style): + self.layer_styles = vtl_style + def redraw(self): """Force redrawing the tiles. From d3c87a59091c8ceba38b5d87a72ab4d7fbfec987 Mon Sep 17 00:00:00 2001 From: Oliver Lopez Date: Sat, 20 Jul 2024 13:01:41 -0700 Subject: [PATCH 12/12] Backwards compatiblity and update layer_styles --- python/ipyleaflet/ipyleaflet/leaflet.py | 17 ++++-- .../src/layers/VectorTileLayer.ts | 53 ++++++++++++------- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/python/ipyleaflet/ipyleaflet/leaflet.py b/python/ipyleaflet/ipyleaflet/leaflet.py index 3a645482..5ce862e6 100644 --- a/python/ipyleaflet/ipyleaflet/leaflet.py +++ b/python/ipyleaflet/ipyleaflet/leaflet.py @@ -1125,7 +1125,6 @@ class VectorTileLayer(Layer): attribution = Unicode().tag(sync=True, o=True) layer_styles = Union([Dict(), Unicode()]).tag(sync=True, o=True) - vector_tile_layer_styles = Union([Dict(), Unicode()], allow_none=True, default_value=None) opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True,o=True) visible = Bool(True).tag(sync=True, o=True) interactive = Bool(False).tag(sync=True, o=True) @@ -1137,12 +1136,22 @@ class VectorTileLayer(Layer): feature_id = Unicode(allow_none=True, default_value=None).tag(sync=True, o=True) feature_style = Dict().tag(sync=True) + # Backwards compatibility: allow vector_tile_layer_styles as input: + @property + def vector_tile_layer_styles(self): + return self.layer_styles + + @vector_tile_layer_styles.setter + def vector_tile_layer_styles(self, value): + self.layer_styles = value + def __init__(self, **kwargs): super(VectorTileLayer, self).__init__(**kwargs) # Backwards compatibility: allow vector_tile_layer_styles as input: - vtl_style = getattr(self, "vector_tile_layer_styles") - if(vtl_style): - self.layer_styles = vtl_style + if "vector_tile_layer_styles" in kwargs: + vtl_style = kwargs["vector_tile_layer_styles"] + if(vtl_style): + self.layer_styles = vtl_style def redraw(self): """Force redrawing the tiles. diff --git a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts index 083647ae..0ff2680d 100644 --- a/python/jupyter_leaflet/src/layers/VectorTileLayer.ts +++ b/python/jupyter_leaflet/src/layers/VectorTileLayer.ts @@ -29,6 +29,28 @@ export class LeafletVectorTileLayerModel extends LeafletLayerModel { export class LeafletVectorTileLayerView extends LeafletLayerView { obj: VectorGrid.Protobuf; + async set_vector_tile_layer_styles(options: any) { + if ('layerStyles' in options) { + let x: any = options['layerStyles']; + options['vectorTileLayerStyles'] = x; + if (typeof x === 'string') { + try { + let blobCode = `const jsStyle=${x}; export { jsStyle };`; + + const blob = new Blob([blobCode], { type: 'text/javascript' }); + const url = URL.createObjectURL(blob); + const module = await import(/* webpackIgnore: true*/ url); + const jsStyle = module.jsStyle; + + options['vectorTileLayerStyles'] = jsStyle; + } catch (error) { + options['vectorTileLayerStyles'] = {}; + } + } + } + return options; + } + async create_obj() { let options = { ...this.get_options(), @@ -50,24 +72,7 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { } } - if ('layerStyles' in options) { - let x: any = options['layerStyles']; - options['vectorTileLayerStyles'] = x; - if (typeof x === 'string') { - try { - let blobCode = `const jsStyle=${x}; export { jsStyle };`; - - const blob = new Blob([blobCode], { type: 'text/javascript' }); - const url = URL.createObjectURL(blob); - const module = await import(/* webpackIgnore: true*/ url); - const jsStyle = module.jsStyle; - - options['vectorTileLayerStyles'] = jsStyle; - } catch (error) { - options['vectorTileLayerStyles'] = {}; - } - } - } + options = await this.set_vector_tile_layer_styles(options); this.obj = L.vectorGrid.protobuf(this.model.get('url'), options); this.model.on('msg:custom', this.handle_message.bind(this)); @@ -76,6 +81,18 @@ export class LeafletVectorTileLayerView extends LeafletLayerView { this.obj.setOpacity(0); } + this.model.on('change:layer_styles', async () => { + let options = { + ...this.get_options(), + }; + options = await this.set_vector_tile_layer_styles(options); + this.obj.options.vectorTileLayerStyles = options['vectorTileLayerStyles']; + if (this.model.get('visible') == false) { + this.obj.setOpacity(0); + } + this.obj.redraw(); + }); + this.model.on('change:feature_style', () => { const feature_style = this.model.get('feature_style'); const reset = feature_style['reset'];