Custom transform control for geoman

374 Views Asked by At

I am trying to add a custom transform control to geoman, to do certain transformations with polylines and polygons. I see that on edit, geoman draws hint lines above vertices etc. I would like my tool to highlight polylines/polygons with the same type of hints. Below is the skeleton of my action:

const ConvertAction = L.Toolbar2.Action.extend({
  options: {
    toolbarIcon: {
      html:
        '<div class="icon-maps icon-convert" title="Convert point"></div>',
      tooltip: 'Convert point'
    }
  },
  addHooks: () => {
    // draw polygon
    // map.pm.enableDraw();

    changeConvert();
  }
});

function changeConvert() {
  convert = true;
  map.eachLayer(function (layer) {
    if (layer.feature && layer.feature.geometry.type === 'Point') {
      layer._icon.style['pointer-events'] = 'auto';
    }
  });
}

Is there an internal function or something that I could use to outline shapes? When I enable Edit layers tool already built into the geoman, shapes are outlined for me. How could I achieve this from my code without having to reimplement the entire thing?

1

There are 1 best solutions below

0
On BEST ANSWER

Thus far, after quickly reviewing geoman code, I was able to come up with:

  const ConvertAction = L.Toolbar2.Action.extend({
    options: {
      toolbarIcon: {
        html:
          '<div class="icon-maps icon-convert" title="Convert point"></div>',
        tooltip: 'Convert point'
      }
    },
    addHooks: () => {
      // draw polygon
      // map.pm.enableDraw();
      if (!convert) changeConvert();
      else disableConvert();
    }
  });

  function changeConvert() {
    convert = true;
    map.eachLayer(function (layer) {
      if (
        layer?.feature?.geometry.type === 'Polygon' ||
        layer?.feature?.geometry.type === 'LineString'
      ) {
        const coords = layer.getLatLngs();

        const markerGroup = new L.LayerGroup();
        markerGroup._pmTempLayer = true;

        const createMarker = (latlng) => {
          const marker = new L.Marker(latlng, {
            draggable: true,
            icon: L.divIcon({ className: 'marker-icon' })
          });
          layer.options.pane =
            (map.pm.globalOptions.panes &&
              map.pm.globalOptions.panes.vertexPane) ||
            'markerPane';

          marker._pmTempLayer = true;

          markerGroup.addLayer(marker);

          return marker;
        };

        const handleRing = (coordsArr) => {
          // if there is another coords ring, go a level deep and do this again
          if (Array.isArray(coordsArr[0])) {
            return coordsArr.map(handleRing, this);
          }

          // the marker array, it includes only the markers of vertexes (no middle markers)
          const ringArr = coordsArr.map(createMarker);

          return ringArr;
        };
        const markers = handleRing(coords);
        map.addLayer(markerGroup);
      }
    });
  }

  function disableConvert() {
    convert = false;
    map.eachLayer(function (layer) {
      if (
        layer.dragging &&
        layer.options?.draggable === true &&
        layer._pmTempLayer === true
      ) {
        console.log('temp layer:', layer);
        map.removeLayer(layer);
      }
    });
    update();
  }

Seems like an excessive amount of code, and reimplementation [and probably not as good the geoman version as I don't fully understand geoman code by far] of existing functionality.

How do I simplify/fix this?