Adjust Control pane with multiple GeoJSON datasets

Hi I have been developing with Dash and dash_leaflet for a few time. I have 3 datasets in 3 different geojson object.
The geojson are structured as follows: list of Point, list of LineString, list of Polygon.

I want to be able to click on the polyline that could be inside on of the Polygons.
I tried to use the object Pane, passing the zIndex as style property. But it doesn’t seem to work.
I also have to add that I have a callback that selects the Polygon when is clicked.

Here’s the map definition:

crea la mappa

    self.map = dl.Map(id='mapLayout',
               children=[
                   dl.LayersControl(
                       [dl.BaseLayer(dl.TileLayer(),name="normal-map",checked=True),dl.BaseLayer(self.wms_layer,name="satellite-map")]+
                        [
                        dl.Pane([dl.Overlay(dl.GeoJSON(id="id-geojson-nodes",  data=self.geojson_nodes,zoomToBounds=True,hideout=dict(showTooltip=False,isPermanent=True),pointToLayer=self.draw_nodes,onEachFeature=self.show_labels),name="nodes")],style={'zIndex':1000},name="paneNodes"),
                         dl.Pane([dl.Overlay(dl.GeoJSON(id='id-geojson-links',  data=self.geojson_links,zoomToBounds=True,hideout=dict(showTooltip=False,isPermanent=True),onEachFeature=self.show_labels),name="links")],style={'zIndex':1100},name="paneLinks"),
                         dl.Pane([dl.Overlay(dl.GeoJSON(id="id-geojson-zones",  data=self.zones, zoomToBounds=True,hideout=dict(selected=[],showTooltip=False,isPermanent=True), style=self.styleZones,onEachFeature=self.show_labels),name="zones")],style={'zIndex':900},name="paneZones")
                        ],id="layer-control",baseLayer="normal-map",autoZIndex=True)],
               style={"width": "1800", "height": "800px"},
               attributionControl=False)

here is the HighlightZones callback:
self.app.callback(
Output(component_id=“id-geojson-zones”,component_property= “hideout”),
Input(“id-geojson-zones”, “n_clicks”),
State(“id-geojson-zones”, “clickData”),
State(“id-geojson-zones”, “hideout”),
prevent_initial_call=True
)(self.HighlightZone)
def HighlightZone(self,_, feature, hideout):
selected = hideout[“selected”]
name = feature[“properties”][“name”]
if name in selected:
selected.remove(name)
else:
selected.append(name)
return hideout

Here is an image:

I manage to click the point, but if i try to click the line it doesnt work, instead the polygon gets selected.

I’m sorry if I have missed something and thanks to anyone who will try to help.
I m using dash_leaflet =1.0.3

It probably has to done with what layer is on top - both the line and the polygon occupy the same space. Hence, when you click, you’ll get an event from the top layer (which seems to be the polygon). An issue regarding layering was fixed recently, so I would suggest that you try out the latest release to see if that fixes the issue,

Hi Emil, thanks for your reply and for all the efforts in this project, I love it!
Regarding the problem I think it has to do with this issue: Help: What is the proper way of controlling zIndex · Issue #38 · emilhe/dash-leaflet · GitHub.
Someone says that the control of the zIndex of the GeoJSON objects using the Pane object has stopped working after dash-leaflet 1.0.0.
I will try to update at the latest version and have another shot.
Thank you again.

Update: I updated from 1.0.3 to 1.0.15. And the project doesnt work quite the same. the TileLayer() doesnt shows. The onEachFeature callback doesnt gets executed when the hideout property changes. So I had to switch back to the previous version and all seems to work.

While 1.0 was a breaking release, the following releases were intended backwards compatible. Could you post an MWE that demonstrates the regression? Then Ill try to figure out what is wrong :slight_smile:

Hi emil, I resolved the problem with the newer version. I m now at 1.0.16rc1.
I am facing a problem with the control of the layering in my leaflet map. I’ve wrapped my 3 geojsons in 3 Pane each with a different zIndex passed in style. But it doesn’t seem to work. I specify that I’m using these 3 geojson with LayerControl.

Searching through the web I found that in leaflet js there is a way to create a pane attach it to the map, and then link the layer to the pane through the property pane of the layer. Is there a way to do that?
There is the code I have been working on(just the map part). The behaviour of the map is not the one I want. It seems the zINdex are ignored.

self.map = dl.Map(id='mapLayout',
                   children=[
                       dl.Polyline(id='id-routing', positions=routes),
                       dl.LayersControl(
                           [dl.BaseLayer(dl.TileLayer(),
                                        name="Mappa", checked=True),
                            dl.BaseLayer(dl.TileLayer(url=self.url_google),
                                        name='Satellite', checked=False),
                            dl.Overlay(dl.Pane(dl.GeoJSON(id="id-geojson-zones", data=self.zones, zoomToBounds=True,hideout=dict(selected=[],showTooltip=False,isPermanent=True), style=self.styleZones,onEachFeature=self.show_labels),name="paneZones",style={'zIndex':'auto'}),
                                        name="Zone",checked=False),
                            dl.Overlay(dl.Pane(dl.GeoJSON(id="id-geojson-nodes", data=self.geojson_nodes,zoomToBounds=True,hideout=dict(showTooltip=False,isPermanent=True),pointToLayer=self.draw_nodes,onEachFeature=self.show_labels),name="paneNodes",style={'zIndex':600}),
                                        name="Nodi",checked=True),
                            dl.Overlay(dl.Pane(dl.GeoJSON(id='id-geojson-links', data=self.geojson_links,zoomToBounds=True,hideout=dict(showTooltip=False,isPermanent=True),onEachFeature=self.show_labels),name="paneLinks",style={'zIndex':601}),
                                        name="Links",checked=False),
                            
                   ],id="layer-control",baseLayer="Mappa")],
                   style={"width": "1800", "height": "800px"},zoom=10,center=[10,10],
                   attributionControl=False)

These are the js callbacks:


self.draw_nodes = assign("""function(feature, latlng,context){
        const flag = L.icon({iconUrl: `./assets/nodo_idrico_on.png`, iconSize: [20, 20]});
            return L.marker(latlng, {icon: flag});
        }""")
        self.styleZones = assign("""function(feature, context){
            const {selected} = context.hideout;
            if(selected.includes(feature.properties.name)){
                return {fillColor: 'red', color: 'grey'};
            }
            return {fillColor: 'grey', color: 'grey'};
        }""")
        # self.filter = assign("""function(feature,context){ const {toggled} = context.hideout; return toggled;}""")
        self.show_labels = assign("""function(feature, layer,context) {
            if (context.hideout.showTooltip){
            const name = feature.properties.name;
            return layer.bindTooltip(name,{permanent:context.hideout.isPermanent});
            }
            }""")

It all works, I just can’t get the Layering correct. If you have some tips or link to the specific docs for layering.
P.S. I want that the zonesLayer is under the other two layers.
Thanks a lot for your time.

Update: It seems that updating the version to 1.0.16rc1 resolved the issue.
The final version of the map follows:

self.map = dl.Map(id='mapLayout',
                   children=[
                       dl.Pane(style={'zIndex':601},name="paneRouting",id="id-pane-routing"),
                       dl.LayersControl(
                           [dl.BaseLayer(dl.TileLayer(),
                                        name="Mappa", checked=True),
                            dl.BaseLayer(dl.TileLayer(url=self.url_google),
                                        name='Satellite', checked=False),
                            dl.Overlay(dl.Pane(dl.GeoJSON(id="id-geojson-zones", data=self.zones, zoomToBounds=False,hideout=dict(selected=[],showTooltip=False,isPermanent=True), style=self.styleZones,onEachFeature=self.show_labels),name="paneZones",style={'zIndex':599}),
                                        name="Zone",checked=False),
                            dl.Overlay(dl.Pane(dl.GeoJSON(id="id-geojson-nodes", data=self.geojson_nodes,zoomToBounds=True,hideout=dict(showTooltip=False,isPermanent=True),pointToLayer=self.draw_nodes,onEachFeature=self.show_labels),name="paneNodes",style={'zIndex':600}),
                                        name="Nodi",checked=True),
                            dl.Overlay(dl.Pane(dl.GeoJSON(id='id-geojson-links', data=self.geojson_links,zoomToBounds=False,hideout=dict(showTooltip=False,isPermanent=True),onEachFeature=self.show_labels,style=self.styleLinks),name="paneLinks",style={'zIndex':600}),
                                        name="Links",checked=False),
                            
                            
                   ],id="layer-control",baseLayer="Mappa")],
                   style={"width": "1800", "height": "800px"},zoom=10,center=[10,10],
                   attributionControl=False)

Support for layering control via panes was added in 1.0.15, so from this version and onwards, the issue should be fixed :blush: