Abrir en Colab

Introducción al mapeo de riesgos#

Combinaremos distintos factores para crear mapas sencillos de posibles zonas de riesgo.

import folium
import ee
import geemap
import geopandas as gpd

ee.Authenticate()

# Escribe aquí el ID de tu proyecto, entre comillas
ee.Initialize(project="emerge-lessons")
def add_ee_layer(self, ee_image_object, vis_params, name):
    """
    Agrega a un mapa de Folium una capa de teselas
    procedente de una imagen de Earth Engine.
    """
    map_id_dict = ee.Image(
        ee_image_object
    ).getMapId(vis_params)

    folium.raster_layers.TileLayer(
        tiles=map_id_dict["tile_fetcher"].url_format,
        attr=(
            'Map Data © '
            '<a href="https://earthengine.google.com/">'
            "Google Earth Engine</a>"
        ),
        name=name,
        overlay=True,
        control=True
    ).add_to(self)


folium.Map.add_ee_layer = add_ee_layer
start_date = "2025-06-01"
end_date = "2025-06-30" 
def mask_s2_clouds(image):
    """
    Oculta las nubes de una imagen Sentinel-2 mediante la banda QA.

    Parámetros:
        image (ee.Image): imagen de Sentinel-2.

    Devuelve:
        ee.Image: imagen de Sentinel-2 con las nubes ocultas.
    """
    qa = image.select("QA60")

    # Los bits 10 y 11 representan nubes y cirros, respectivamente
    cloud_bit_mask = 1 << 10
    cirrus_bit_mask = 1 << 11

    # Ambos indicadores deben ser cero para representar condiciones despejadas
    mask = (
        qa.bitwiseAnd(cloud_bit_mask)
        .eq(0)
        .And(
            qa.bitwiseAnd(cirrus_bit_mask).eq(0)
        )
    )

    return image.updateMask(mask).divide(10000)

Define la región de interés en el centro de Florida.

point = ee.Geometry.Point(
    -81.660044,
    28.473813
)

region = point.buffer(
    distance=100000
)

Carga los datos de Google Earth Engine de manera similar a la lección 1 de este capítulo.

lst = (
    ee.ImageCollection("MODIS/061/MOD11A1")
    .filterBounds(region)
    .filterDate(start_date, end_date)
    .select("LST_Day_1km")
    .median()
    .clip(region)
)

rgb = (
    ee.ImageCollection(
        "COPERNICUS/S2_SR_HARMONIZED"
    )
    .filterBounds(region)
    .filterDate(start_date, end_date)
    .map(mask_s2_clouds)
    .median()
    .clip(region)
)

ndvi = rgb.normalizedDifference(
    ["B8", "B4"]
).rename("NDVI")

rain = (
    ee.ImageCollection(
        "UCSB-CHG/CHIRPS/DAILY"
    )
    .filterBounds(region)
    .filterDate(start_date, end_date)
    .select("precipitation")
    .sum()
    .clip(region)
)

Visualiza los datos en un mapa. Utiliza el control de la esquina superior derecha para elegir la capa que deseas mostrar.

map = folium.Map(
    location=[28.263363, -83.497652],
    tiles="Cartodb dark_matter",
    zoom_start=7
)

lst_vis = {
    "min": 13000.0,
    "max": 16500.0,
    "palette": [
        "040274", "040281", "0502a3", "0502b8", "0502ce", "0502e6",
        "0602ff", "235cb1", "307ef3", "269db1", "30c8e2", "32d3ef",
        "3be285", "3ff38f", "86e26f", "3ae237", "b5e22e", "d6e21f",
        "fff705", "ffd611", "ffb613", "ff8b13", "ff6e08", "ff500d",
        "ff0000", "de0101", "c21301", "a71001", "911003"
    ]
}

map.add_ee_layer(
    lst,
    lst_vis,
    "Temperatura de la superficie terrestre"
)

map.add_ee_layer(
    ndvi,
    {
        "min": -1,
        "max": 1,
        "palette": ["blue", "white", "green"]
    },
    "NDVI"
)

map.add_ee_layer(
    rain,
    {
        "min": 0,
        "max": 200,
        "palette": ["white", "blue"]
    },
    "Precipitación"
)

folium.LayerControl(
    collapsed=False
).add_to(map)

display(map)

Combina las capas en una sola imagen.

# Definir una proyección común basada en Sentinel-2
s2_proj = (
    ee.ImageCollection(
        "COPERNICUS/S2_SR_HARMONIZED"
    )
    .first()
    .select("B1")
    .projection()
)

# Remuestrear la temperatura y la precipitación
# para utilizar la proyección de Sentinel-2
lst_resampled = (
    lst.resample("bilinear")
    .reproject(crs=s2_proj)
)

rain_resampled = (
    rain.resample("bilinear")
    .reproject(crs=s2_proj)
)

# Combinar las capas en una sola imagen
combined = (
    ndvi
    .addBands(lst_resampled)
    .addBands(rain_resampled)
)
# Calcular los valores promedio de la región
mean_lst = (
    lst.reduceRegion(
        reducer=ee.Reducer.mean(),
        geometry=region,
        scale=1000,
        maxPixels=1e12
    )
    .get("LST_Day_1km")
    .getInfo()
)

mean_rain = (
    rain.reduceRegion(
        reducer=ee.Reducer.mean(),
        geometry=region,
        scale=5566,
        maxPixels=1e12
    )
    .get("precipitation")
    .getInfo()
)


def classify_risk(image):
    """
    Clasifica cada píxel como riesgo bajo, medio o alto
    a partir del NDVI, la temperatura y la precipitación.
    """
    ndvi_band = image.select("NDVI")
    lst_band = image.select("LST_Day_1km")
    rain_band = image.select("precipitation")

    low_risk = (
        ndvi_band.lt(0)
        .And(lst_band.lt(mean_lst))
        .And(rain_band.lt(mean_rain))
    )

    high_risk = (
        ndvi_band.gt(0.3)
        .And(lst_band.gt(mean_lst))
        .And(rain_band.gt(mean_rain))
    )

    # Asignar valores mutuamente excluyentes:
    # 1 = bajo, 2 = medio, 3 = alto
    risk = (
        ee.Image.constant(2)
        .where(low_risk, 1)
        .where(high_risk, 3)
        .rename("Risk_Level")
    )

    return image.addBands(risk)


# Aplicar la clasificación
classified = classify_risk(combined)
# Crear un mapa nuevo
map = folium.Map(
    location=[28.263363, -83.497652],
    tiles="Cartodb dark_matter",
    zoom_start=7
)

# Agregar la capa de riesgo
map.add_ee_layer(
    classified.select("Risk_Level"),
    {
        "min": 1,
        "max": 3,
        "palette": ["green", "yellow", "red"]
    },
    "Nivel de riesgo"
)

display(map)

Este es un mapa muy sencillo que clasifica el riesgo potencial como bajo, medio o alto a partir de tres variables: NDVI, temperatura de la superficie terrestre y precipitación.

Esta clasificación es solamente un ejemplo educativo. No constituye un modelo validado de riesgo de mosquitos ni debe utilizarse para tomar decisiones de salud pública. Investigaciones anteriores han identificado muchas otras variables relacionadas con los mosquitos, y cualquier análisis de riesgo debe considerar las condiciones ambientales y sociales específicas de cada lugar.