0

I would like to implement the GroupedLayerControl plugin to my leaflet map.

Unfortunately, after applying the L.control it stops working.

My layers look as this:

 var maptiles = {
"OpenStreetMap": osm,
"Hybrid": hybridMutant
};


 var overlays = {
  "Eclipses" :{
    "Annular" : annular,
    "Hybrid" : hybrid,
    "Total" : total
  },
  "Places" : {
      "Places": places
  }
 };

I've tried:

 var layers = L.control.groupedLayers(maptiles, overlays);
 map.addControl(layers);

and

 L.control.layers(maptiles, overlays).addTo(map);

neither first nor second example was working. After this code, the map is crashed and I see only the OpenStreetMap canvas and everything, which is above this line of code.

I've checked the console, which for the first case says:

Uncaught TypeError: Cannot read property '_leaflet_id' of undefined

https://github.com/Leaflet/Leaflet/issues/1074 https://github.com/stefanocudini/leaflet-panel-layers/issues/6

and for the second one:

Uncaught TypeError: Cannot read property 'minZoom' of undefined

discussed also here:

L.control.layers: Uncaught TypeError: Cannot read property 'minZoom' of undefined

Is there something wrong with my layers? I've defined variables, which include a bunch of separate .geojson layers.

Full JSfiddle is here:

https://jsfiddle.net/okezw4dL/

It starts working, when the grouped L.GeoJSON layers are switched off. The one example of this group is below.

var hybrid = L.geoJSON([H23, H31, H49, H50, H67], {
 style: function (feature) {
   return {
    fillColor: '#0000FF',
    weight: 2,
    opacity: 0.5,
    color: 'blue',
    fillOpacity: 0.25
   };
  },
  coordsToLatLng: function (coords) {
  var latLng = L.CRS.EPSG3857.unproject(L.point(coords));
  return latLng;
 },
 onEachFeature: function (feature, layer) {
         layer.on({                    
                                    mouseover: function (e) {
                                        this.setStyle({
                                            'fillColor': 'yellow',
                                            'color': 'yellow'
                                            
                                        });
                                    },  
                                    mouseout: function (e) {
                                        this.setStyle({
                                            'fillColor': 'blue',
                                            'color': 'blue'
                                        });
                                    }       
                  });
                 }
             }).bindPopup(function (layer) {
          return layer.feature.properties.descriptio || 
         layer.feature.properties.description ;
        }).addTo(map);

        hybrid.addData(H23);
        hybrid.addData(H31);
        hybrid.addData(H49);
        hybrid.addData(H50);
        hybrid.addData(H67);

What should I do to make it running?

Occasionally I have also an error like this:

Control.Layers.js:246 Uncaught TypeError: Cannot read property 'setZIndex' of undefined

all of these says nothing to me. Is anyone able to advise?

15
  • Hey MKR, At first glance, looks like you have a lot going on in there. I'm no expert, but I think the data needs to be loaded first. I moved the bottom 3 geojson bits to the top. Then it says things like can't find A23, etc. Where is the data for Annular, etc? Then looks like some typos, layer.feature.properties.descriptio, missing 'n'. I would start way simple with the example from github, get it running, then 1 by 1 add new features.
    – timlohnes
    Commented Aug 11, 2021 at 16:45
  • First try with standard Leaflet layer control L.control.layers(maptiles, overlays).addTo(map); and see if everything works. To make this control work, overlays must have standard Leaflet structure (same as maptiles), not the one for L.control.groupedLayers.
    – TomazicM
    Commented Aug 11, 2021 at 17:02
  • I've tried with the basic Leaflet Geojson example leafletjs.com/examples/geojson and it's still the same
    – Geographos
    Commented Aug 12, 2021 at 10:39
  • This is then just question of debugging. Without having your code it's more or less impossible to find out what goes wrong. Your JSFiddle is missing data. Limit it to less data and include data in the code.
    – TomazicM
    Commented Aug 12, 2021 at 11:19
  • I've attached the full jsfiddle for it: jsfiddle.net/okezw4dL
    – Geographos
    Commented Aug 12, 2021 at 11:21

1 Answer 1

1
+100

There is some simple JS debugging and understanding of JS logic needed to find out what and why it goes wrong.

When you get error

Uncaught TypeError: Cannot read property '_leaflet_id' of undefined

at statement

var layers = L.control.groupedLayers(maptiles, overlays);

, you go to browser debugger, set a breakpoint at this statement and inspect values of maptiles and overlays. You'll notice that overlays annular, hybrid and total in overlays object are undefined at the time of statement execution. If you look at the code flow, that's logical, since object overlays, which uses those overlays, is defined before overlays are defined. This means that overlays definition and control creation should go after overlays definition.

When you do that, you'll notice that places overlay is not selected in the layer control, although layer itself is shown on the map. If you then try to select it, you'll get error:

Uncaught Error: The provided object is not a Layer.

Reason for this is that places is not overlay but source GeoJSON object for the overlay. At the time of overlay creation, you have to assign it to some variable, let's say placesOverlay and then use this in overlays definition.

So code for places overlay should look something like this:

var placesLayer = L.geoJSON(places, {
  pointToLayer: function (feature, latlng) {
    return L.circleMarker(latlng, geojsonMarkerOptions);
  }
}).addTo(map);

Code for overlays group and control creation should be put at the end and could look something like this:

var overlays = {
  "Eclipses" :{
    "Annular" : annular,
    "Hybrid" : hybrid,
    "Total" : total
  },
  "Places" : {
    "Places": placesLayer
  }
 };


var layers = L.control.groupedLayers(maptiles, overlays);
layers.addTo(map);

This is how the map looks like then (with limited set of data and without extra controls):

enter image description here

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