Skip to content

Inconsistent issue when removing a split map control from an ipyleaflet map #850

@lopezvoliver

Description

@lopezvoliver

I am facing a very difficult issue to trace, so I came up with this almost reproducible example.

This animation shows the demo initially working as expected. Then, I refresh the app and there is an issue with the demo: the split-map control does not get removed correctly.

bug_split_map_inconsistent

Setup

Let's start with defining a custom class inheriting from ipyleaflet.Map that can dynamically change between a split map and a "stack" map (layers stacked on top of each other).

import ipyleaflet
import traitlets
from traitlets import observe

class Map(ipyleaflet.Map,):
    map_type = traitlets.Unicode().tag(sync=True)

    @observe("map_type")
    def _on_map_type_change(self, change):
        if hasattr(self, "split_map_control"):
            if change.new=="stack":
                self.remove(self.split_map_control)  
                self.set_stack_mode()

            if change.new=="split":
                self.set_split_mode()     

    def set_stack_mode(self):
       self.layers = tuple([
           self.esri_layer,
           self.topo_layer
       ]) 

    def set_split_mode(self):
        self.layers = ()
        self.add(self.left_layer)
        self.add(self.right_layer)
        self.add(self.split_map_control)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.osm = self.layers[0]

        esri_url=ipyleaflet.basemaps.Esri.WorldImagery.build_url()
        topo_url = ipyleaflet.basemaps.OpenTopoMap.build_url()

        self.left_layer = ipyleaflet.TileLayer(url = topo_url, name="left")
        self.right_layer = ipyleaflet.TileLayer(url = esri_url, name="right")
        self.topo_layer = ipyleaflet.TileLayer(url=topo_url, name="topo", opacity=0.25)
        self.esri_layer = ipyleaflet.TileLayer(url=esri_url, name="esri")

        self.stack_layers = [
            self.esri_layer,
            self.topo_layer,
        ]

        self.split_map_control = ipyleaflet.SplitMapControl(
            left_layer=self.left_layer, 
            right_layer=self.right_layer)


        if self.map_type=="split":
            self.set_split_mode()

        if self.map_type=="stack":
            self.set_stack_mode()

I haven't encountered the issue when testing the ipyleaflet code without solara.

Now let's add solara to the equation:

import solara
import ipyleaflet
import traitlets
from traitlets import observe
zoom=solara.reactive(4)
map_type = solara.reactive("stack")

class Map(ipyleaflet.Map,):
.... (same code defining Map as above)
....


@solara.component
def Page():
    with solara.ToggleButtonsSingle(value=map_type):
       solara.Button("Stack", icon_name="mdi-layers-triple", value="stack", text=True)
       solara.Button("Split", icon_name="mdi-arrow-split-vertical", value="split", text=True)   
    Map.element(
        zoom=zoom.value,
        on_zoom=zoom.set,
        map_type=map_type.value
    ) 

Page()

Could you please help diagnose this problem?

Here's a live version of an app where I am facing this issue (also inconsistently! try refreshing until you encounter the issue).

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