Skip to content

Commit

Permalink
Fix draw control editing bug (#2046)
Browse files Browse the repository at this point in the history
* Fix draw control editing bug

* Fix unittest error

* Skip GDAL testing on Windows

* Clean up code

* Reduce nesting and remove comment line
  • Loading branch information
giswqs authored Jul 15, 2024
1 parent 16b2e02 commit a0a79c4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 41 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ jobs:
python-version: "3.11"
- name: Install GDAL
run: conda install -c conda-forge gdal --yes
- name: Test GDAL installation
run: |
python -c "from osgeo import gdal"
gdalinfo --version
# - name: Test GDAL installation
# run: |
# python -c "from osgeo import gdal"
# gdalinfo --version
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
77 changes: 40 additions & 37 deletions geemap/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,26 +178,39 @@ def _sync_geometries(self):
return
# The current geometries from the draw_control.
test_geojsons = self._get_synced_geojson_from_draw_control()
i = 0
while i < self.count and i < len(test_geojsons):
local_geometry = None
test_geometry = None
while i < self.count and i < len(test_geojsons):
local_geometry = self.geometries[i]
test_geometry = common.geojson_to_ee(test_geojsons[i], geodesic=False)
if test_geometry == local_geometry:
i += 1
else:
break
if i < self.count and test_geometry is not None:
self.geometries[i] = test_geometry
if self.layer is not None:
self._redraw_layer()
self.geometries = [
common.geojson_to_ee(geo_json, geodesic=False) for geo_json in test_geojsons
]

def _redraw_layer(self):
if self.host_map:
if not self.host_map:
return
# If the layer already exists, substitute it. This can avoid flickering.
if _DRAWN_FEATURES_LAYER in self.host_map.ee_layers:
old_layer = self.host_map.ee_layers.get(_DRAWN_FEATURES_LAYER, {})[
"ee_layer"
]
new_layer = ee_tile_layers.EELeafletTileLayer(
self.collection,
{"color": "blue"},
_DRAWN_FEATURES_LAYER,
old_layer.visible,
0.5,
)
self.host_map.substitute(old_layer, new_layer)
self.layer = self.host_map.ee_layers.get(_DRAWN_FEATURES_LAYER, {}).get(
"ee_layer", None
)
self.host_map.ee_layers.get(_DRAWN_FEATURES_LAYER, {})[
"ee_layer"
] = new_layer
else: # Otherwise, add the layer.
self.host_map.add_layer(
self.collection, {"color": "blue"}, _DRAWN_FEATURES_LAYER, False, 0.5
self.collection,
{"color": "blue"},
_DRAWN_FEATURES_LAYER,
False,
0.5,
)
self.layer = self.host_map.ee_layers.get(_DRAWN_FEATURES_LAYER, {}).get(
"ee_layer", None
Expand All @@ -217,7 +230,6 @@ def _handle_geometry_edited(self, geo_json):
self.last_geometry = geometry
self.last_draw_action = DrawActions.EDITED
self._sync_geometries()
self._redraw_layer()
self._geometry_edit_dispatcher(self, geometry=geometry)

def _handle_geometry_deleted(self, geo_json):
Expand Down Expand Up @@ -250,13 +262,6 @@ def __init__(self, host_map, **kwargs):
"""
super(MapDrawControl, self).__init__(host_map=host_map, **kwargs)

# NOTE: Overridden for backwards compatibility, where edited geometries are
# added to the layer instead of modified in place. Remove when
# https://github.com/jupyter-widgets/ipyleaflet/issues/1119 is fixed to
# allow geometry edits to be reflected on the tile layer.
def _handle_geometry_edited(self, geo_json):
return self._handle_geometry_created(geo_json)

def _get_synced_geojson_from_draw_control(self):
return [data.copy() for data in self.data]

Expand All @@ -276,20 +281,18 @@ def handle_draw(_, action, geo_json):
raise Exception(e)

self.on_draw(handle_draw)
# NOTE: Uncomment the following code once
# https://github.com/jupyter-widgets/ipyleaflet/issues/1119 is fixed
# to allow edited geometries to be reflected instead of added.
# def handle_data_update(_):
# self._sync_geometries()
# self.observe(handle_data_update, 'data')

def handle_data_update(_):
self._sync_geometries()
# Need to refresh the layer if the last action was an edit.
if self.last_draw_action == DrawActions.EDITED:
self._redraw_layer()

self.observe(handle_data_update, "data")

def _remove_geometry_at_index_on_draw_control(self, index):
# NOTE: Uncomment the following code once
# https://github.com/jupyter-widgets/ipyleaflet/issues/1119 is fixed to
# remove drawn geometries with `remove_last_drawn()`.
# del self.data[index]
# self.send_state(key='data')
pass
del self.data[index]
self.send_state(key="data")

def _clear_draw_control(self):
self.data = [] # Remove all drawn features from the map.
Expand Down

0 comments on commit a0a79c4

Please sign in to comment.