Skip to content

Commit

Permalink
Returning selected layers (#225)
Browse files Browse the repository at this point in the history
* Add return values for selected layers in LayersControl

* Remove comment; Added Example and returning Url + Layer instead of just Layer because some provider use the same Layer but different Urls.

* added improvements and reformated

* (re)added on click and on mouseover to layer.
  • Loading branch information
reyemb authored Sep 30, 2024
1 parent d07a248 commit 6382e45
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 1 deletion.
90 changes: 90 additions & 0 deletions examples/pages/layer_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import folium
import streamlit as st
from folium.plugins import Draw
from folium.raster_layers import WmsTileLayer

from streamlit_folium import st_folium

# Set page configurations
st.set_page_config(
page_title="streamlit-folium documentation: LayerControl",
)

# WMTS layers dictionary
LAYER_WMTS: dict[str, dict] = {
"KATASTER-Farbig": {
"wmts_url": "https://geodienste.ch/db/avc_0/deu",
"layer_name": "daten",
"legend_url": None,
},
"SWISS-IMAGE": {
"wmts_url": "https://wms.geo.admin.ch/",
"layer_name": "ch.swisstopo.swissimage",
"legend_url": None,
},
"Solarenergie: Eignung Dächer": {
"wmts_url": "https://wms.geo.admin.ch/",
"layer_name": "ch.bfe.solarenergie-eignung-daecher",
"legend_url": "https://api3.geo.admin.ch/static/images/legends/ch.bfe.solarenergie-eignung-daecher_de.png",
},
"Solarenergie: Eignung Fassaden": {
"wmts_url": "https://wms.geo.admin.ch/g",
"layer_name": "ch.bfe.solarenergie-eignung-fassaden",
"legend_url": "https://api3.geo.admin.ch/static/images/legends/ch.bfe.solarenergie-eignung-fassaden_de.png",
},
"Solare Einstrahlung horizontal": {
"wmts_url": "https://wms.geo.admin.ch/",
"layer_name": "ch.bfe.solarenergie-einstrahlung_0_grad",
"legend_url": "https://api3.geo.admin.ch/static/images/legends/ch.bfe.solarenergie-einstrahlung_0_grad_de.png",
},
"Solare Einstrahlung 30° Neigung Süd": {
"wmts_url": "https://wms.geo.admin.ch/",
"layer_name": "ch.bfe.solarenergie-einstrahlung_30_grad",
"legend_url": "https://api3.geo.admin.ch/static/images/legends/ch.bfe.solarenergie-einstrahlung_30_grad_de.png",
},
"Solare Einstrahlung 75° Neigung Süd": {
"wmts_url": "https://wms.geo.admin.ch/",
"layer_name": "ch.bfe.solarenergie-einstrahlung_75_grad",
"legend_url": "https://api3.geo.admin.ch/static/images/legends/ch.bfe.solarenergie-einstrahlung_75_grad_de.png",
},
"Solare Einstrahlung 90° Neigung Süd": {
"wmts_url": "https://wms.geo.admin.ch/",
"layer_name": "ch.bfe.solarenergie-einstrahlung_90_grad",
"legend_url": "https://api3.geo.admin.ch/static/images/legends/ch.bfe.solarenergie-einstrahlung_90_grad_de.png",
},
}

m = folium.Map(location=[47.377512, 8.540670], zoom_start=15, max_zoom=20)

selected_layers = LAYER_WMTS

for i, layer in enumerate(selected_layers):
layer_info = LAYER_WMTS[layer]

st.write("Layer Info:", layer_info)

if layer_info.get("wmts_url") and layer_info.get("layer_name"):
try:
WmsTileLayer(
url=layer_info["wmts_url"],
layers=layer_info["layer_name"],
name=layer,
fmt="image/png",
transparent=True,
overlay=True,
control=True,
version="1.3.0",
show=i == 0,
max_zoom=20,
).add_to(m)
except Exception as e:
st.error(f"Error adding layer {layer}: {e}")
else:
st.warning(f"Missing URL or layer for {layer}")

Draw(export=True).add_to(m)

folium.LayerControl(position="topright").add_to(m)

data = st_folium(m)
st.write(data)
2 changes: 2 additions & 0 deletions streamlit_folium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# the component, and True when we're ready to package and distribute it.
_RELEASE = True


if not _RELEASE:
_component_func = components.declare_component(
"st_folium", url="http://localhost:3001"
Expand Down Expand Up @@ -326,6 +327,7 @@ def bounds_to_dict(bounds_list: list[list[float]]) -> dict[str, dict[str, float]
else {},
"last_circle_radius": None,
"last_circle_polygon": None,
"selected_layers": None,
}

# If the user passes a custom list of returned objects, we'll only return those
Expand Down
56 changes: 55 additions & 1 deletion streamlit_folium/frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type GlobalData = {
last_center: any
last_feature_group: any
last_layer_control: any
selected_layers: Record<string, { name: string; url: string }>
}

declare global {
Expand Down Expand Up @@ -57,6 +58,7 @@ function updateComponentValue(map: any) {
last_circle_radius: global_data.last_circle_radius,
last_circle_polygon: global_data.last_circle_polygon,
center: map.getCenter(),
selected_layers: Object.values(global_data.selected_layers)
}

let to_return = global_data.returned_objects
Expand Down Expand Up @@ -111,6 +113,43 @@ function onDraw(e: any) {
return onLayerClick(e)
}

function removeLayer(e: any) {
const global_data = window.__GLOBAL_DATA__
let layer = e.layer

if (layer && layer["_url"] && layer["wmsParams"] && layer["wmsParams"]["layers"]) {
const layerName = layer["wmsParams"]["layers"];
const layerUrl = layer["_url"];

const layerKey = `${layerUrl},${layerName}`;

// Remove the layer object if it exists
if (global_data.selected_layers[layerKey]) {
delete global_data.selected_layers[layerKey];
}
}

debouncedUpdateComponentValue(window.map)
}

function addLayer(e: any) {
const global_data = window.__GLOBAL_DATA__
let layer = e.layer

if (layer && layer["_url"] && layer["wmsParams"] && layer["wmsParams"]["layers"]) {
const layerName = layer["wmsParams"]["layers"];
const layerUrl = layer["_url"];

const layerKey = `${layerUrl},${layerName}`;

if (!global_data.selected_layers[layerKey]) {
global_data.selected_layers[layerKey] = { name: layerName, url: layerUrl };
}
}

debouncedUpdateComponentValue(window.map)
}

function onLayerClick(e: any) {
const global_data = window.__GLOBAL_DATA__
global_data.last_object_clicked = e.latlng
Expand Down Expand Up @@ -167,10 +206,21 @@ function getPixelatedStyles(pixelated: boolean) {
}

window.initComponent = (map: any, return_on_hover: boolean) => {
const global_data = window.__GLOBAL_DATA__
map.on("click", onMapClick)
map.on("moveend", onMapMove)
for (let key in map._layers) {
let layer = map._layers[key]
if (layer && layer["_url"] && layer["wmsParams"] && layer["wmsParams"]["layers"]) {
const layerName = layer["wmsParams"]["layers"];
const layerUrl = layer["_url"];

const layerKey = `${layerUrl},${layerName}`;

if (!global_data.selected_layers[layerKey]) {
global_data.selected_layers[layerKey] = { name: layerName, url: layerUrl };
}
}
layer.on("click", onLayerClick)
if (return_on_hover) {
layer.on("mouseover", onLayerClick)
Expand All @@ -180,6 +230,10 @@ window.initComponent = (map: any, return_on_hover: boolean) => {
map.on("draw:edited", onDraw)
map.on("draw:deleted", onDraw)

// Adding functionality for tracking layer changes
map.on("overlayadd", addLayer);
map.on("overlayremove", removeLayer);

Streamlit.setFrameHeight()
updateComponentValue(map)
}
Expand Down Expand Up @@ -228,7 +282,6 @@ async function onRender(event: Event) {
linkTag.href = link
window.document.head.appendChild(linkTag)
})

const style = document.createElement("style")
style.innerHTML = getPixelatedStyles(pixelated)
window.document.head.appendChild(style)
Expand Down Expand Up @@ -339,6 +392,7 @@ async function onRender(event: Event) {
last_center: null,
last_feature_group: null,
last_layer_control: null,
selected_layers: {}
}
if (script.indexOf("map_div2") !== -1) {
parent_div?.classList.remove("single")
Expand Down

0 comments on commit 6382e45

Please sign in to comment.