Skip to article content

Riesgo por olas de calor urbano en Cartagena, Bolívar bajo escenarios de cambio climático

Back to Article
Exports para Observable / D3
Download Notebook

Exports para Observable / D3

Cuaderno suplementario del CRC002. Genera los archivos planos (JSON, GeoJSON) en observable/data/ que alimentan la galería interactiva del proyecto Riesgos.

Prerrequisito: ejecutar article.ipynb en la misma sesión de kernel (o descomentar la celda %run a continuación) para disponer de las variables df_idx, OUT_OBS, SSP_LABELS, delta_field, lst_mean, lst_p90, df_zonal y los parámetros de grilla.

# Descomentar si se ejecuta este cuaderno de forma independiente
# %run ../article.ipynb

1. Exports Fase 1 — Hazard climatológico

Tres archivos planos que el sitio MyST de la scr-ungrd puede consumir sin re-correr el pipeline. Alimentan la galería interactiva del proyecto Riesgos.

# 5.1 Serie temporal plana
ts_export = df_idx.copy()
ts_export['scenario_label'] = ts_export['scenario'].map(SSP_LABELS)
ts_export[['scenario', 'scenario_label', 'year', 'member',
           'HWF', 'HWML', 'TR_nights', 'TX35']]    .to_json(OUT_OBS / 'hazard_timeseries.json', orient='records')

# 5.2 Estadísticas del ensamble (banda + línea)
df_stats_export = df_stats.copy()
df_stats_export['scenario_label'] = df_stats_export['scenario'].map(SSP_LABELS)
df_stats_export.to_json(OUT_OBS / 'hazard_ensemble_stats.json', orient='records')

# 5.3 GeoJSON del cambio espacial
features = []
for i in range(ny):
    for j in range(nx):
        poly = [
            [float(lons[j]-dlon), float(lats[i]-dlat)],
            [float(lons[j]+dlon), float(lats[i]-dlat)],
            [float(lons[j]+dlon), float(lats[i]+dlat)],
            [float(lons[j]-dlon), float(lats[i]+dlat)],
            [float(lons[j]-dlon), float(lats[i]-dlat)],
        ]
        features.append({
            'type': 'Feature',
            'geometry': {'type': 'Polygon', 'coordinates': [poly]},
            'properties': {'delta_hwf': round(float(delta_field[i, j]), 2)},
        })

geojson = {
    'type': 'FeatureCollection',
    'name': 'Δ HWF SSP5-8.5 (2021-2050) vs referencia',
    'metadata': {
        'units': 'events/year',
        'source': 'Pattern scaling sobre GMST CMIP6, ensamble sintético',
        'value_field': 'delta_hwf',
    },
    'features': features,
}
with open(OUT_OBS / 'hazard_delta_hwf.geojson', 'w', encoding='utf-8') as f:
    json.dump(geojson, f, ensure_ascii=False, separators=(',', ':'))

for fname in ('hazard_timeseries.json',
              'hazard_ensemble_stats.json',
              'hazard_delta_hwf.geojson'):
    size = (OUT_OBS / fname).stat().st_size
    print(f"  ✓ {fname:<35s} ({size//1024} KB)")
  ✓ hazard_timeseries.json              (557 KB)
  ✓ hazard_ensemble_stats.json          (32 KB)
  ✓ hazard_delta_hwf.geojson            (35 KB)

2. Exports Fase 2 — Urban Heat Island

Tres archivos planos consumibles desde el sitio MyST o desde dashboards externos.

# 6.7.1 GeoJSON del raster LST media
features_lst = []
for i in range(ny_lst):
    for j in range(nx_lst):
        poly = [
            [float(lons_lst[j]-dlon_lst), float(lats_lst[i]-dlat_lst)],
            [float(lons_lst[j]+dlon_lst), float(lats_lst[i]-dlat_lst)],
            [float(lons_lst[j]+dlon_lst), float(lats_lst[i]+dlat_lst)],
            [float(lons_lst[j]-dlon_lst), float(lats_lst[i]+dlat_lst)],
            [float(lons_lst[j]-dlon_lst), float(lats_lst[i]-dlat_lst)],
        ]
        features_lst.append({
            'type': 'Feature',
            'geometry': {'type': 'Polygon', 'coordinates': [poly]},
            'properties': {
                'lst_mean': round(float(lst_mean[i, j]), 2),
                'lst_p90':  round(float(lst_p90[i, j]), 2),
            },
        })

geo_lst = {
    'type': 'FeatureCollection',
    'name': 'LST media + P90 Cartagena (Modo A sintético)',
    'metadata': {
        'units': '°C',
        'source': 'Synthetic LST calibrated to Caribbean coastal UHI literature',
        'value_fields': ['lst_mean', 'lst_p90'],
    },
    'features': features_lst,
}
with open(OUT_OBS / 'uhi_lst_raster.geojson', 'w', encoding='utf-8') as f:
    json.dump(geo_lst, f, ensure_ascii=False, separators=(',', ':'))

# 6.7.2 JSON plano del resumen zonal
df_zonal.to_json(OUT_OBS / 'uhi_zonal_summary.json', orient='records')

for fname in ('uhi_lst_raster.geojson', 'uhi_zonal_summary.json'):
    size = (OUT_OBS / fname).stat().st_size
    print(f"  ✓ {fname:<35s} ({size//1024} KB)")
  ✓ uhi_lst_raster.geojson              (1096 KB)
  ✓ uhi_zonal_summary.json              (0 KB)