Skip to content

Commit 6244c7c

Browse files
committed
Add Map panes
1 parent 3437521 commit 6244c7c

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

ipyleaflet/leaflet.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ def get_value(change):
8080
return future
8181

8282

83+
class PaneException(TraitError):
84+
"""Custom PaneException class."""
85+
pass
86+
87+
8388
class LayerException(TraitError):
8489
"""Custom LayerException class."""
8590
pass
@@ -112,6 +117,8 @@ class Layer(Widget, InteractMixin):
112117
Custom name for the layer, which will be used by the LayersControl.
113118
popup: object
114119
Interactive widget that will be shown in a Popup when clicking on the layer.
120+
pane: string
121+
Name of the pane to use for the layer.
115122
"""
116123

117124
_view_name = Unicode('LeafletLayerView').tag(sync=True)
@@ -129,6 +136,7 @@ class Layer(Widget, InteractMixin):
129136
popup_min_width = Int(50).tag(sync=True)
130137
popup_max_width = Int(300).tag(sync=True)
131138
popup_max_height = Int(default_value=None, allow_none=True).tag(sync=True)
139+
pane = Unicode('').tag(sync=True)
132140

133141
options = List(trait=Unicode()).tag(sync=True)
134142

@@ -2181,6 +2189,7 @@ def _default_options(self):
21812189
right = Float(0, read_only=True).tag(sync=True)
21822190
left = Float(9007199254740991, read_only=True).tag(sync=True)
21832191

2192+
panes = Dict().tag(sync=True)
21842193
layers = Tuple().tag(trait=Instance(Layer), sync=True, **widget_serialization)
21852194

21862195
@default('layers')
@@ -2243,6 +2252,19 @@ def observe_attribution_control(self, change):
22432252
if self.attribution_control_instance is not None and self.attribution_control_instance in self.controls:
22442253
self.remove(self.attribution_control_instance)
22452254

2255+
@validate('panes')
2256+
def _validate_panes(self, proposal):
2257+
'''Validate panes.
2258+
'''
2259+
error_msg = "Panes should look like: {'pane_name': {'zIndex': 650, 'pointerEvents': 'none'}, ...}"
2260+
for k1, v1 in proposal.value.items():
2261+
if not isinstance(k1, str) or not isinstance(v1, dict):
2262+
raise PaneException(error_msg)
2263+
for k2, v2 in v1.items():
2264+
if not isinstance(k2, str) or not isinstance(v2, (str, int, float)):
2265+
raise PaneException(error_msg)
2266+
return proposal.value
2267+
22462268
_layer_ids = List()
22472269

22482270
@validate('layers')

js/src/Map.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export class LeafletMapModel extends widgets.DOMWidgetModel {
7373
right: 0,
7474
left: 9007199254740991,
7575
options: [],
76+
panes: {},
7677
layers: [],
7778
controls: [],
7879
crs: {
@@ -165,6 +166,17 @@ export class LeafletMapView extends utils.LeafletDOMWidgetView {
165166
this.dirty = false;
166167
}
167168

169+
create_panes() {
170+
const panes = this.model.get('panes');
171+
for (let name in panes) {
172+
const pane = this.obj.createPane(name);
173+
const styles = panes[name];
174+
for (let key in styles) {
175+
pane.style[key] = styles[key];
176+
}
177+
}
178+
}
179+
168180
remove_layer_view(child_view) {
169181
this.obj.removeLayer(child_view.obj);
170182
child_view.remove();
@@ -229,6 +241,7 @@ export class LeafletMapView extends utils.LeafletDOMWidgetView {
229241

230242
render_leaflet() {
231243
this.create_obj().then(() => {
244+
this.create_panes();
232245
this.layer_views.update(this.model.get('layers'));
233246
this.control_views.update(this.model.get('controls'));
234247
this.leaflet_events();

js/src/layers/Layer.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ export class LeafletLayerModel extends widgets.WidgetModel {
2323
popup: null,
2424
popup_min_width: 50,
2525
popup_max_width: 300,
26-
popup_max_height: null
26+
popup_max_height: null,
27+
pane: ''
2728
};
2829
}
2930
}
@@ -58,6 +59,10 @@ export class LeafletLayerView extends utils.LeafletWidgetView {
5859
this.listenTo(this.model, 'change:popup', function(model, value) {
5960
this.bind_popup(value);
6061
});
62+
const pane = this.model.get('pane');
63+
if (pane !== '') {
64+
L.setOptions(this.obj, {pane});
65+
}
6166
});
6267
}
6368

0 commit comments

Comments
 (0)