Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove map callbacks when DrawControl removed from map #916

Merged
merged 2 commits into from
Feb 17, 2022

Conversation

clydebw
Copy link
Contributor

@clydebw clydebw commented Jan 21, 2022

This fixes a bug wherein if a DrawControl is added and removed from a Map several times, callbacks start accumulating, resulting in duplicate layers.

For example, the following adds a DrawControl to the map, and adds a polygon to it:

from ipyleaflet import Map, DrawControl
m = Map()
dc = DrawControl()
dc.data = [{
    'type': 'Feature',
    'properties': {
        'style': {
            'stroke': True,
            'color': '#3388ff',
            'weight': 4,
            'opacity': 0.5,
            'fill': True,
            'fillColor': None,
            'fillOpacity': 0.2,
            'clickable': True
        }
    },
    'geometry': {
        'type': 'Polygon',
        'coordinates': [
            [[-0.104027, 0.005665],
             [-0.069351, 0.023518],
             [-0.062141, 0.00103],
             [-0.104027, 0.005665]]
        ]
    }
}]
m.add_control(dc)
m

Now, by removing and adding the DrawControl several times, we can see that it becomes much darker in opacity, which is due to the same layer getting re-added to the map:

for i in range(10):
    m.remove_control(dc)
    m.add_control(dc)

Additionally, if we clear the DrawControl, and remove and add it again, we can observe it leaves behind a "ghost" polygon that we previously cleared:

dc.clear()
m.remove_control(dc)
m.add_control(dc)

This "ghost" disappears when we start drawing more Polygons, it appears to be the result of not updating the DrawControl model after updating the view.

Two additional callbacks appear to get added each time the DrawControl is added to the Map which I did not attempt to address:

this.model.on('msg:custom', this.handle_message.bind(this));
this.model.on('change:data', this.data_to_layers.bind(this));

Although I think they can probably be removed when the DrawControl is removed from the map too?

@clydebw
Copy link
Contributor Author

clydebw commented Jan 21, 2022

Actually, I'm thinking it might be best to remove the callbacks specific to a particular DrawControl, in the event that multiple DrawControls exist on the map. 🤔

I'll test/make the changes.

@martinRenou
Copy link
Member

Thanks a lot! I guess we've not been very careful on the "removing layers" use case. There might be issues with all kinds of layers

@clydebw
Copy link
Contributor Author

clydebw commented Jan 21, 2022

@martinRenou no prob—this is an absolutely fantastic project, and thank you for all that you (and others) do!

I've went ahead and removed those other callbacks when the DrawControl is removed from the Map. On the multiple DrawControls case, I'm actually not sure how to tell events from different DrawControls apart. Some quick searching around seems to indicate that maybe there isn't a way? For instance, see this issue. Multiple DrawControls isn't a use case of mine, anyways.

@clydebw
Copy link
Contributor Author

clydebw commented Feb 15, 2022

Hey @martinRenou, do you think this is OK to merge without addressing the "multiple draw control" use case described above?

@martinRenou
Copy link
Member

Yes I agree we shouldn't address this use-case (not sure it's even a use-case we want to support anyway). Thanks!

@martinRenou martinRenou merged commit 84aac77 into jupyter-widgets:master Feb 17, 2022
@clydebw clydebw deleted the fix-draw-control branch June 9, 2022 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants