Search code examples
reactjsleafletgeojsonreact-leaflet

Getting updated coordinates after dragging in Leaflet


I am using react-leaflet and Leaflet.Path.Drag to drag GeoJSON. I would need to keep GeoJSON coordinations in React state. The issue is that updated coordinations on dragEnd are not corrent and GeoJSON position is not correct after dragging.

codesandbox.io

App.js

import React from "react";
import { MapContainer, GeoJSON, TileLayer, useMap } from "react-leaflet";
import "./styles.css";
import "leaflet/dist/leaflet.css";

require("leaflet-path-drag");

export default function App() {
  const geoJSONRef = React.useRef(null);
  const [coordinates, setCoordinates] = React.useState([
    [-104.98569488525392, 39.63431579014969],
    [-104.98569488525392, 39.64165260123419],
    [-104.97161865234376, 39.64165260123419],
    [-104.97161865234376, 39.63431579014969]
  ]);

  const handleFeature = (layer) => {
    layer.makeDraggable();
    layer.dragging.enable();

    layer.on("dragend", function (e) {
      const latLngs = e.target.getLatLngs()[0];
      console.log({ latLngs });
      const coordinates = latLngs.map((point) => [point.lng, point.lat]);
      geoJSONRef.current.eachLayer((geoLayer) => {
        console.log(geoLayer.getLatLngs()[0]);
      });
      setCoordinates(coordinates);
    });
  };

  const object = {
    polygon: {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          properties: {},
          geometry: {
            type: "Polygon",
            coordinates: [[...coordinates]]
          }
        }
      ]
    }
  };

  return (
    <MapContainer center={[39.63563779557324, -104.99234676361085]} zoom={12}>
      <TileLayer
        attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
      />
      <GeoJSON
        key={`${coordinates}`}
        ref={geoJSONRef}
        data={object.polygon}
        style={() => ({
          color: "green",
          weight: 3,
          opacity: 0.5
        })}
        draggable={true}
        pmIgnore={false}
        onEachFeature={(feature, layer) => handleFeature(layer)}
      ></GeoJSON>
    </MapContainer>
  );
}

Solution

  • I am not sure why but e.target._latlngs[0] and e.target.getLatLngs()[0]; give a different result. Therefore if you try using the first expression it works as expected without moving further the dragged polygon

    layer.on("dragend", function (e) {
          const latLngs = e.target._latlngs[0]; // here replace the expression
          const coordinates = latLngs.map((point) => [point.lng, point.lat]);
          geoJSONRef.current.eachLayer((geoLayer) => {
            // console.log(geoLayer.getLatLngs()[0]);
          });
          setCoordinates(coordinates);
    });