0

My purpose here is to allow only one polygon on the map. My approach has been saving the new layer during onCreated method in a var or array and in the method onDrawStart get it and delete, so once the user tries to draw another shape, the previous one gets removed, but this is not working, any suggestion how to make it possible?

onCreated = (e) => {
  coordinates = e.layer._bounds;
  layer.push(e.layer);
}

onDrawStart = (e) => {
  layer.forEach((ele) => {
    ele.remove()
  });
}

Is there maybe any way to access to onDelete and to access here to the built in remove all??

kboul
  • 13,836
  • 5
  • 42
  • 53
Nendil
  • 65
  • 1
  • 5

2 Answers2

2

You can achieve that by checking the stored drawn layers number using a featureGroupRef. If the number is bigger than one then delete the previous stored layer and only keep the latest one. Here is the code:

const [editableFG, setEditableFG] = useState(null);

const onCreated = e => {
    console.log(e);
    console.log(editableFG);

    // here you have all the stored layers
    const drawnItems = editableFG.leafletElement._layers;
    console.log(drawnItems);
    // if the number of layers is bigger than 1 then delete the first
    if (Object.keys(drawnItems).length > 1) {
        Object.keys(drawnItems).forEach((layerid, index) => {
            if (index > 0) return;
            const layer = drawnItems[layerid];
            editableFG.leafletElement.removeLayer(layer);
        });
        console.log(drawnItems); // here you will get only the last one
    }
};

const onFeatureGroupReady = reactFGref => {
    // store the featureGroup ref for future access to content
    setEditableFG(reactFGref);
};

return (
    <Map
        center={[37.8189, -122.4786]}
        zoom={13}
        style={{ height: '100vh' }}>
        <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
        />
        <FeatureGroup
            ref={featureGroupRef => {
                onFeatureGroupReady(featureGroupRef);
            }}>
            <EditControl position="topright" onCreated={onCreated} />
        </FeatureGroup>
    </Map>
);

Demo

kboul
  • 13,836
  • 5
  • 42
  • 53
  • Hi there, I used your solution to gain ability to draw only one shape, but I got ```cannot read propery leafletElement of undefined```, I used leaflet v1.7.1, leaflet-draw 1.0.4, react-leaflet v2.8.3 and react-leaflet-draw v0.19.8, I guess leafletElement is replaced with something alternative in new versions. How can I implement deleting shapes when new shape is created in versions above? – Abolfazl Heidarpour Jul 18 '21 at 15:34
  • Please ask this in a new question and provide an example with your attempt with preferably a reproducible demo. – kboul Jul 18 '21 at 16:59
0

kbouls answer does not work anymore with the current react-leaflet since they removed ref access to FeatureGroup.

Proposed solution for the new version:

let lastAddedPolygonID;

  const _onCreate = (e) => {

    if (layerType === "polygon") {

      // Remove previous polygon from map
      if (lastAddedPolygonID) {
        e.sourceTarget._layers[lastAddedPolygonID].remove();
      }
      lastAddedPolygonID = _leaflet_id;
    }
  };

Not sure if it creates any unexpected side-effects, please edit my answer if it does.

kibz
  • 1
  • 1