Search code examples
leafletreact-leafletreact-leaflet-v3

Leaflet zIndex in custom pane between TileLayer, Geojson


I am organising several layers with an interface which allow order decision. For example I have 3 layers:

  1. WMS Layer, order: 3
  2. Geojson layer: order 2
  3. WMS Layer, order: 1

I am able to order the WMS layers with the zIndex property. The Geojson layer however is unable to fit between these too.

The Leaflet.Pane concept + a custom Pane was something I tried, this helps in moving the custom layers on top of lets say everything. But inside this custom pane, I can't assign an order to this Geojson (svg) layer.

In this example, the tileLayers and geoJSON are in the same custom pane. Inside this pane, I want to switch the order of the layers, base on a property (e.g. zIndex). But I can't find how to dos this with a TileLayer <> Geojson combination.

https://codesandbox.io/s/leaflet-custom-pane-fw0ue


Solution

  • Your issue is that you are trying to set the zIndex on the layers, instead of the panes they belong to. You need to set the zIndex on the pane itself. In vanilla leaflet:

    map.createPane("top");
    map.getPane("top").style.zIndex = "380";
    
    map.createPane("middle");
    map.getPane("middle").style.zIndex = "360";
    
    map.createPane("bottom");
    map.getPane("bottom").style.zIndex = "340";
    
    var positron = L.tileLayer(
      "https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
      {
        pane: "bottom",
      }
    ).addTo(map);
    
    var geojson = L.geoJson(euCountries, { pane: "middle"}).addTo(map);
    
    var positronLabels = L.tileLayer(
      "https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png",
      {
        pane: "top"
      }
    ).addTo(map);
    

    Working codesandbox

    This is a bit more elegant in react-leaflet, where you can wrap your various layers in Pane components:

    const Map = (props) => {
      return (
        <MapContainer
          doubleClickZoom={false}
          id="mapId"
          zoom={4}
          center={[47.040182144806664, 9.667968750000002]}
        >
          <Pane name="top" style={{ zIndex: 380 }}>
            <TileLayer
              url="https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png"
            />
          </Pane>
          <Pane name="middle" style={{ zIndex: 360 }}>
            <GeoJSON data={countries} />
          </Pane>
          <Pane name="bottom" style={{ zIndex: 340 }}>
            <TileLayer
              url="https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png"
            />
          </Pane>
        </MapContainer>
      );
    };
    

    Working codesandbox