Esta página superpone la zonificación de amenaza (3.3.b) con las edificaciones, las vías y los equipamientos críticos del barrio. Como la zonificación es categórica y no da probabilidades, el resultado es exposición por categoría, no una pérdida esperada; es la lógica de la exposición anual esperada de CCDR-tools cuando no hay función de vulnerabilidad Amadio, 2024.
Exposición de edificaciones¶
import geopandas as gpd
import numpy as np
import pandas as pd
from IPython.display import Markdown, display
from sidro import exposicion, process, viz
from sidro.analisis import indices, masa
from sidro.aoi import aoi_bufer
from sidro.config import rutas
from sidro.fetch import obtener_capa
amenaza = intentar(obtener_capa, "amenaza_mov_masa", mensaje="La zonificación de amenaza no está disponible")
edif = intentar(exposicion.edificaciones, mensaje="No se pudo construir la exposición de edificaciones")
if amenaza is not None and len(amenaza):
amenaza = masa.preparar(amenaza) # traduce los códigos numéricos del POT a Baja / Media / Alta
campo = "categoria"
else:
campo = None
listo = edif is not None and campo is not None
if amenaza is not None and campo is None:
display(Markdown(":::{warning}\nLa capa de amenaza no tiene polígonos o un campo de categoría reconocible.\n:::"))if listo:
edif["categoria"] = masa.clasificar(edif, amenaza, campo)
tabla = masa.resumen_exposicion(edif, edif["categoria"], {
"edificaciones": ("id_edif", "count"), "personas": ("ocupantes_est", "sum"),
"valor_millones_cop": ("valor_cop", lambda s: s.sum() / 1e6)})
tabla.loc["Total"] = tabla.sum()
display(tabla.round(0).astype(int))Las personas son residentes estimados: área construida de uso habitacional ÷ 110 m² brutos por residente, calibrados con las viviendas de la UAECD y las personas por hogar del DANE (ver config/parametros.yaml). No incluyen la población flotante de oficinas, comercio o colegios. «Sin categoría»
significa que la edificación no cae en ninguna zona de la capa consultada, no que esté libre de amenaza.
if listo:
m = viz.mapa_base()
viz.capa(m, amenaza, campo, nombre="Amenaza", categorica=True, cmap="RdYlGn_r")
viz.capa(m, edif, "categoria", nombre="Edificaciones", categorica=True, cmap="RdYlGn_r",
tooltip=["categoria", "pisos", "anio", "uso"])
viz.cerrar(m)
else:
m = None
mVías y equipamientos críticos¶
vias = intentar(obtener_capa, "red_vial", mensaje="No se pudo obtener la red vial de OpenStreetMap")
equip = intentar(obtener_capa, "equipamientos_criticos", mensaje="No se pudo obtener los equipamientos críticos")if listo and vias is not None and len(vias):
vias_aoi = gpd.clip(vias, aoi_bufer().geometry.iloc[0])
km = masa.longitud_por_categoria(vias_aoi, amenaza, campo)
display(km.round(2).rename("km de vía").to_frame())
if listo and equip is not None and len(equip):
equip = equip.copy()
equip["categoria"] = masa.clasificar(equip, amenaza, campo)
cols = [c for c in ("name", "amenity", "categoria") if c in equip.columns]
display(equip[equip.categoria.isin(masa.orden_tabla()[:2])][cols].reset_index(drop=True))La tabla de equipamientos lista solo los que están en amenaza alta o media. Los equipamientos de OpenStreetMap están lejos de ser un inventario completo; úselos como una primera aproximación y contraste con el registro de IDIGER o la Secretaría de Educación y Salud.
Agregación por unidad de análisis¶
La medida de riesgo por unidad son las personas estimadas en amenaza alta; la amenaza media se informa como columna aparte.
if listo:
orden = masa.orden_tabla()
edif["personas_alta"] = edif["ocupantes_est"].where(edif["categoria"] == orden[0], 0.0)
edif["personas_media"] = edif["ocupantes_est"].where(edif["categoria"] == orden[1], 0.0)
edif["edif_alta"] = (edif["categoria"] == orden[0]).astype(int)
unidades = process.unidades_analisis()
agg = process.agregar(edif, unidades, {
"n_edificaciones": ("id_edif", "count"), "edificaciones_alta": ("edif_alta", "sum"),
"personas_alta": ("personas_alta", "sum"), "personas_media": ("personas_media", "sum")})
agg["vulnerabilidad_social"] = indices.vulnerabilidad_social(agg)
print(f"Unidades: {len(agg)} (origen: {unidades.attrs.get('origen')})")
display(agg.drop(columns="geometry").sort_values("personas_alta", ascending=False).head(10).round(1))WARNING sidro.fetch: manzanas_censo: falló nivel nacional/usuario -> Archivo de usuario no encontrado: /Users/mauricio/Documents/Data-science-local/SIDRo/data/user/dane_mgn_manzanas_cnpv2018.gpkg
WARNING sidro.process: Unidades: manzanas_censo no disponible (No se pudo obtener 'manzanas_censo'. Intentos: [{'nivel': 'nacional', 'tipo': 'usuario', 'error': 'Archivo de usuario no encontrado: /Users/mauricio/Documents/Data-science-local/SIDRo/data/user/dane_mgn_manzanas_cnpv2018.gpkg'}])
Unidades: 57 (origen: estratificacion)
Riesgo × vulnerabilidad social¶
if listo:
biv = indices.bivariado(agg["personas_alta"].fillna(0), agg["vulnerabilidad_social"])
agg = agg.join(biv)
m = viz.mapa_base()
viz.capa_bivariada(m, agg)
viz.cerrar(m)
else:
m = None
mLeyenda: exposición a movimientos en masa en el eje vertical, vulnerabilidad social en el horizontal.
Si casi todas las unidades tienen cero personas en amenaza alta, los terciles se calculan sobre muchos empates y el mapa se vuelve poco informativo; en ese caso use el indicador de amenaza media o la lectura directa de la tabla anterior.
Exportación¶
if listo:
process.guardar(agg[["id_unidad", "geometry", "personas_alta", "edificaciones_alta", "personas_media",
"vulnerabilidad_social"]].rename(columns={"personas_alta": "riesgo"}), "riesgo_mov_masa")
print("Guardado:", (rutas().processed / "riesgo_mov_masa.parquet").relative_to(rutas().raiz))Guardado: data/processed/riesgo_mov_masa.parquet
riesgo_mov_masa.parquet queda en data/processed/ con id_unidad y la columna riesgo (personas
estimadas en amenaza alta) para la síntesis 3.6.
- Amadio, M. (2024). CCDR tools data and methodology. Global Facility for Disaster Reduction and Recovery (GFDRR), World Bank. https://gfdrr.github.io/CCDR-tools