diff --git a/geemap/core.py b/geemap/core.py index ccce5a3dc3..a1635fa52d 100644 --- a/geemap/core.py +++ b/geemap/core.py @@ -178,30 +178,59 @@ 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 + ] + # i = 0 + # while i < self.count and i < len(test_geojsons): + # self.geometries = [] + + # 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() def _redraw_layer(self): if self.host_map: - self.host_map.add_layer( - 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 - ) + # 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_layer(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.layer = self.host_map.ee_layers.get(_DRAWN_FEATURES_LAYER, {}).get( + "ee_layer", None + ) def _handle_geometry_created(self, geo_json): geometry = common.geojson_to_ee(geo_json, geodesic=False) @@ -217,7 +246,7 @@ def _handle_geometry_edited(self, geo_json): self.last_geometry = geometry self.last_draw_action = DrawActions.EDITED self._sync_geometries() - self._redraw_layer() + # self._redraw_layer() self._geometry_edit_dispatcher(self, geometry=geometry) def _handle_geometry_deleted(self, geo_json): @@ -254,8 +283,8 @@ def __init__(self, host_map, **kwargs): # 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 _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] @@ -276,20 +305,23 @@ 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() + 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.