Skip to content

Drawing polygons with different colors #1234

Open
@odhondt

Description

@odhondt

I am trying to draw polygons where the polygon color is determined by ipywidget.widgets.RadioButtons

This is what I got so far (inspired by #425)

import ipywidgets as widgets
from ipyleaflet import Map, GeomanDrawControl, basemaps

# Radio buttons for class selection
class_selector = widgets.RadioButtons(
    options=["Water", "Crop", "Urban"], description="Class:", disabled=False
)

# Function to return different colors based on class
def get_class_color(polygon_class):
    if polygon_class == "Water":
        return "#0000FF"  # Blue
    elif polygon_class == "Crop":
        return "#008800"  # Green
    elif polygon_class == "Urban":
        return "#FF0000"  # Red
    return "#000000"  # Default black

m = Map(center=(51.0, 0.0), zoom=12, basemap=basemaps.OpenStreetMap.Mapnik)

class LabelTool:
    def __init__(self, m):
        self.m = m
        self.current_polygon = None

        # Initial color is blue for "Water"
        initial_color = get_class_color(class_selector.value)

        # Geoman Draw control
        self.draw_control = GeomanDrawControl(
            circle={},
            polyline={},
            polygon={"shapeOptions": {"color": initial_color}},  # Initial color
        )
        self.m.add_control(self.draw_control)

        # Set up event listeners
        self.draw_control.on_draw(self.handle_draw)
        class_selector.observe(self.update_draw_color, 'value')

    # Draw event handler
    def handle_draw(self, target, action, geo_json):
        if action == 'create':
            self.current_polygon = geo_json
            polygon_class = class_selector.value
            color = get_class_color(polygon_class)

            # Update drawn polygon's color by recreating the control with the new color
            self.update_draw_color({'new': polygon_class})

    # Update polygon color based on the selected class
    def update_draw_color(self, change):
        polygon_class = class_selector.value
        color = get_class_color(polygon_class)

        # Remove and recreate draw control with updated color
        self.m.remove_control(self.draw_control)
        self.draw_control = GeomanDrawControl(
            circle={},
            polyline={},
            polygon={"shapeOptions": {"color": color}},  # Updated color
        )
        self.m.add_control(self.draw_control)

        # Reattach the draw event handler
        self.draw_control.on_draw(self.handle_draw)

# Display map and widgets
l = LabelTool(m)


widgets.VBox([m, class_selector])

The problem is that when the radio value is changed, the next create action draws several superimposed identical polygons (see the following screenshot, I slighly shifted the polygons for visualization)

Screenshot 2024-10-09 at 09 27 30

Any idea how to fix that?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions