Currently my code looks like this:
import dash
from dash import Output, Input, State, html, no_update
import dash_leaflet as dl
import osmnx as ox
import json
from numpy import dtype
# Style-Funktion für GeoJSON-Features
def get_style(feature):
return {
"color": "rgba(0,0,0,0)", # Transparent
"weight": 5,
"opacity": 1,
"fillOpacity": 0
}
# create a style for the GeoJSON features where the color is dependent on the "use" attribute
def get_style_with_use(feature):
if feature['properties']['use'] == True:
return {
"color": "rgba(0,0,0,0)",
"weight": 2,
"opacity": 0.7,
"fillOpacity": 0
}
else:
return {
"color": "green",
"weight": 5,
"opacity": 0.9,
"fillOpacity": 0
}
# Hover-Style (blau)
hover_style = {
"color": "blue",
"weight": 7,
"opacity": 1,
"fillOpacity": 0.5
}
# GeoJSON with Dresdner streets
G = ox.load_graphml("dresden_saxony_germanyroad_network.graphml")
# add a attribute to the edges called "use" and set it to "TRUE"
for u, v, key, data in G.edges(keys=True, data=True):
data['use'] = True
geojson_data = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=True).to_json()
data = json.loads(geojson_data)
meta = data['features']
mapping = {}
for i in range(len(meta)):
mapping[meta[i]['id']] = i
# print the Name of the Street on the Dash App as text below the map
# Dash-App mit Leaflet-Karte
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1("Dresden Streets Map"),
dl.Map([
dl.TileLayer(),
dl.GeoJSON(
data=data,
id="geojson-dresden-streets",
style={
"color": "rgba(0,0,0,0)",
"weight": 5,
"opacity": 1,
"fillOpacity": 0
},
hoverStyle=hover_style
)
], style={'width': '1000px', 'height': '500px'}, center=[51.0504, 13.7373], zoom=12),
html.Div(id='container-output-text',
children='Enter a value and press submit')
])
@app.callback(
Output('container-output-text', 'children'),
Input('geojson-dresden-streets', 'n_clicks'),
State('geojson-dresden-streets', 'clickData'),
prevent_initial_call=True
)
def f1(input_, state_):
print(json.dumps(input_))
print(json.dumps(state_))
# id = mapping.get(str(state_['id']))
# print(state_['id'])
# print(id)
# # print datatype of data['features']
# print(type(data['features']))
# print(data['features'][id])
# data['features'][id]['properties']['use'] = False
print()
if __name__ == "__main__":
app.run(debug=True)
What I want to do:
What I tried for 'Clicking on a street':
True
to False
or vise verseI have tried a lot, but I have no idea how to get it to work...
Using Highlight a selected feature from the Geojson Tutorial page as a reference, it looks like you can use a hideout
property to store state, and then use style_handle = assign"""function(feature, context){...}"""
for the javascript rendering logic to color a selection depending on its state.
Below is a fully reproducible example (note that I defined G using a downloadable graph of Dresden, Saxony instead of your file):
import dash
from dash import Output, Input, State, html, no_update
from dash_extensions.javascript import assign
import dash_leaflet as dl
import osmnx as ox
import json
from numpy import dtype
# Style-Funktion für GeoJSON-Features
def get_style(feature):
return {
"color": "rgba(0,0,0,0)", # Transparent
"weight": 5,
"opacity": 1,
"fillOpacity": 0
}
# create a style for the GeoJSON features where the color is dependent on the "use" attribute
def get_style_with_use(feature):
if feature['properties']['use'] == True:
return {
"color": "rgba(0,0,0,0)",
"weight": 2,
"opacity": 0.7,
"fillOpacity": 0
}
else:
return {
"color": "green",
"weight": 5,
"opacity": 0.9,
"fillOpacity": 0
}
# Hover-Style (blau)
hover_style = {
"color": "blue",
"weight": 7,
"opacity": 1,
"fillOpacity": 0.5
}
# GeoJSON with Dresdner streets
# G = ox.load_graphml("dresden_saxony_germanyroad_network.graphml")
## to reproduce the graph G
G = ox.graph_from_place("Dresden, Saxony, Germany", network_type="drive")
# add a attribute to the edges called "use" and set it to "TRUE"
for u, v, key, data in G.edges(keys=True, data=True):
data['use'] = True
geojson_data = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=True).to_json()
data = json.loads(geojson_data)
meta = data['features']
mapping = {}
for i in range(len(meta)):
mapping[meta[i]['id']] = i
# print the Name of the Street on the Dash App as text below the map
# Dash-App mit Leaflet-Karte
app = dash.Dash(__name__)
style_handle = assign("""function(feature, context){
const {selected} = context.hideout;
if (selected.includes(feature.id)) {
return {color: 'red', weight: 5, opacity: 1};
}
return {color: 'rgba(0,0,0,0)', weight: 5, opacity: 1, fillOpacity: 0};
}""")
app.layout = html.Div([
html.H1("Dresden Streets Map"),
dl.Map([
dl.TileLayer(),
dl.GeoJSON(
data=data,
id="geojson-dresden-streets",
hoverStyle=hover_style,
hideout=dict(selected=[]),
style=style_handle,
)
], style={'width': '1000px', 'height': '500px'}, center=[51.0504, 13.7373], zoom=12),
html.Div(id='container-output-text',
children='Enter a value and press submit')
])
@app.callback(
Output("geojson-dresden-streets", "hideout"),
Input("geojson-dresden-streets", "n_clicks"),
State("geojson-dresden-streets", "clickData"),
State("geojson-dresden-streets", "hideout"),
prevent_initial_call=True,
)
def f1(_, feature, hideout):
selected = hideout["selected"]
feature_id = feature["id"]
if feature_id in selected:
selected.remove(feature_id)
else:
selected.append(feature_id)
return hideout
if __name__ == "__main__":
app.run(debug=True)