tn-historical-imagery / pages /01_imagery.py
giswqs's picture
Remove layer manager
8c09e2f
import os
import leafmap
import solara
import ipywidgets as widgets
import pandas as pd
import geopandas as gpd
import tempfile
from shapely.geometry import Point
def add_widgets(m):
style = {"description_width": "initial"}
padding = "0px 0px 0px 5px"
checkbox = widgets.Checkbox(
value=True,
description="County",
style=style,
layout=widgets.Layout(width="90px", padding="0px"),
)
split = widgets.Checkbox(
value=False,
description="Split map",
style=style,
layout=widgets.Layout(width="92px", padding=padding),
)
reset = widgets.Checkbox(
value=False,
description="Reset",
style=style,
layout=widgets.Layout(width="75px", padding="0px"),
)
output = widgets.Output()
def checkbox_map(change):
if change.new:
layer = m.find_layer("TN Counties")
layer.visible = True
split.value = False
else:
layer = m.find_layer("TN Counties")
layer.visible = False
checkbox.observe(checkbox_map, names="value")
widgets.jslink((checkbox, "value"), (m.find_layer("TN Counties"), "visible"))
def reset_map(change):
if change.new:
checkbox.value = True
split.value = False
layer = m.find_layer("Selected Image")
if layer is not None:
m.remove(layer)
output.clear_output()
reset.observe(reset_map, names="value")
def change_split(change):
if change.new:
layer = m.find_layer("Selected Image")
if layer is not None:
m.remove(layer)
left_layer = m.url
right_layer = m.find_layer("TDOT Imagery")
layer = m.find_layer("TN Counties")
layer.visible = False
if left_layer is not None:
m.split_map(
left_layer=left_layer,
right_layer=right_layer,
add_close_button=True,
)
else:
checkbox.value = True
# m.update_layer_manager()
split.observe(change_split, names="value")
def handle_click(**kwargs):
if kwargs.get("type") == "click" and (not split.value):
latlon = kwargs.get("coordinates")
geometry = Point(latlon[::-1])
selected = m.gdf[m.gdf.intersects(geometry)]
setattr(m, "zoom_to_layer", False)
if len(selected) > 0:
filename = selected.iloc[0]["Filename"]
county = selected.iloc[0]["County"]
if county != "Knox":
year = filename.split("_")[-1][:4]
with output:
output.clear_output()
output.append_stdout(f"County: {county} | Year: {year}")
url = (
f"https://data.source.coop/giswqs/tn-imagery/imagery/{filename}"
)
layer = m.find_layer("Selected Image")
if layer is not None:
m.remove(layer)
m.default_style = {"cursor": "wait"}
m.add_cog_layer(url, name="Selected Image", zoom_to_layer=False)
m.default_style = {"cursor": "default"}
setattr(m, "url", url)
else:
with output:
output.clear_output()
output.append_stdout("No image found.")
setattr(m, "url", None)
else:
setattr(m, "url", None)
with output:
output.clear_output()
output.append_stdout("No image found.")
# m.update_layer_manager()
m.on_interaction(handle_click)
box = widgets.VBox([widgets.HBox([checkbox, split, reset]), output])
m.add_widget(box, position="topright", add_header=False)
zoom = solara.reactive(8)
center = solara.reactive((35.64836915737426, -86.21246337890626))
class Map(leafmap.Map):
def __init__(self, **kwargs):
kwargs["toolbar_control"] = False
kwargs["draw_control"] = False
super().__init__(**kwargs)
basemap = {
"url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
"attribution": "Google",
"name": "Google Satellite",
}
self.add_tile_layer(**basemap, shown=False)
wms_url = "https://tnmap.tn.gov/arcgis/services/BASEMAPS/IMAGERY_WEB_MERCATOR/MapServer/WMSServer"
self.add_wms_layer(wms_url, layers="0", name="TDOT Imagery", shown=True)
vexcel_url = "https://tnmap.giza.cloud/login/path/cycle-janet-bravo-binary/wms"
self.add_wms_layer(
vexcel_url, layers="vexcel_2023", name="Vexcel 2023", shown=False
)
self.add_wms_layer(
vexcel_url, layers="vexcel_imagery_2021", name="Vexcel 2021", shown=False
)
self.add_wms_layer(
vexcel_url, layers="vdp_us_tennesse", name="Vexcel 2019", shown=False
)
self.add_layer_manager(opened=True)
# add_widgets(self)
geojson = "https://github.com/opengeos/datasets/releases/download/vector/TN_Counties.geojson"
style = {"color": "#3388ff", "opacity": 1, "weight": 2, "fillOpacity": 0}
self.add_geojson(
geojson,
layer_name="TN Counties",
style=style,
zoom_to_layer=False,
info_mode="on_hover",
)
gdf = gpd.read_file(geojson)
setattr(self, "gdf", gdf)
add_widgets(self)
@solara.component
def Page():
with solara.Column(style={"min-width": "500px"}):
# solara components support reactive variables
# solara.SliderInt(label="Zoom level", value=zoom, min=1, max=20)
# using 3rd party widget library require wiring up the events manually
# using zoom.value and zoom.set
Map.element( # type: ignore
zoom=zoom.value,
on_zoom=zoom.set,
center=center.value,
on_center=center.set,
scroll_wheel_zoom=True,
toolbar_ctrl=False,
data_ctrl=False,
height="780px",
)
# solara.Text(f"Center: {center.value}")
# solara.Text(f"Zoom: {zoom.value}")