Leaflet Draw “Cannot read property 'enable' of undefined” adding control to geoJSON layer





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







2















I am trying to use leaflet's edit function on polygons that I loaded from my database. When I click on leaflet's edit button I get the error
Cannot read property 'enable' of undefined



This thread describes a similar problem, and user ddproxy said




"Since FeatureGroup extends LayerGroup You can walk through the layers
presented and add them individually to the FeatureGroup used for
Leaflet.draw"




I am confused what he means by "walk through", I thought I was adding a layer group, so i'm not sure what I would be walking through. Does this have to do with the fact that i'm adding the polygons as a geoJSON object?
Adding the polygons to the map, binding their popups, and assigning them custom colors works perfectly FYI.



The following is the relevant code:



<script>
window.addEventListener("load", function(event){
//other stuff
loadHazards();

});

//next 6 lines siply add map to page
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
var osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib})
var map = new L.Map('map', { center: new L.LatLng(39.255467, -76.711964), zoom: 16 })

osm.addTo(map);

var drawnItems = L.featureGroup().addTo(map);
var Hazards = L.featureGroup().addTo(map);

L.control.layers({
'osm': osm.addTo(map)
},
{
'drawlayer': drawnItems,
"Hazards" : Hazards,
"Tickets": Tickets
},

{
position: 'topleft', collapsed: false
}
).addTo(map);

map.addControl(new L.Control.Draw({
edit: {
featureGroup: Hazards,
poly: {
allowIntersection: false
}
},
draw: {
polygon: {
allowIntersection: false,
showArea: true
},
rectangle:false,
circle:false,
circlemarker:false
}
}));

map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});

</script>


And the loadHazards() function:



function loadHazards(){
$.ajax({
type: 'GET',
url:'/loadPolygonFromDatabase',
success : function(polygons){
polygons = JSON.parse(polygons);

var toAdd = ;
for (i in polygons){

var item = {
"type" : "Feature",
"properties":{
"category":"",
"description":"",
"ID":""
},
"geometry" : {
"type":"Polygon",
"coordinates":,

}

};

item["geometry"]["coordinates"][0] = polygons[i]["coordinates"];
item["properties"]["category"] = polygons[i]["category"];
item["properties"]["description"] = polygons[i]["description"];
item["properties"]["ID"] = polygons[i]["ID"];
toAdd.push(item);

}

//Add information to popup
var layerGroup = L.geoJSON(toAdd, {
onEachFeature: function (feature, layer) {
layer.bindPopup( '<h1>' + feature.properties.category + '</h1>'
+ '<p>' + feature.properties.description + '</p>');
layer.id = feature.properties.ID;

},
style: function(feature){
switch (feature.properties.category) {
case 'Rabid_Beavers': return {color: "#663326"};
case 'Fire': return {color: "#ff0000"};
case 'Flood': return {color: "#0000ff"};
}
}
}).addTo(Hazards);

}
});
}


Thanks in advance!










share|improve this question































    2















    I am trying to use leaflet's edit function on polygons that I loaded from my database. When I click on leaflet's edit button I get the error
    Cannot read property 'enable' of undefined



    This thread describes a similar problem, and user ddproxy said




    "Since FeatureGroup extends LayerGroup You can walk through the layers
    presented and add them individually to the FeatureGroup used for
    Leaflet.draw"




    I am confused what he means by "walk through", I thought I was adding a layer group, so i'm not sure what I would be walking through. Does this have to do with the fact that i'm adding the polygons as a geoJSON object?
    Adding the polygons to the map, binding their popups, and assigning them custom colors works perfectly FYI.



    The following is the relevant code:



    <script>
    window.addEventListener("load", function(event){
    //other stuff
    loadHazards();

    });

    //next 6 lines siply add map to page
    var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
    var osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib})
    var map = new L.Map('map', { center: new L.LatLng(39.255467, -76.711964), zoom: 16 })

    osm.addTo(map);

    var drawnItems = L.featureGroup().addTo(map);
    var Hazards = L.featureGroup().addTo(map);

    L.control.layers({
    'osm': osm.addTo(map)
    },
    {
    'drawlayer': drawnItems,
    "Hazards" : Hazards,
    "Tickets": Tickets
    },

    {
    position: 'topleft', collapsed: false
    }
    ).addTo(map);

    map.addControl(new L.Control.Draw({
    edit: {
    featureGroup: Hazards,
    poly: {
    allowIntersection: false
    }
    },
    draw: {
    polygon: {
    allowIntersection: false,
    showArea: true
    },
    rectangle:false,
    circle:false,
    circlemarker:false
    }
    }));

    map.on(L.Draw.Event.CREATED, function (event) {
    var layer = event.layer;
    drawnItems.addLayer(layer);
    });

    </script>


    And the loadHazards() function:



    function loadHazards(){
    $.ajax({
    type: 'GET',
    url:'/loadPolygonFromDatabase',
    success : function(polygons){
    polygons = JSON.parse(polygons);

    var toAdd = ;
    for (i in polygons){

    var item = {
    "type" : "Feature",
    "properties":{
    "category":"",
    "description":"",
    "ID":""
    },
    "geometry" : {
    "type":"Polygon",
    "coordinates":,

    }

    };

    item["geometry"]["coordinates"][0] = polygons[i]["coordinates"];
    item["properties"]["category"] = polygons[i]["category"];
    item["properties"]["description"] = polygons[i]["description"];
    item["properties"]["ID"] = polygons[i]["ID"];
    toAdd.push(item);

    }

    //Add information to popup
    var layerGroup = L.geoJSON(toAdd, {
    onEachFeature: function (feature, layer) {
    layer.bindPopup( '<h1>' + feature.properties.category + '</h1>'
    + '<p>' + feature.properties.description + '</p>');
    layer.id = feature.properties.ID;

    },
    style: function(feature){
    switch (feature.properties.category) {
    case 'Rabid_Beavers': return {color: "#663326"};
    case 'Fire': return {color: "#ff0000"};
    case 'Flood': return {color: "#0000ff"};
    }
    }
    }).addTo(Hazards);

    }
    });
    }


    Thanks in advance!










    share|improve this question



























      2












      2








      2








      I am trying to use leaflet's edit function on polygons that I loaded from my database. When I click on leaflet's edit button I get the error
      Cannot read property 'enable' of undefined



      This thread describes a similar problem, and user ddproxy said




      "Since FeatureGroup extends LayerGroup You can walk through the layers
      presented and add them individually to the FeatureGroup used for
      Leaflet.draw"




      I am confused what he means by "walk through", I thought I was adding a layer group, so i'm not sure what I would be walking through. Does this have to do with the fact that i'm adding the polygons as a geoJSON object?
      Adding the polygons to the map, binding their popups, and assigning them custom colors works perfectly FYI.



      The following is the relevant code:



      <script>
      window.addEventListener("load", function(event){
      //other stuff
      loadHazards();

      });

      //next 6 lines siply add map to page
      var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
      var osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib})
      var map = new L.Map('map', { center: new L.LatLng(39.255467, -76.711964), zoom: 16 })

      osm.addTo(map);

      var drawnItems = L.featureGroup().addTo(map);
      var Hazards = L.featureGroup().addTo(map);

      L.control.layers({
      'osm': osm.addTo(map)
      },
      {
      'drawlayer': drawnItems,
      "Hazards" : Hazards,
      "Tickets": Tickets
      },

      {
      position: 'topleft', collapsed: false
      }
      ).addTo(map);

      map.addControl(new L.Control.Draw({
      edit: {
      featureGroup: Hazards,
      poly: {
      allowIntersection: false
      }
      },
      draw: {
      polygon: {
      allowIntersection: false,
      showArea: true
      },
      rectangle:false,
      circle:false,
      circlemarker:false
      }
      }));

      map.on(L.Draw.Event.CREATED, function (event) {
      var layer = event.layer;
      drawnItems.addLayer(layer);
      });

      </script>


      And the loadHazards() function:



      function loadHazards(){
      $.ajax({
      type: 'GET',
      url:'/loadPolygonFromDatabase',
      success : function(polygons){
      polygons = JSON.parse(polygons);

      var toAdd = ;
      for (i in polygons){

      var item = {
      "type" : "Feature",
      "properties":{
      "category":"",
      "description":"",
      "ID":""
      },
      "geometry" : {
      "type":"Polygon",
      "coordinates":,

      }

      };

      item["geometry"]["coordinates"][0] = polygons[i]["coordinates"];
      item["properties"]["category"] = polygons[i]["category"];
      item["properties"]["description"] = polygons[i]["description"];
      item["properties"]["ID"] = polygons[i]["ID"];
      toAdd.push(item);

      }

      //Add information to popup
      var layerGroup = L.geoJSON(toAdd, {
      onEachFeature: function (feature, layer) {
      layer.bindPopup( '<h1>' + feature.properties.category + '</h1>'
      + '<p>' + feature.properties.description + '</p>');
      layer.id = feature.properties.ID;

      },
      style: function(feature){
      switch (feature.properties.category) {
      case 'Rabid_Beavers': return {color: "#663326"};
      case 'Fire': return {color: "#ff0000"};
      case 'Flood': return {color: "#0000ff"};
      }
      }
      }).addTo(Hazards);

      }
      });
      }


      Thanks in advance!










      share|improve this question
















      I am trying to use leaflet's edit function on polygons that I loaded from my database. When I click on leaflet's edit button I get the error
      Cannot read property 'enable' of undefined



      This thread describes a similar problem, and user ddproxy said




      "Since FeatureGroup extends LayerGroup You can walk through the layers
      presented and add them individually to the FeatureGroup used for
      Leaflet.draw"




      I am confused what he means by "walk through", I thought I was adding a layer group, so i'm not sure what I would be walking through. Does this have to do with the fact that i'm adding the polygons as a geoJSON object?
      Adding the polygons to the map, binding their popups, and assigning them custom colors works perfectly FYI.



      The following is the relevant code:



      <script>
      window.addEventListener("load", function(event){
      //other stuff
      loadHazards();

      });

      //next 6 lines siply add map to page
      var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
      var osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors'
      var osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib})
      var map = new L.Map('map', { center: new L.LatLng(39.255467, -76.711964), zoom: 16 })

      osm.addTo(map);

      var drawnItems = L.featureGroup().addTo(map);
      var Hazards = L.featureGroup().addTo(map);

      L.control.layers({
      'osm': osm.addTo(map)
      },
      {
      'drawlayer': drawnItems,
      "Hazards" : Hazards,
      "Tickets": Tickets
      },

      {
      position: 'topleft', collapsed: false
      }
      ).addTo(map);

      map.addControl(new L.Control.Draw({
      edit: {
      featureGroup: Hazards,
      poly: {
      allowIntersection: false
      }
      },
      draw: {
      polygon: {
      allowIntersection: false,
      showArea: true
      },
      rectangle:false,
      circle:false,
      circlemarker:false
      }
      }));

      map.on(L.Draw.Event.CREATED, function (event) {
      var layer = event.layer;
      drawnItems.addLayer(layer);
      });

      </script>


      And the loadHazards() function:



      function loadHazards(){
      $.ajax({
      type: 'GET',
      url:'/loadPolygonFromDatabase',
      success : function(polygons){
      polygons = JSON.parse(polygons);

      var toAdd = ;
      for (i in polygons){

      var item = {
      "type" : "Feature",
      "properties":{
      "category":"",
      "description":"",
      "ID":""
      },
      "geometry" : {
      "type":"Polygon",
      "coordinates":,

      }

      };

      item["geometry"]["coordinates"][0] = polygons[i]["coordinates"];
      item["properties"]["category"] = polygons[i]["category"];
      item["properties"]["description"] = polygons[i]["description"];
      item["properties"]["ID"] = polygons[i]["ID"];
      toAdd.push(item);

      }

      //Add information to popup
      var layerGroup = L.geoJSON(toAdd, {
      onEachFeature: function (feature, layer) {
      layer.bindPopup( '<h1>' + feature.properties.category + '</h1>'
      + '<p>' + feature.properties.description + '</p>');
      layer.id = feature.properties.ID;

      },
      style: function(feature){
      switch (feature.properties.category) {
      case 'Rabid_Beavers': return {color: "#663326"};
      case 'Fire': return {color: "#ff0000"};
      case 'Flood': return {color: "#0000ff"};
      }
      }
      }).addTo(Hazards);

      }
      });
      }


      Thanks in advance!







      javascript leaflet leaflet.draw






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 25 '18 at 3:01









      ghybs

      24.2k32648




      24.2k32648










      asked Nov 24 '18 at 22:55









      TomTom

      323




      323
























          2 Answers
          2






          active

          oldest

          votes


















          3














          Unfortunately Leaflet.draw plugin does not handle nested Layer Groups (same for Feature Groups / GeoJSON Layer Groups).



          That is the meaning of the Leaflet.draw #398 issue you reference: they advise looping through the child layers of your Layer/Feature/GeoJSON Layer Group (e.g. with their eachLayer method). If the child layer is a non-group layer, then add it to your editable Feature Group. If it is another nested group, then loop through its own child layers again.



          See the code proposed in that post:



          https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet



          var geoJsonGroup = L.geoJson(myGeoJSON);
          addNonGroupLayers(geoJsonGroup, drawnItems);

          // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
          function addNonGroupLayers(sourceLayer, targetGroup) {
          if (sourceLayer instanceof L.LayerGroup) {
          sourceLayer.eachLayer(function(layer) {
          addNonGroupLayers(layer, targetGroup);
          });
          } else {
          targetGroup.addLayer(sourceLayer);
          }
          }


          In your very case, you can also refactor your code with 2 other solutions:




          • Instead of building your layerGroup (which is actually a Leaflet GeoJSON Layer Group) first and then add it into your Hazards Feature Group, make the latter a GeoJSON Layer Group from the beginning, and addData for each of your single Features (item):


          var Hazards = L.geoJSON(null, yourOptions).addTo(map);

          for (i in polygons) {
          var item = {
          "type" : "Feature",
          // etc.
          };
          // toAdd.push(item);
          Hazards.addData(item); // Directly add the GeoJSON Feature object
          }



          • Instead of building a GeoJSON Feature Object (item) and parse it into a Leaflet GeoJSON Layer, you can directly build a Leaflet Polygon and add it into your Hazards Layer/Feature Group:


          for (i in polygons) {
          var coords = polygons[i]["coordinates"];
          var style = getStyle(polygons[i]["category"]);
          var popup = ""; // fill it as you wish

          // Directly build a Leaflet layer instead of an intermediary GeoJSON Feature
          var itemLayer = L.polygon(coords, style).bindPopup(popup);
          itemLayer.id = polygons[i]["ID"];
          itemLayer.addTo(Hazards);
          }

          function getStyle(category) {
          switch (category) {
          case 'Rabid_Beavers': return {color: "#663326"};
          case 'Fire': return {color: "#ff0000"};
          case 'Flood': return {color: "#0000ff"};
          }
          }





          share|improve this answer































            1














            As mentioned by @ghybs Leaflet.Draw doesn't support Groups or MultiPolygons. I needed the same functionality so a few years ago I created leaflet.pm which supports holes, MultiPolygons, GeoJSON and LayerGroups:



            enter image description here



            https://github.com/codeofsumit/leaflet.pm



            Hope it helps.






            share|improve this answer



















            • 1





              leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

              – Scott
              Jan 30 at 23:18












            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463078%2fleaflet-draw-cannot-read-property-enable-of-undefined-adding-control-to-geoj%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            3














            Unfortunately Leaflet.draw plugin does not handle nested Layer Groups (same for Feature Groups / GeoJSON Layer Groups).



            That is the meaning of the Leaflet.draw #398 issue you reference: they advise looping through the child layers of your Layer/Feature/GeoJSON Layer Group (e.g. with their eachLayer method). If the child layer is a non-group layer, then add it to your editable Feature Group. If it is another nested group, then loop through its own child layers again.



            See the code proposed in that post:



            https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet



            var geoJsonGroup = L.geoJson(myGeoJSON);
            addNonGroupLayers(geoJsonGroup, drawnItems);

            // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
            function addNonGroupLayers(sourceLayer, targetGroup) {
            if (sourceLayer instanceof L.LayerGroup) {
            sourceLayer.eachLayer(function(layer) {
            addNonGroupLayers(layer, targetGroup);
            });
            } else {
            targetGroup.addLayer(sourceLayer);
            }
            }


            In your very case, you can also refactor your code with 2 other solutions:




            • Instead of building your layerGroup (which is actually a Leaflet GeoJSON Layer Group) first and then add it into your Hazards Feature Group, make the latter a GeoJSON Layer Group from the beginning, and addData for each of your single Features (item):


            var Hazards = L.geoJSON(null, yourOptions).addTo(map);

            for (i in polygons) {
            var item = {
            "type" : "Feature",
            // etc.
            };
            // toAdd.push(item);
            Hazards.addData(item); // Directly add the GeoJSON Feature object
            }



            • Instead of building a GeoJSON Feature Object (item) and parse it into a Leaflet GeoJSON Layer, you can directly build a Leaflet Polygon and add it into your Hazards Layer/Feature Group:


            for (i in polygons) {
            var coords = polygons[i]["coordinates"];
            var style = getStyle(polygons[i]["category"]);
            var popup = ""; // fill it as you wish

            // Directly build a Leaflet layer instead of an intermediary GeoJSON Feature
            var itemLayer = L.polygon(coords, style).bindPopup(popup);
            itemLayer.id = polygons[i]["ID"];
            itemLayer.addTo(Hazards);
            }

            function getStyle(category) {
            switch (category) {
            case 'Rabid_Beavers': return {color: "#663326"};
            case 'Fire': return {color: "#ff0000"};
            case 'Flood': return {color: "#0000ff"};
            }
            }





            share|improve this answer




























              3














              Unfortunately Leaflet.draw plugin does not handle nested Layer Groups (same for Feature Groups / GeoJSON Layer Groups).



              That is the meaning of the Leaflet.draw #398 issue you reference: they advise looping through the child layers of your Layer/Feature/GeoJSON Layer Group (e.g. with their eachLayer method). If the child layer is a non-group layer, then add it to your editable Feature Group. If it is another nested group, then loop through its own child layers again.



              See the code proposed in that post:



              https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet



              var geoJsonGroup = L.geoJson(myGeoJSON);
              addNonGroupLayers(geoJsonGroup, drawnItems);

              // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
              function addNonGroupLayers(sourceLayer, targetGroup) {
              if (sourceLayer instanceof L.LayerGroup) {
              sourceLayer.eachLayer(function(layer) {
              addNonGroupLayers(layer, targetGroup);
              });
              } else {
              targetGroup.addLayer(sourceLayer);
              }
              }


              In your very case, you can also refactor your code with 2 other solutions:




              • Instead of building your layerGroup (which is actually a Leaflet GeoJSON Layer Group) first and then add it into your Hazards Feature Group, make the latter a GeoJSON Layer Group from the beginning, and addData for each of your single Features (item):


              var Hazards = L.geoJSON(null, yourOptions).addTo(map);

              for (i in polygons) {
              var item = {
              "type" : "Feature",
              // etc.
              };
              // toAdd.push(item);
              Hazards.addData(item); // Directly add the GeoJSON Feature object
              }



              • Instead of building a GeoJSON Feature Object (item) and parse it into a Leaflet GeoJSON Layer, you can directly build a Leaflet Polygon and add it into your Hazards Layer/Feature Group:


              for (i in polygons) {
              var coords = polygons[i]["coordinates"];
              var style = getStyle(polygons[i]["category"]);
              var popup = ""; // fill it as you wish

              // Directly build a Leaflet layer instead of an intermediary GeoJSON Feature
              var itemLayer = L.polygon(coords, style).bindPopup(popup);
              itemLayer.id = polygons[i]["ID"];
              itemLayer.addTo(Hazards);
              }

              function getStyle(category) {
              switch (category) {
              case 'Rabid_Beavers': return {color: "#663326"};
              case 'Fire': return {color: "#ff0000"};
              case 'Flood': return {color: "#0000ff"};
              }
              }





              share|improve this answer


























                3












                3








                3







                Unfortunately Leaflet.draw plugin does not handle nested Layer Groups (same for Feature Groups / GeoJSON Layer Groups).



                That is the meaning of the Leaflet.draw #398 issue you reference: they advise looping through the child layers of your Layer/Feature/GeoJSON Layer Group (e.g. with their eachLayer method). If the child layer is a non-group layer, then add it to your editable Feature Group. If it is another nested group, then loop through its own child layers again.



                See the code proposed in that post:



                https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet



                var geoJsonGroup = L.geoJson(myGeoJSON);
                addNonGroupLayers(geoJsonGroup, drawnItems);

                // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
                function addNonGroupLayers(sourceLayer, targetGroup) {
                if (sourceLayer instanceof L.LayerGroup) {
                sourceLayer.eachLayer(function(layer) {
                addNonGroupLayers(layer, targetGroup);
                });
                } else {
                targetGroup.addLayer(sourceLayer);
                }
                }


                In your very case, you can also refactor your code with 2 other solutions:




                • Instead of building your layerGroup (which is actually a Leaflet GeoJSON Layer Group) first and then add it into your Hazards Feature Group, make the latter a GeoJSON Layer Group from the beginning, and addData for each of your single Features (item):


                var Hazards = L.geoJSON(null, yourOptions).addTo(map);

                for (i in polygons) {
                var item = {
                "type" : "Feature",
                // etc.
                };
                // toAdd.push(item);
                Hazards.addData(item); // Directly add the GeoJSON Feature object
                }



                • Instead of building a GeoJSON Feature Object (item) and parse it into a Leaflet GeoJSON Layer, you can directly build a Leaflet Polygon and add it into your Hazards Layer/Feature Group:


                for (i in polygons) {
                var coords = polygons[i]["coordinates"];
                var style = getStyle(polygons[i]["category"]);
                var popup = ""; // fill it as you wish

                // Directly build a Leaflet layer instead of an intermediary GeoJSON Feature
                var itemLayer = L.polygon(coords, style).bindPopup(popup);
                itemLayer.id = polygons[i]["ID"];
                itemLayer.addTo(Hazards);
                }

                function getStyle(category) {
                switch (category) {
                case 'Rabid_Beavers': return {color: "#663326"};
                case 'Fire': return {color: "#ff0000"};
                case 'Flood': return {color: "#0000ff"};
                }
                }





                share|improve this answer













                Unfortunately Leaflet.draw plugin does not handle nested Layer Groups (same for Feature Groups / GeoJSON Layer Groups).



                That is the meaning of the Leaflet.draw #398 issue you reference: they advise looping through the child layers of your Layer/Feature/GeoJSON Layer Group (e.g. with their eachLayer method). If the child layer is a non-group layer, then add it to your editable Feature Group. If it is another nested group, then loop through its own child layers again.



                See the code proposed in that post:



                https://gis.stackexchange.com/questions/203540/how-to-edit-an-existing-layer-using-leaflet



                var geoJsonGroup = L.geoJson(myGeoJSON);
                addNonGroupLayers(geoJsonGroup, drawnItems);

                // Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
                function addNonGroupLayers(sourceLayer, targetGroup) {
                if (sourceLayer instanceof L.LayerGroup) {
                sourceLayer.eachLayer(function(layer) {
                addNonGroupLayers(layer, targetGroup);
                });
                } else {
                targetGroup.addLayer(sourceLayer);
                }
                }


                In your very case, you can also refactor your code with 2 other solutions:




                • Instead of building your layerGroup (which is actually a Leaflet GeoJSON Layer Group) first and then add it into your Hazards Feature Group, make the latter a GeoJSON Layer Group from the beginning, and addData for each of your single Features (item):


                var Hazards = L.geoJSON(null, yourOptions).addTo(map);

                for (i in polygons) {
                var item = {
                "type" : "Feature",
                // etc.
                };
                // toAdd.push(item);
                Hazards.addData(item); // Directly add the GeoJSON Feature object
                }



                • Instead of building a GeoJSON Feature Object (item) and parse it into a Leaflet GeoJSON Layer, you can directly build a Leaflet Polygon and add it into your Hazards Layer/Feature Group:


                for (i in polygons) {
                var coords = polygons[i]["coordinates"];
                var style = getStyle(polygons[i]["category"]);
                var popup = ""; // fill it as you wish

                // Directly build a Leaflet layer instead of an intermediary GeoJSON Feature
                var itemLayer = L.polygon(coords, style).bindPopup(popup);
                itemLayer.id = polygons[i]["ID"];
                itemLayer.addTo(Hazards);
                }

                function getStyle(category) {
                switch (category) {
                case 'Rabid_Beavers': return {color: "#663326"};
                case 'Fire': return {color: "#ff0000"};
                case 'Flood': return {color: "#0000ff"};
                }
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 25 '18 at 1:48









                ghybsghybs

                24.2k32648




                24.2k32648

























                    1














                    As mentioned by @ghybs Leaflet.Draw doesn't support Groups or MultiPolygons. I needed the same functionality so a few years ago I created leaflet.pm which supports holes, MultiPolygons, GeoJSON and LayerGroups:



                    enter image description here



                    https://github.com/codeofsumit/leaflet.pm



                    Hope it helps.






                    share|improve this answer



















                    • 1





                      leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

                      – Scott
                      Jan 30 at 23:18
















                    1














                    As mentioned by @ghybs Leaflet.Draw doesn't support Groups or MultiPolygons. I needed the same functionality so a few years ago I created leaflet.pm which supports holes, MultiPolygons, GeoJSON and LayerGroups:



                    enter image description here



                    https://github.com/codeofsumit/leaflet.pm



                    Hope it helps.






                    share|improve this answer



















                    • 1





                      leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

                      – Scott
                      Jan 30 at 23:18














                    1












                    1








                    1







                    As mentioned by @ghybs Leaflet.Draw doesn't support Groups or MultiPolygons. I needed the same functionality so a few years ago I created leaflet.pm which supports holes, MultiPolygons, GeoJSON and LayerGroups:



                    enter image description here



                    https://github.com/codeofsumit/leaflet.pm



                    Hope it helps.






                    share|improve this answer













                    As mentioned by @ghybs Leaflet.Draw doesn't support Groups or MultiPolygons. I needed the same functionality so a few years ago I created leaflet.pm which supports holes, MultiPolygons, GeoJSON and LayerGroups:



                    enter image description here



                    https://github.com/codeofsumit/leaflet.pm



                    Hope it helps.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Dec 8 '18 at 16:22









                    ProblemsOfSumitProblemsOfSumit

                    9,16243250




                    9,16243250








                    • 1





                      leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

                      – Scott
                      Jan 30 at 23:18














                    • 1





                      leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

                      – Scott
                      Jan 30 at 23:18








                    1




                    1





                    leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

                    – Scott
                    Jan 30 at 23:18





                    leaflet.pm is excellent. I switched to it after banging my head against the wall with Leaflet.Draw and GeoJSON FeatureCollections of MultiPolygons.

                    – Scott
                    Jan 30 at 23:18


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463078%2fleaflet-draw-cannot-read-property-enable-of-undefined-adding-control-to-geoj%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()