Dr. Alberto García Robledo
CentroGeo Querétaro
Seminario Multidisciplinario CentroGeo
27 de octubre de 2023
Observatorio Metropolitano CentroGeo
Es un colectivo de investigación (CI) formado en 2018 integrado por investigadores de diferentes disciplinas, incluyendo geografía humana, inteligencia artificial y ciencia de los datos.
Observatorio Metropolitano CentroGeo
Observatorio
Metropolitano
CentroGeo
Los miembros del CI somos IxM adscritos a CentroGeo CDMX y Querétaro en el proyecto IxM #154 Observatorio Metropolitano.
Observatorio
Metropolitano
CentroGeo
Realizamos actividades de investigación científica, formación de recursos humanos, desarrollo tecnológico, propuestas de intervención, y actividades de vinculación y difusión del conocimiento sobre aspectos estratégicos del fenómeno metropolitano y urbano.
Observatorio
Metropolitano
CentroGeo
Agua y ciudades
Computación científica en problemas geoespaciales y sociales
Simulación y modelación numérica
Visualización y Big Data Geoespacial
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Un tablero de visualización, es una herramienta visual que permite representar y monitorear de manera centralizada información clave y métricas de rendimiento de una organización o sistema en tiempo real o en periodos definidos.
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Dash provee herramientas para desarrollar componentes que expandan el framework
Básicamente, un componente Dash no es más que un envoltorio de un componente React.js
Dash goza de una nutrida comunidad de desarrolladores que han creado sus propios componentes Dash
Observatorio
Metropolitano
CentroGeo
Sin soporte de dibujo de poli-líneas para los enlaces
Sin soporte de coordenadas geográficas
Sin soporte de mapas web
Sin aceleración por GPU
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Biblioteca Dash desarrollada en CentroGeo.
Permite la visualización de redes de caminos grandes utilizando WebGL.
Las visualizaciones son altamente personalizables.
Eventos de click para nodos y enlaces de la red.
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Dash Sylvereye permite incrustar la visualización de una red de caminos en un tablero Dash
La topología de una red de caminos puede ser obtenida desde OSM a través de la biblioteca OSMnx
Es posible cargar otro tipo de redes geoespaciales
Dash Sylvereye permite la configuración de la capa de mapa web sobre la que se dibuja la red de caminos
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
import osmnx as ox
from dash import Dash
from dash_html_components import Div
from dash_sylvereye import SylvereyeRoadNetwork
from dash_sylvereye.utils import load_from_osmnx_graph
# configuración de la visualización
OSMNX_QUERY = 'Kamppi, Helsinki, Finland'
TILE_LAYER_URL = '//stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png'
TILE_LAYER_SUBDOMAINS = 'abcd'
TILE_LAYER_ATTRIBUTION = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.'
MAP_CENTER = [60.1663, 24.9313]
MAP_ZOOM = 15
MAP_STYLE = {'width': '100%', 'height': '98vh'}
# obtener la topología de la red desde OSM
road_network = ox.graph_from_place(OSMNX_QUERY, network_type='drive')
nodes_data, edges_data = load_from_osmnx_graph(road_network)
# construir visualización
app = Dash()
app.layout = Div([
SylvereyeRoadNetwork(
id='sylvereye-roadnet',
tile_layer_url=TILE_LAYER_URL,
tile_layer_subdomains=TILE_LAYER_SUBDOMAINS,
tile_layer_attribution=TILE_LAYER_ATTRIBUTION,
map_center=MAP_CENTER,
map_zoom=MAP_ZOOM,
map_style=MAP_STYLE,
nodes_data=nodes_data,
edges_data=edges_data
)
])
# correr visualización
if __name__ == '__main__':
app.run_server()
Dash Sylvereye permite interactuar con los nodos (cruces de caminos) y los enlaces (caminos)
Lo anterior a través de la detección de eventos de click
Esto significa que puede asociar un callback al evento click de los nodos y/o enlaces
Dash Sylvereye pasará al callback los datos del elemento clickeado
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
import osmnx as ox
from dash import Dash
from dash.dependencies import Input, Output
from dash_html_components import Div
from dash_html_components import H2, H3
from dash_sylvereye import SylvereyeRoadNetwork
from dash_sylvereye.utils import load_from_osmnx_graph
# configuración de la visualización
OSMNX_QUERY = 'Kamppi, Helsinki, Finland'
TILE_LAYER_URL = '//stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png'
TILE_LAYER_SUBDOMAINS = 'abcd'
TILE_LAYER_ATTRIBUTION = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.'
MAP_CENTER = [60.1663, 24.9313]
MAP_ZOOM = 15
MAP_STYLE = {'width': '100%', 'height': '84vh'}
# obtener la topología de la red desde OSM
road_network = ox.graph_from_place(OSMNX_QUERY, network_type='drive')
nodes_data, edges_data = load_from_osmnx_graph(road_network)
# construcción de la visualización
app = Dash()
app.layout = Div([
SylvereyeRoadNetwork(
id='sylvereye-roadnet',
tile_layer_url=TILE_LAYER_URL,
tile_layer_subdomains=TILE_LAYER_SUBDOMAINS,
tile_layer_attribution=TILE_LAYER_ATTRIBUTION,
map_center=MAP_CENTER,
map_zoom=MAP_ZOOM,
map_style=MAP_STYLE,
nodes_data=nodes_data,
edges_data=edges_data
),
H5("Clicked elements:"),
H6(id='h3-clicked-node-coords'),
H6(id='h3-clicked-edge-coords')
])
# callbacks
@app.callback(
Output('h3-clicked-node-coords', 'children'),
[Input('sylvereye-roadnet', 'clicked_node')])
def update_node_data(clicked_node):
if clicked_node:
return f'Clicked node coords: {clicked_node["data"]["lat"]}, \
{clicked_node["data"]["lon"]}'
@app.callback(
Output('h3-clicked-edge-coords', 'children'),
[Input('sylvereye-roadnet', 'clicked_edge')])
def update_edge_data(clicked_edge):
if clicked_edge:
return f'Clicked edge coords: {clicked_edge["data"]["coords"]}'
# correr visualización
if __name__ == '__main__':
app.run_server()
Dash Sylvereye permite la configuración visual de los nodos y enlaces individuales de la red
Para los nodos es posible configurar su diámetro, color y transparencia
Para los enlaces es posible configurar su grosor, color y transparencia
Dash Sylvereye puede calcular automáticamente el color de nodos y enlaces en función de un atributo de peso
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
import osmnx as ox
import numpy as np
from dash import Dash
from dash_html_components import Div
from dash_sylvereye import SylvereyeRoadNetwork
from dash_sylvereye.utils import load_from_osmnx_graph
from dash_sylvereye.enums import NodeSizeMethod, EdgeColorMethod, EdgeWidthMethod
from dash_sylvereye.defaults import get_default_node_options, get_default_edge_options
OSMNX_QUERY = 'Kamppi, Helsinki, Finland'
TILE_LAYER_URL = '//stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png'
TILE_LAYER_SUBDOMAINS = 'abcd'
TILE_LAYER_ATTRIBUTION = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.'
MAP_CENTER = [60.1663, 24.9313]
MAP_ZOOM = 15
MAP_STYLE = {'width': '100%', 'height': '84vh'}
# obtener la red desde OSM
road_network = ox.graph_from_place(OSMNX_QUERY, network_type='drive')
nodes_data, edges_data = load_from_osmnx_graph(road_network)
# asignar pesos aleatorios a los nodos y enlaces de acuerdo a una dist. libre de escala
for node in nodes_data: node["data"]["weight"] = 1 - np.random.power(a=3, size=None)
for edge in edges_data: edge["data"]["weight"] = 1 - np.random.power(a=3, size=None)
# configurar las opciones visuales de los nodos
node_options = get_default_node_options()
node_options["alpha_default"] = 0.25
node_options["size_method"] = NodeSizeMethod.SCALE
node_options["size_scale_field"] = "weight"
# configurar las opciones visualies de los enlaces
edge_options = get_default_edge_options()
edge_options["width_method"] = EdgeWidthMethod.SCALE
edge_options["width_scale_field"] = "weight"
edge_options["color_method"] = EdgeColorMethod.SCALE
edge_options["color_scale_field"] = "weight"
edge_options["color_scale_left"] = 0xcbdbff
edge_options["color_scale_right"] = 0x06696
# construir la visualización
app = Dash()
app.layout = Div([
SylvereyeRoadNetwork(
id='sylvereye-roadnet',
tile_layer_url=TILE_LAYER_URL,
tile_layer_subdomains=TILE_LAYER_SUBDOMAINS,
tile_layer_attribution=TILE_LAYER_ATTRIBUTION,
map_center=MAP_CENTER,
map_zoom=MAP_ZOOM,
map_style=MAP_STYLE,
nodes_data=nodes_data,
edges_data=edges_data,
node_options=node_options,
edge_options=edge_options
)
])
# correr servidor
if __name__ == '__main__':
app.run_server()
Dash Sylvereye permite visualizar marcadores encima tanto del mapa web como de la red
Los marcadores son interactivos: es posible asociar un callback al evento click de cada marcador
Dash Sylvereye pasará los datos del marcador clickeado a un parámetro del callback
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
import osmnx as ox
from dash import Dash
from dash.dependencies import Input, Output
from dash_html_components import Div
from dash_html_components import H2, H3
from dash_sylvereye import SylvereyeRoadNetwork
from dash_sylvereye.utils import load_from_osmnx_graph, generate_markers_from_coords
from dash_sylvereye.defaults import get_default_marker_options
OSMNX_QUERY = 'Kamppi, Helsinki, Finland'
TILE_LAYER_URL = '//stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png'
TILE_LAYER_SUBDOMAINS = 'abcd'
TILE_LAYER_ATTRIBUTION = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.'
MAP_CENTER = [60.1663, 24.9313]
MAP_ZOOM = 15
MAP_STYLE = {'width': '100%', 'height': '80vh'}
# obtener red de caminos desde OSM
road_network = ox.graph_from_place(OSMNX_QUERY, network_type='drive')
nodes_data, edges_data = load_from_osmnx_graph(road_network)
# crear un marcador por cada nodo de la red
markers_coords = [ [node_data["lat"], node_data["lon"]] for node_data in nodes_data ]
markers_data = generate_markers_from_coords(markers_coords)
# escalar el tamaño de los marcadores al nivel de zoom
marker_options = get_default_marker_options()
marker_options["enable_zoom_scaling"] = True
# construir visualización
app = Dash()
app.layout = Div([
SylvereyeRoadNetwork(
id='sylvereye-roadnet',
tile_layer_url=TILE_LAYER_URL,
tile_layer_subdomains=TILE_LAYER_SUBDOMAINS,
tile_layer_attribution=TILE_LAYER_ATTRIBUTION,
map_center=MAP_CENTER,
map_zoom=MAP_ZOOM,
map_style=MAP_STYLE,
nodes_data=nodes_data,
edges_data=edges_data,
markers_data=markers_data,
marker_options=marker_options
),
H2("Clicked elements:"),
H3(id='h3-clicked-marker-coords')
])
@app.callback(
Output('h3-clicked-marker-coords', 'children'),
[Input('sylvereye-roadnet', 'clicked_marker')])
def update_marker_data(clicked_marker):
if clicked_marker:
marker = clicked_marker["marker"]
return f'Clicked marker coords: {[ marker["lat"], marker["lon"] ]}'
# correr visualización
if __name__ == '__main__':
app.run_server()
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
Urbanismo y Desarrollo Urbano:
Observatorio
Metropolitano
CentroGeo
Transporte Público:
Investigación Académica:
Observatorio
Metropolitano
CentroGeo
Salud Pública:
Seguridad y Emergencia:
Servicios Públicos y Utilities:
Observatorio
Metropolitano
CentroGeo
Observatorio
Metropolitano
CentroGeo
agarcia@centrogeo.edu.mx
Observatorio Metropolitano CentroGeo