import solara
import ipyleaflet
import traitlets
from traitlets import observe
import time
zoom = solara.reactive(4)
map_type = solara.reactive("stack")
class Map(ipyleaflet.Map,):
map_type = traitlets.Unicode().tag(sync=True)
# PATCH dummy trait
map_type_dummy = traitlets.Bool(False).tag(sync=True)
# PATCH: dummy observer
@observe("map_type_dummy")
def _on_map_dummy(self, change):
if change.new:
self.map_type_dummy=False
# The dummy reactive variable is set to True
# after issuing the command to remove the split
# map control
# By using reactive variable, we ensure a round-trip
# to the back-end..
# thus the control is removed.
# finally, request the update to the layers:
time.sleep(2)
# ^^ we should see that the control has been indeed removed
# while waiting for the timer.
self.set_stack_mode()
@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() # DONT update layers here,
# since it could potentially be done BEFORE
# the control is actually removed
# instead, update the dummy reactive variable:
self.map_type_dummy=True
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()
@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()