gee-community/geemap

Draw_control.features is inaccurate after editing a drawn object

nyehughes opened this issue · 3 comments

Environment Information

Python 3.11.6, geemap : 0.30.4, ee : 0.1.384, ipyleaflet : 0.17.3, running under Solara 1.25.1

Description

The draw_control.features list doesn't accurately reflect drawn features on the map after using the edit control. In turn, I believe the same problem is also affecting: draw_control.collections, map.user_roi, etc

Expected behaviour:
After editing an object using the buttons on the map, the draw_control.feature list should update to reflect the new edited geometry.

Observed behaviour:
After editing and clicking save, an extra feature is added to draw_control.features. After each edit and save, the number of extra objects in the draw_controls.features list goes up by one. This makes impossible to, e.g. accurately calculate the area of the geometry drawn on the map.

How to reproduce

Given the following code:

import geemap
import solara

@solara.component
def Page():
	def handle_draw(traget, action, geo_json):
		print(f"A draw event occurred of type: {action}, and the draw control features length is: {len(Map.draw_control.features)}")
    
	Map = geemap.Map(center=(40, -100), zoom=4)
	Map.draw_control.on_draw(handle_draw)
	display(Map)

Draw a square polygon on the map. Console reads:
A draw event occurred of type: created, and the draw control features length is: 1

Edit the square using the edit button and click 'Save'. Console reads:
A draw event occurred of type: edited, and the draw control features length is: 2

Edit the square again. Console reads:
A draw event occurred of type: edited, and the draw control features length is: 3

(Also, is the 'traget' parameter of Map.draw_control.on_draw() a typo? Should it be 'target'?)

@nyehughes Thank you for reporting. I can confirm this bug with the geemap.core module. Editing the drawn geometries appear to add new features into m._draw_control.features but did not remove the exsiting geometries.

@sufyanAbbasi @naschmitz Would you be able to look into this?

import ee
import geemap.core as geemap

m = geemap.Map()
m

image

image

I'm all booked up for today, but I'll take a look first thing on Monday. Thanks for finding, nyehughes@.

Sorry it took so long. Just dug into this issue.

There's an underlying bug with ipyleaflet.DrawControl that prevents the geometries from being updated (ipywidgets 1119). Until that's resolved, there's not much we can do. We only get access to the underlying GeoJSON data through the variable that isn't being updated, ipyleaflet.DrawControl.data.

Aside, you should be able to access the underlying geometries for the shapes drawn on the map with draw_control.geometries.

Looked into your question about Map.draw_control.on_draw as well and I'm not sure what you mean. ipyleaflet.DrawControl has an on_draw method, but the signature is as follows: def on_draw(self, callback, remove=False). Could you provide a link to the code?