5

I am used to working

with OL3 and I wanted to try using leaflet and see if it is as powerful as OL. I loaded a map with some data from a GeoServer WFS layer using this tutorial from Georepublic.

var group = new L.featureGroup().addTo(map);
var geojsonlayer;
function handleJson(data) {
    //      console.log(data);
    geojsonlayer=L.geoJson(data, {
        style: function (feature) {
            return {
                "weight": 2,
                "opacity": 0.65
            };
        },
        onEachFeature: function (feature, my_Layer) {
            my_Layer.bindPopup("ID : "+feature.properties.id+"<br />Name : "+feature.properties.name);
        }
    }).addTo(group);
    map.fitBounds(group.getBounds());
}

I wanted to add some editing and found the Leaflet.draw plugin I loaded it, and so far I can add a feature to the database ( knowing how painful it will be with WFS-T I used an AJAX call to a php script instead ). Here is how I call the draw control :

var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
    edit: {
            featureGroup: drawnItems
    }
});
map.on('draw:created', function (e) {
    //Here I call the php script that stores the created feature in the DB
});

The problem is when I want to edit the existing features using the Leaflet.draw plugin, so I thought of changing the featureGroup in edit to group like this :

var drawControl = new L.Control.Draw({
    edit: {
            featureGroup: group
    }
});

but now I get this error:

Uncaught TypeError: Cannot read property 'enable' of undefined

I have done some research and found that I need to enable editing of the layer with this : layer.editing.enable(); the problem is where to add it so that when I click on the edit icon in the Leaflet.draw control I can edit my layer.

I kind of liked the Leaflet.draw plugin menu on the side, is it possible to solve my problem using this plugin or should I make my own editing menu?

  • I have exactly the same problem. Have you managed to solve this? – user1919 Jul 27 '16 at 8:16
  • Not yet but I'm making a custom control using that same plugin to avoid this problem – Hicham Zouarhi Jul 27 '16 at 8:18
  • What approach are you thinking of implementing for building the control? – user1919 Jul 27 '16 at 8:29
  • 1
    Making a similar menu in html just for the editing and deleting. Catching the click or whatever events you choose and add the layer.editing.enable() – Hicham Zouarhi Jul 27 '16 at 8:32
  • 1
    I'll post it as an answer when I finally make it – Hicham Zouarhi Jul 27 '16 at 8:46
3

Thanks to the help of @user1919 who pointed me to the solution proposed in Stackoverflow, I could edit the existing layer with the plugin Leaflet.draw without customizing it ( at least not it's code ).

The edits now are made on the onEachFeature function in the L.geoJSON call like this:

var selectedFeature = null;
function handleJson(data) {
    geojsonlayer=L.geoJson(data, {
        onEachFeature: function (feature, layer) {
            group.addLayer(layer);
            layer.on('click', function(e){
                if(selectedFeature){
                    selectedFeature.editing.disable();
                    // and Here I'll add the code to store my edited polygon in the DB or whatever I want to do with it
                }
                selectedFeature = e.target;
                e.target.editing.enable();
            });
        }
    }).addTo(group);
}

and so there is no need to use the edits from the menu in Leaflet.draw control

Now to use the Leaflet.draw control I had to add to the drawnItems, which is the editable layer defined in Leaflet.draw control, the feature which I selected. It looks like this :

drawnItems.addLayer(e.target);

and define drawnItems in the edit of the Leaflet.draw control like this :

var drawControl = new L.Control.Draw({
    edit: {
        featureGroup: drawnItems
    }
});
  • great job. I made it also work for markers. But for lines and polygons I still get errors. Does it work for all your geometries? – user1919 Jul 27 '16 at 13:56
  • 1
    I am working only with polygons and it works – Hicham Zouarhi Jul 27 '16 at 13:57
  • According to here the plugin doesn't work properly with Multi Geometries (github.com/Leaflet/Leaflet.draw/issues/560) Can you please confirm if your polygon geometries are of type Multipolygon or Polygon? Thanks. – user1919 Jul 27 '16 at 14:01
  • 1
    I've checked in my DB and in GeoServer, my geometries are Polygons – Hicham Zouarhi Jul 27 '16 at 14:06
3

If my understanding is correct, the root cause of the issue resides in the fact that the layers you want to make editable through Leaflet.draw plugin are nested within a Layer Group (e.g. if they are built through L.geoJSon() factory, which outputs a Feature Group).

But Leaflet.draw does not like nested groups in the drawnItems Feature Group, so you have to add only "non-group" layers.

In that case, you would just need to "flatten" your Layer Group (if any) and extract only single / non-group layers, so that you can now safely add them into drawnItems.

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);
  }
}

Updated JSFiddle: http://jsfiddle.net/suL12z93/4/

Note: as mentioned in the code, there is actually a thread at Leaflet issue #4461 about adding such a functionality to core Leaflet. I am sure Leaflet maintainers would be more than happy to receive a Pull Request to implement it! :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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