Mapbox and Leaflet Draw edit only 1 group

2019-09-08 23:10发布

问题:

I want to add multiple layergroup or featuregroup objects or something else if there's a better way on a map that can contain multiple polygons in each. I want these groups to be distinguishable so they can be used in conjunction with datatables and the leaflet draw tool so that when I select a row within datatables, only the polygons within the related group can be edited or deleted using the draw tool and any new polygons are only added to that group.

I've done this before with only a single polygon and one featuregroup, but how do I handle multiple groups?

            featureGroup = L.featureGroup().addTo(map);

        var drawControl = new L.Control.Draw({
            edit: {
                featureGroup: featureGroup
            },
            draw: {
                marker: false,
                polygon: true,
                polyline: false,
                rectangle: false,
                circle: false
            },
            locate: {
                marker: true
            }
        }).addTo(map);

        $('.leaflet-control-zoom').css('margin-top', '45px');

        L.drawLocal.draw.toolbar.buttons.polygon = 'Draw damage area';
        L.drawLocal.edit.toolbar.buttons.edit = 'Edit damage area';
        L.drawLocal.edit.toolbar.buttons.remove = 'Delete damage area';

        if (jsModel.polygonpoints)
        {
            var polygonPoints = jsModel.polygonpoints.split(';');
            if (polygonPoints.length > 0) {
                var polyPoints = [];
                for (var i = 0; i < polygonPoints.length; i++) {
                    var point = polygonPoints[i].split(',');

                    polyPoints.push([parseFloat(point[0]), parseFloat(point[1])]);
                }
                var points = polyPoints;

                var polyOptions = {
                    color: '#f06eaa'
                };

                var polygon;
                if (typeof featureGroup !== "undefined") {
                    polygon = L.polygon(points, polyOptions).addTo(self.featureGroup);
                    self.polygon = polygon;
                }
            }   
        }

I'm trying to add the polygons during a render of my datatable columns. Here is what I have so far. I saw a post somewhere that talked about adding multiple draw tools and then only make the current one available. Not sure if this is a good way to do it, but if it is, what can I use in my button's "data-draw-control" to be able to point to the one I want to be current?

                "columns": [
                {
                    "render": function (data, type, row) {
                        var featureGroup = L.featureGroup().addTo(map);
                        var drawControl = new L.Control.Draw({
                            edit: {
                                featureGroup: featureGroup
                            },
                            draw: {
                                marker: false,
                                polygon: true,
                                polyline: false,
                                rectangle: false,
                                circle: false
                            }
                        }).addTo(map);

                        for (var al = 0; al < row.areaList.length; al++)
                        {
                            var polyPoints = [];
                            for (var ap = 0; ap < row.areaList[al].areaPointList.length; ap++)
                            {
                                if (row.areaList[al].areaPointList[ap].x == 0 && row.areaList[al].areaPointList[ap].y == 0)
                                {
                                    if (polyPoints.length != 0)
                                    {
                                        //add polygon to map
                                        L.polygon(polyPoints).addTo(featureGroup);
                                        polyPoints.length = 0;
                                    }
                                }
                                else
                                {
                                    polyPoints.push([parseFloat(row.areaList[al].areaPointList[ap].x), parseFloat(row.areaList[al].areaPointList[ap].y)]);
                                }
                            }
                        }
                        return "<button type='button' class='btn-zoom' data-draw-control='" + drawControl + "'><i class='fa fa-search'></i></button";
                    }
                }

回答1:

First create two featuregroups and a layercontrol so you can toggle between them:

var layerControl = new L.Control.Layers({
    'FeatureGroup 1': new L.FeatureGroup(),
    'FeatureGroup 2': new L.FeatureGroup()
}).addTo(map);

Now then you toggle between those, the map fires a basemapchanged event which contains the currently selected featuregroup, store that in a variable:

var currentFeatureGroup;

map.on('baselayerchange', function (e) {
    currentFeatureGroup = e.layer;
});

When you draw something, the map fires another event where you can process the drawn feature. Create a function that returns the currently selected featuregroup and store it into that:

function getCurrentFeatureGroup () {
    return currentFeatureGroup;
}

map.on('draw:created', function (e) {
    var featureGroup = getCurrentFeatureGroup();
    if (featureGroup instanceof L.FeatureGroup) {
        featureGroup.addLayer(e.layer);
    } else {
        alert('Please select a featuregroup');
    }
});

Here's an example of the concept on Plunker: http://plnkr.co/edit/9ZEjuP?p=preview