1

In my React app, I'm using Geoman on a Leaflet map with several Geoman tools. Currently, I have an event listener that verify which tool is used and chose the right function to fire when the user has finished with the tool :

  useEffect(() => {
    map.on("pm:create", ({ shape, layer }) => {
      if (mapMode === MapMode.SPLIT_SPACES) {
        handlingSplit(shape, layer);
      } else {
        handlingCreate(shape, layer);
      }
      setMapMode(MapMode.NONE);
    });
    return (): void => {
      if (map.hasEventListeners("pm:create")) {
        map.removeEventListener("pm:create");
      }
    };
  }, [map, setMapMode, handlingCreate, mapMode]);

I'd like to add a button to trigger the handlingSplit() function instead of clicking on the points on the map. The problem is, this function needs both shape and layer provided by the pm:create event. Is there any way to get those data ?

FE-P
  • 69
  • 8

2 Answers2

0

You will always need a reference to a layer, so you need to store the data of the last created layer and then if you click on a button get this data from the variable.

I can't say you how to do this in react but in vanilla it looks like this:

var shape, layer;
map.on('pm:create', function(e) {
  shape = e.shape;
  layer = e.layer;
});

A custom control can be created like this:

map.pm.Toolbar.createCustomControl({
  name: 'SplitButton',
  block: 'edit',
  onClick: ()=>{
    console.log(shape, layer);
    alert(shape);
  },
  className: 'leaflet-pm-icon-cut'
});

https://jsfiddle.net/qx07eLn2/

Falke Design
  • 10,635
  • 3
  • 15
  • 30
  • Correct me if I'm wrong, but it only works if your last layer has been finished. If I draw a Rectangle, put two points of a Polyline and then click on the custom button, the alert text is "Rectangle". What Id' like, is to get the Polyline shape and layer at this point. – FE-P Jan 03 '23 at 09:52
0

I've succeeded in catching the elements needed to fire my function, using the map drawstart and layer change event listeners :

  useEffect(() => {
    map.on("pm:drawstart", ({ workingLayer }) => {
      if (mapMode === MapMode.SPLIT_SPACES) {
        setSplitWorkingLayer(workingLayer);
      }
      workingLayer.on("pm:change", () => {
        if (workingLayer._parts.length !== splitWorkingLayer?._parts.length) {
          setSplitWorkingLayer(workingLayer);
        }
      });
    });
    return (): void => {
      if (map.hasEventListeners("pm:drawstart")) {
        map.removeEventListener("pm:drawstart");
      }
    };
  }, [map, mapMode]);

I can now fire my function and remove the workingLayer from the map... but : the layer vertexes stayed on the map and my cursor still allowed me to place more, even though the tool is unselected and the previously drawn layer has disappeared (as intended). SO I also had to add map.pm.disableDraw(); to my button onClick.

It looks like it works fine now.

FE-P
  • 69
  • 8