Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import pydeck as pdk | |
from opencage.geocoder import OpenCageGeocode | |
# Replace 'YOUR_API_KEY' with your actual OpenCage API key | |
geocoder = OpenCageGeocode('ac8657fff8634409b4ace821b905ada3') | |
# Daten einlesen | |
file_path = 'Unfallstatistik 2021.csv' | |
data = pd.read_csv(file_path, delimiter=';') | |
# Daten bereinigen | |
data['XGCSWGS84'] = data['XGCSWGS84'].str.replace(',', '.').astype(float) | |
data['YGCSWGS84'] = data['YGCSWGS84'].str.replace(',', '.').astype(float) | |
# Titel der App | |
st.title('Unfallstatistik 2021') | |
# Kartenstil Auswahl | |
map_style_option = st.selectbox( | |
'Wählen Sie den Kartenstil:', | |
('OpenStreetMap', 'Pydeck Light Map', 'Pydeck Dark Map', 'Cesium Standard 3D') | |
) | |
# Entsprechenden map_style bestimmen | |
map_styles = { | |
'OpenStreetMap': 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json', | |
'Pydeck Light Map': 'mapbox://styles/mapbox/light-v10', | |
'Pydeck Dark Map': 'mapbox://styles/mapbox/dark-v10', | |
'Cesium Standard 3D': 'https://assets.agi.com/stk-terrain/world' | |
} | |
map_style = map_styles[map_style_option] | |
# Layer Optionen und Erstellung | |
layer_options = { | |
'Radfahrer': {'column': 'IstRad', 'color': [255, 0, 0]}, | |
'PKW': {'column': 'IstPKW', 'color': [0, 255, 0]}, | |
'Fußgänger': {'column': 'IstFuss', 'color': [0, 0, 255]} | |
} | |
# Erstellen der Layer basierend auf Benutzerauswahl | |
layers = [ | |
pdk.Layer( | |
"ScatterplotLayer", | |
data[data[details['column']] == 1], | |
get_position='[XGCSWGS84, YGCSWGS84]', | |
get_radius=100, | |
get_color=details['color'], | |
pickable=True, | |
tooltip={"text": f"{option} beteiligt"} | |
) for option, details in layer_options.items() if st.checkbox(f'{option} beteiligt', True) | |
] | |
# Kartenansicht konfigurieren | |
view_state = pdk.ViewState(latitude=data['YGCSWGS84'].mean(), longitude=data['XGCSWGS84'].mean(), zoom=11, pitch=0) | |
# Pydeck-Karte anzeigen, falls Layer vorhanden | |
if layers: | |
r = pdk.Deck(layers=layers, initial_view_state=view_state, map_style=map_style) | |
st.pydeck_chart(r) | |
else: | |
st.error("Bitte wählen Sie mindestens eine Unfallbeteiligungsoption.") | |
# Heatmap Layer | |
if st.checkbox('Heatmap anzeigen'): | |
heatmap_layer = pdk.Layer( | |
'HeatmapLayer', | |
data, | |
get_position='[XGCSWGS84, YGCSWGS84]', | |
opacity=0.9, | |
get_weight="1", | |
radius_pixels=30, | |
intensity=1, | |
threshold=0.05, | |
color_range=[(63, 40, 102), (108, 57, 123), (142, 73, 133), (178, 88, 142), (216, 104, 149), | |
(248, 120, 150), (252, 148, 139), (253, 174, 120), (254, 200, 100), (255, 227, 80)] | |
) | |
heatmap = pdk.Deck( | |
layers=[heatmap_layer], | |
initial_view_state=view_state, | |
map_style=map_style | |
) | |
st.subheader("Heatmap der Unfallhäufigkeit") | |
st.pydeck_chart(heatmap) | |
# Datenanzeige | |
if st.checkbox('Daten anzeigen'): | |
st.write("Hier sind die Daten der Unfallstatistik 2021:") | |
st.dataframe(data) | |
# Funktion für Reverse Geocoding mit OpenCage | |
def reverse_geocode(lat, lon): | |
results = geocoder.reverse_geocode(lat, lon) | |
if results and len(results): | |
return results[0]['formatted'] | |
else: | |
return "Unbekannte Straße" | |
# Gruppierung nach Koordinaten und Unfälle zählen | |
st.subheader('Top 5 gefährlichste Orte nach Unfallhäufigkeit') | |
# Unfallhäufigkeit nach Koordinaten ermitteln | |
most_accident_locations = data.groupby(['XGCSWGS84', 'YGCSWGS84']).size().reset_index(name='Unfallanzahl') | |
most_accident_locations = most_accident_locations.nlargest(5, 'Unfallanzahl') | |
# Straßennamen durch Reverse Geocoding ermitteln | |
most_accident_locations['Straßenname'] = most_accident_locations.apply( | |
lambda row: reverse_geocode(row['YGCSWGS84'], row['XGCSWGS84']), axis=1 | |
) | |
# Anzeigen der Liste mit den häufigsten Unfallorten und Straßennamen | |
st.write("Top 5 Unfallorte nach Koordinaten und Anzahl der Unfälle:") | |
st.table(most_accident_locations[['XGCSWGS84', 'YGCSWGS84', 'Unfallanzahl', 'Straßenname']]) | |
# Farblegende | |
st.markdown(""" | |
<style> | |
.dot { | |
height: 15px; | |
width: 15px; | |
border-radius: 50%; | |
display: inline-block; | |
} | |
</style> | |
<h4>Farblegende</h4> | |
<span class="dot" style="background-color: rgb(255, 0, 0);"></span> Radfahrer beteiligt<br> | |
<span class="dot" style="background-color: rgb(0, 255, 0);"></span> PKW beteiligt<br> | |
<span class="dot" style="background-color: rgb(0, 0, 255);"></span> Fußgänger beteiligt | |
""", unsafe_allow_html=True) | |