react-leaflet-draw icon indicating copy to clipboard operation
react-leaflet-draw copied to clipboard

Edit not working on programatically added polygons

Open jorgenboganes opened this issue 3 years ago • 10 comments

I send a list of polygons (LatLngTuple[][]) into my PolygonLayer-component on render, so that they are there when the map loads. I also give the user to draw more and edit/delete polygons.

When I try to delete a polygon that is in the initial polygons, it works. But when I try to edit one, this happens:

Screenshot 2021-06-18 at 13 49 17

So the polygon doesn't actually get edited, but the draggable squares move. This does not happen with a polygon I add via the toolbar.

jorgenboganes avatar Jun 18 '21 11:06 jorgenboganes

Hi, @jorgenboganes. Did you manage to solve this problem with editing polygons? I have the same issue with my project.

nkulchytskyi avatar Dec 16 '21 13:12 nkulchytskyi

I've the same problem. It seems an initialization problem, if you cancel edit an try edit again, it shows vertexs correctly. chrome-capture3

Maybe it's related with this issue on leaflet-draw

sergioedo avatar Dec 28 '21 10:12 sergioedo

This happens when you update the state of the polygon while in edit mode. You can't edit and render polygons at the same time - the state update is busted up stream :(

I resolved this by disabling the edit before making changes to the polygon list in the render.

  // Turn the edit mode on
  // When we start drawing we need to turn edit mode off
  const enableDrawPolygon = () => {
    getDrawControls()?._toolbars?.draw?._modes?.polygon?.handler?.enable()
    getDrawControls()?._toolbars?.edit?._modes?.edit?.handler?.disable() 
    setIsDrawing(true)
    setIsCreating(true)
    drawControls?._toolbars?.draw?._activeMode?.handler?._poly?.setStyle(DRAWING_STYLES)
    // console.log('drawControls', drawControls)
  }

  // When drawing done we need to enter edit mode
  const enableEditPolygon = () => {
    drawControls?._toolbars?.draw?._activeMode?.handler?._poly?.setStyle(DRAWING_STYLES)
    getDrawControls()?._toolbars?.draw?._modes?.polygon?.handler?.disable()
    getDrawControls()?._toolbars?.edit?._modes?.edit?.handler?.enable() 
    setIsDrawing(true)
    setIsCreating(false)
  }

  // Turn the edit mode off
  const disableDrawPolygon = () => {
    getDrawControls()?._toolbars?.draw?._modes?.polygon?.handler?.disable()
    getDrawControls()?._toolbars?.edit?._modes?.edit?.handler?.disable() 
    setIsDrawing(false)
    setIsCreating(false)
  }


  const onPolyUpdated = async (event: Json) => {
    // console.log('event', event)
    // console.log('edited', event)
    await disableDrawPolygon()
    if (event?.layer?._latlngs[0] && event?.layer?._path) {
      const closedPoly = closePolygon(castLatLngArrayToTupleArray(event?.layer?._latlngs[0]))
      console.log('closedPoly', closedPoly)
      await setMeasurePolygon(closedPoly.map((point) => new LatLng(point[0], point[1])))
      await setEditablePolygons([closedPoly])
    }

    if (event?.poly?._latlngs && event?.poly?._latlngs[0]) {
      console.log( event?.poly?._latlngs[0],  event?.poly)
      const closedPoly = closePolygon(castLatLngArrayToTupleArray(event?.poly?._latlngs[0]))
      console.log('closedPoly', closedPoly)
      await setMeasurePolygon(closedPoly.map((point) => new LatLng(point[0], point[1])))
      await setEditablePolygons([closedPoly])
    }
    await enableEditPolygon()
  }


<EditControl
      position='topright'
      draw={{
        polyline: false,
        polygon: {
          edit: {color: 'red'},
          draw: {color: 'red'}
        },
        rectangle: false,
        circle: false,
        marker: false,
        circlemarker: false
      }}
      onMounted={onMounted}
      onCreated={onPolyCreated}
      onEdited={onPolyUpdated}
      onEditMove={onPolyUpdated}
      onEditVertex={onPolyUpdated}
      onDrawVertex={onCreateCaptureChanges}  
    />

I was also able to resolve this by no updating the polygon list while editing - keeping track of changes in a separate array.

  const [editablePolygons, setEditablePolygons] = useAsyncSetState<LatLangList[]>([])
  const [initialEditablePolygons, setInitialEditablePolygons] = useAsyncSetState<LatLangList[]>([])


  <FeatureGroup>
    {/*  The ability to edit - some how talks to the edit group */}
    <EditControl
      position='topright'
      draw={{
        polyline: false,
        polygon: {
          edit: {color: 'red'},
          draw: {color: 'red'}
        },
        rectangle: false,
        circle: false,
        marker: false,
        circlemarker: false
      }}
      onMounted={onMounted}
      onCreated={onPolyCreated}
      onEdited={onPolyUpdated}
      onEditMove={onPolyUpdated}
      onEditVertex={onPolyUpdated}
      onDrawVertex={onCreateCaptureChanges}  
    />

    {/* The distance Indicator */}
    <MouseTooltip
      className="floating-tool-tip"
      visible={isMeasuring === true}
      offsetX={0}
      offsetY={10}
    >
      Distance: {distance || 0}
    </MouseTooltip>
    {/* Any editable polygons */}  
    {(editablePolygons || []).map((positions, index) => {
      // .. []
      return <React.Fragment key={`${index}`}>
        {(positions) && <>
          <Polygon 
            className='timeline-layer-polygon-editable'
            positions={positions}
          />
        </>}
      </React.Fragment>
    })}
  </FeatureGroup>

Either way it's a frustrating bug!

PS: thanks to all the people for the edit lib.

JoueBien avatar Apr 01 '22 07:04 JoueBien

Any update on this bug?

davis3tnpolitics avatar Sep 10 '22 17:09 davis3tnpolitics

hello, are u using an API to get the list of polygons?

farahkhaled avatar Oct 26 '22 15:10 farahkhaled

Any updates on this issue? image

Kumail-FD avatar Jan 16 '23 09:01 Kumail-FD

Hey y'all, we solved this by adapting the example that @TurtIeSocks created here. Feeding the polygons into a FeatureGroup via a ref allows you to render the polygons and then edit them with the ref as the source of truth.

We handle state upstream and use some async operations to pull in the polygons, so it worked well for us to use the example as a base component. It's not exactly a perfect fix, but we were able to get it to work. So if you're still running into this issue with no fix in sight, give that a try. A big thanks to @TurtIeSocks and @sgmbr for the example.

davis3tnpolitics avatar Jan 18 '23 18:01 davis3tnpolitics

Super helpful @davis3tnpolitics thank you!

AnthonyGress avatar Feb 09 '23 18:02 AnthonyGress

Try this: Add key to Polygon, like that: <Polygon key={Math.random()} .... /> this might solve your problem Screenshot_2

anhgithub16 avatar Mar 30 '23 08:03 anhgithub16

Can confirm that sample by @TurtIeSocks works great. Really easy to catch changes, deletes, creations and it is then easily converted to geojson so you can store it. Thanks

marisancans avatar Sep 10 '23 07:09 marisancans