Triggering Geoman event with custom button

744 Views Asked by At

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 ?

2

There are 2 best solutions below

1
On

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/

0
On

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.