solara-geospatialDashboard / pages /Servicios_apoyo.py
FranciscoGS's picture
Update pages/Servicios_apoyo.py
4e22767 verified
#Libraries
import solara
from ipyleaflet import Map, GeoJSON, GeoData, LayersControl, Marker, MarkerCluster, basemaps, Choropleth
from branca.colormap import linear
import plotly.express as px
import matplotlib
import geopandas as gpd
import pandas as pd
import numpy as np
from shapely import wkt
import json
import re
#Read Pois Data Set
df = pd.read_csv('./data/pois_final_control.csv')
df = df[(df['EnEstudio'] == True)]
df = df[df['Geometry'].notnull()]
df['geometry'] = df['Geometry'].apply(wkt.loads)
pois = gpd.GeoDataFrame(df, geometry='geometry')
pois = pois.set_crs(epsg=4326, inplace=True)
pois = pois.drop('EnEstudio', axis=1)
pois = pois.drop('Geometry', axis=1)
#Read H3 Data Set
df1 = pd.read_csv('./data/poiscount_r8hex_large.csv', index_col=0)
df1 = df1[df1['Conteo'] > 0]
df1 = df1.drop('EnEstudio', axis=1)
df1['geometry'] = df1['geometry'].apply(wkt.loads)
h3 = gpd.GeoDataFrame(df1, geometry='geometry')
h3 = h3.set_crs(epsg=4326, inplace=True)
#Set controls values
cantones = [str(k) for k in pois['Canton'].unique().tolist()]
categorias = [str(k) for k in pois['Categoria'].unique().tolist()]
canton = solara.reactive('QUITO')
categoria = solara.reactive('salud')
limit = solara.reactive(2500)
#Filter function
def data_filter(df, city, category):
df_filtered = df.loc[df['Canton']==city]
df_filtered = df_filtered[df_filtered['Categoria']==category]
return df_filtered
#Map function
def ipyleaflet_map(geo_df, h3_df, h3_geojson):
# Define map center and initial zoom level
center = (geo_df.geometry.y.mean(), geo_df.geometry.x.mean())
zoom = 11
# Create the map
m = Map(center=center, zoom=zoom)
# Create GeoData from the GeoDataFrame
services = GeoData(
geo_dataframe=geo_df,
style={
'color': 'black',
'radius': 7,
'fillColor': '#3366cc',
'opacity': 0.5,
'weight': 1.9,
'dashArray': '2',
'fillOpacity': 0.6
},
hover_style={
'fillColor': 'red',
'fillOpacity': 0.2
},
point_style={
'radius': 7,
'color': 'red',
'fillOpacity': 0.8,
'fillColor': 'blue',
'weight': 3
},
name='Servicios de Apoyo'
)
#h3 Density
colormap = linear.YlOrRd_04.scale(min(h3_df['Conteo']), max(h3_df['Conteo']))
choro_data = dict(zip(h3_df.index.astype(str), h3_df['Conteo']))
h3_choropleth = Choropleth(
geo_data=h3_geojson,
choro_data=choro_data,
colormap=colormap,
border_color='black',
style={'fillOpacity': 0.8, 'dashArray': '5, 5'},
name='Densidad'
)
# Add GeoData to the map
m.add_layer(services)
m.add_layer(h3_choropleth)
# Add Cluster Markers
markers = [Marker(location=(point.y, point.x)) for point in geo_df.geometry]
# Create and add MarkerCluster to the map
marker_cluster = MarkerCluster(markers=markers, name='Cluster Markers')
m.add_layer(marker_cluster)
# Add layer control
m.add_control(LayersControl())
# Display the map
display(m)
#Interactive bar chart function
def type_chart_plotly(df):
tipo_counts = df['Tipo'].value_counts().sort_values(ascending=True)
fig = px.bar(tipo_counts, orientation='h',
x=tipo_counts.values, y=tipo_counts.index,
labels={'x': 'Conteo', 'y': 'Tipo'},
title='Servicios')
solara.FigurePlotly(fig)
#Main panel layout
@solara.component
def View():
dff = data_filter(pois, canton.value, categoria.value)
h3f = data_filter(h3, canton.value, categoria.value)
geo_json_H3 = json.loads(h3f.to_json())
row_count = len(dff)
if row_count > limit.value:
solara.Warning(f"Only showing the first {limit.value} of {row_count:,} services on map")
ipyleaflet_map(dff.iloc[:limit.value], h3f, geo_json_H3)
if row_count > 0:
with solara.Card(''):
type_chart_plotly(dff)
else:
solara.Warning("You filtered out all the data, no charts shown")
#Controls
@solara.component
def Controls():
solara.Select('Cantón', values=cantones, value=canton)
solara.Select('Categoría', values=categorias, value=categoria)
#solara.SelectMultiple('Fuente', all_values=fuentes, values=fuente)
solara.Text("Maximum number of pois to show on map")
solara.SliderInt('', value=limit, min=1, max=5000)
#Dashboard Layout
@solara.component
def Page():
with solara.Column():
solara.Title('Servicios de Apoyo para Migrantes')
with solara.Sidebar():
with solara.Card('Filtros'):
with solara.Column():
Controls()
View()
Page()