1

Consider the following Leaflet map construction, which utilizes tiles from OSM and plots two GeoJSON files. The first GeoJSON file is derived from a multipolygon shapefile and the second GeoJSON file is a point shapefile. The relevant code is as follows.

function onEachFeature(feature, layer) {
        layer.addEventListener("click", () => {
            layer.bringToFront();
            layer.bindPopup(feature.properties.town);
        });
     }

     var mapstyle = {
        zoomControl: true,
        layers: [tileLayer],
        maxZoom: 14,
        minZoom: 8
     }

     var polystyle = {
        color: 'black',      // Outline color
        weight: 2,          // Outline width
        opacity: 1,         // Outline opacity (0 to 1)
        fillOpacity: 0,    // Fill opacity (0 to 1)
        interactive: 'false'
     }
     var markeroptions = {
        radius: 5,
        fillColor: 'blue',
        color: '#000000',
        weight: 1,
        opacity: 1,
        fillOpacity: 0.0,
        interactive: 'true'
     }
     var tileLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png');
     var map = L.map('map', mapstyle
     ).on('load', onMapLoad).setView([40.93920434539264, -73.86905931034256], 11);
     fetch('link/to/file/points.json')
     .then(response => response.json())
     .then(data => {
          L.geoJSON(data, {style: polystyle}).addTo(map);
     });
     fetch('link/to/file/points.json')
     .then(response => response.json())
     .then(data => {
          L.geoJSON(data, {
                pointToLayer: function (feature, latlng) {
                     return L.circleMarker(latlng, markeroptions);
                }, onEachFeature: onEachFeature
          }).addTo(map);
     });
     function onMapLoad(){
          console.log("map loaded");
     }

The entirety of this code produces the desired result, with the exception of the bindPopup at each circleMarker centroid. The issue I'm facing is that these popups do not fire when clicking on a point located inside a layer polygon. This issue looks as follows, note that the popup successfully fires over a point outside the polygon GeoJSON, but fails to do so just to the east:

enter image description here

What corrections can be made to the code above to allow popup events to fire on circleMarkers found inside the boundaries of any particular polygon?

1 Answer 1

1

In Leaflet ordering of layers on the map (zIndex order) is controlled with map panes (see https://leafletjs.com/reference.html#map-pane and https://leafletjs.com/examples/map-panes/). Different type of layers (tile layers, vector layers etc) are by default assigned to different standard map panes, where each pane has it's own zIndex value.

For example, all vector layers are assigned to overlayPane with zIndex 400. But it is possible to create custom map pane with desired zIndex and assign layer to that pane. This is done with the pane option.

So in your case you just create map pane with zIndex value of 450 to place it above standard overlayPane and assign circle markers to that pane.

Also on your onEachFeature function your are assigning popup to layer after each click on marker. This means popup will be shown only after second click. There is no need for layer.addEventListener("click" handling, layer.bindPopup(feature.properties.town); is anough

So relevant part of the code could look something like this:

function onEachFeature(feature, layer) {
  layer.bindPopup(feature.properties.town);
}

var markeroptions = {
  pane: 'pointsPane',
  radius: 5,
  fillColor: 'blue',
  color: '#000000',
  weight: 1,
  opacity: 1,
  fillOpacity: 0.0,
  interactive: 'true'
};

map.createPane('pointsPane');
map.getPane('pointsPane').style.zIndex = 450;

fetch('link/to/file/points.json')
.then(response => response.json())
.then(data => {
  L.geoJSON(data, {
    pointToLayer: function (feature, latlng) {
      return L.circleMarker(latlng, markeroptions);
    },
    onEachFeature: onEachFeature
  }).addTo(map);
});
3
  • This answer has been very insightful, I appreciate it! I've implemented the additions, but I still don't have the popups triggering on these points inside the polygons. I've tried increasing the z-index to 1000, does this issue relate to how the popups trigger in the onEachFeature function? Jan 15 at 23:57
  • 1
    My mistake, map pane should be assigned to circle markers. See modified answer.
    – TomazicM
    Jan 16 at 9:50
  • That solves it, also great catch on the OnClick event listener being an extraneous step in the function. I'll accept your answer, thanks for your help! Jan 16 at 16:50

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.