2

I am working from the example at Highlighting feature by Id with Leaflet.

I wanted to change the appearance of the point layer by using circleMarkers, but now the script (who was supposed to highlight the corresponding setor polygon by mouseover on the commercial layer) doesn't work anymore. I just added the pointToLayer function in "var commercial" and a style "setCircleMarker":

        <script type="text/javascript">
                    //initialisation de la carte
                    var map = L.map('mapid').setView([49.4, 1.3], 8);
                //fond de carte Mapbox
                L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
                    attribution: 'Map data &copy; <a href="https://www.mapbox.com/">Mapbox</a>',
                    maxZoom: 18,
                    id: 'mapbox/streets-v11',
                    tileSize: 512,
                    zoomOffset: -1,
                    accessToken: 'mypk'
                }).addTo(map);
                //style par défaut des secteurs
                var myStyle = {
                    "color": "#bb7800",
                    "weight": 5,
                    "opacity": 0.65
                };
                var setCircleMarker = {
                    radius: 7,
                    fillColor: "#1e7ead",
                    color: "white",
                    weight: 3,
                    opacity: 0.5,
                    fillOpacity: 1
                };  
                var json_commercial = {
                    "type": "FeatureCollection",
                    "name": "commercial",
                    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
                    "features": [
                    { "type": "Feature", "properties": { "id": "1" }, "geometry": { "type": "Point", "coordinates": [ 1.305263516194724, 49.42360636638827 ] } },
                    { "type": "Feature", "properties": { "id": "2" }, "geometry": { "type": "Point", "coordinates": [ 1.974762218487792, 49.283373530097158 ] } }
                    ]
                }

                var json_secteurs = {
                    "type": "FeatureCollection",
                    "name": "secteurs",
                    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
                    "features": [
                    { "type": "Feature", "properties": { "id": "1" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.020274203732134, 49.305991729498949 ], [ 1.309787156075082, 49.56836284255975 ], [ 1.789292983393091, 49.455271845550783 ], [ 1.020274203732134, 49.305991729498949 ] ] ] ] } },
                    { "type": "Feature", "properties": { "id": "2" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.789292983393091, 49.455271845550783 ], [ 1.309787156075082, 49.56836284255975 ], [ 1.775722063752015, 49.65883564016692 ], [ 1.789292983393091, 49.455271845550783 ] ] ] ] } },
                    { "type": "Feature", "properties": { "id": "3" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.789292983393091, 49.455271845550783 ], [ 1.775722063752015, 49.65883564016692 ], [ 2.318558849395044, 49.305991729498949 ], [ 1.689772906025202, 49.002907857514927 ], [ 1.789292983393091, 49.455271845550783 ] ] ] ] } },
                    { "type": "Feature", "properties": { "id": "4" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.789292983393091, 49.455271845550783 ], [ 1.689772906025202, 49.002907857514927 ], [ 1.020274203732134, 49.305991729498949 ], [ 1.789292983393091, 49.455271845550783 ] ] ] ] } }
                    ]
                }
                var featureLayers = new Array();
                var selectedLayer;

                function storeFeatureLayer(feature, layer) {
                    featureLayers[parseInt(feature.properties.id)] = layer;
                }

                function highlightSecteur(e) {
                    selectedLayer = featureLayers[parseInt(e.layer.feature.properties.id)];
                    selectedLayer.setStyle({color: '#ffff00'});
                }

                function resetStyle() {
                    selectedLayer.setStyle({color: "#bb7800"});
                }

                var commercial = L.geoJSON(json_commercial, {
                    style: myStyle,
                    pointToLayer: function (feature, latlng) {
                        return L.circleMarker(latlng, setCircleMarker);
                    }
                }).addTo(map);

                var secteur = L.geoJSON(json_secteurs, {
                    style: myStyle,
                    onEachFeature: storeFeatureLayer
                }).addTo(map);

                commercial.on('mouseover',highlightSecteur);
                commercial.on('mouseout',resetStyle);

        </script>
2
  • What exactly do you mean by "doesn't work any more"? Any errors in the browser debugger console?
    – TomazicM
    Commented Jul 22, 2020 at 12:25
  • No error message in the console, when I pass the mouse over a point, nothing happens.
    – stgarcia
    Commented Jul 22, 2020 at 16:04

1 Answer 1

1

Very interesting problem, hard to find the reason for this behaviour at the first sight.

Leaflet controls vertical ordering of layers on the map (what is above and what below) through placing them on so called map panes, which are separate div elements, each with it's own Z-index.

GeoJSON layer elements/features are placed on overlayPane whith Z-index value of 400. L.marker markers are placed on markerPane with Z-index value of 600, so markers are always above features.

Unlike L.marker markers, L.circleMarker markers are considered as vector overlay and as such placed on the same map pane as features, which is overlayPane. In this case vertical order of elements on the map depends on order of adding elements to the map: what comes later is above previously added layers/features.

In your case layer secteur is added after layer commercial and so polygons cover circle markers and as a consequence circle markers do not receive mouse events.

The simplest solution to this is to reverse the order of GeoJSON layers definition:

var secteur = L.geoJSON(json_secteurs, {
  style: myStyle,
  onEachFeature: storeFeatureLayer
}).addTo(map);

var commercial = L.geoJSON(json_commercial, {
  style: myStyle,
  pointToLayer: function (feature, latlng) {
    return L.circleMarker(latlng, setCircleMarker);
  }
}).addTo(map);

Second possibility would be to assign circle marker to markerPane, which can be done in marker definition options:

var setCircleMarker = {
  radius: 7,
  fillColor: "#1e7ead",
  color: "white",
  weight: 3,
  opacity: 0.5,
  fillOpacity: 1,
  pane: 'markerPane'
};  

Third possibility would be to have separate style for secteur layer and make it non interactive, so mouse events can go through it to circle markers:

var myStyle2 = {
  "color": "#bb7800",
  "weight": 5,
  "opacity": 0.65,
  "interactive": false
};

var secteur = L.geoJSON(json_secteurs, {
  style: myStyle2,
  onEachFeature: storeFeatureLayer
}).addTo(map);
1
  • I inverted my point layer with polygons and it works much better ! Than you again TomazicM
    – stgarcia
    Commented Jul 22, 2020 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.