Content from Fundamentos de teledetección


Última actualización: 2025-08-19 | Mejora esta página

Tiempo estimado: 41 minutos

Hoja de ruta

Preguntas

  • ¿Qué es la teledetección y cómo se diferencia de otros métodos de observación?
  • ¿Qué es la radiación electromagnética y por qué es clave en la teledetección?
  • ¿Qué es una imagen satelital y cómo se interpretan sus componentes?

Objetivos

  • Definir qué es la teledetección y explicar su relevancia para el estudio ambiental.
  • Comprender el rol de la radiación electromagnética y el espectro electromagnético en la obtención de datos satelitales.
  • Identificar los componentes básicos de una imagen satelital y cómo se estructuran los datos en píxeles y bandas.

¿Qué es la teledetección?


La teledetección es el proceso mediante el cual se obtiene información sobre un objeto, una superficie o un fenómeno sin necesidad de estar en contacto directo con él. En el contexto del análisis ambiental, esto se logra a través del uso de sensores montados en plataformas como satélites, drones o aviones, que capturan datos sobre la Tierra desde una distancia considerable.

A diferencia de otros métodos de observación directa, la teledetección permite recopilar datos de forma remota, frecuente y sistemática, lo cual la convierte en una herramienta fundamental para estudiar el planeta en diferentes escalas espaciales y temporales. Esto es especialmente valioso en regiones de difícil acceso o para observar procesos que ocurren a gran escala, como la deforestación o las inundaciones.

¿Qué es la radiación electromagnética y por qué es clave?


La radiación electromagnética (REM) es el medio fundamental a través del cual los sensores remotos obtienen información del entorno. Esta radiación consiste en la propagación de campos eléctricos y magnéticos que transportan energía a través del espacio.

Todos los objetos cuya temperatura está por encima del cero absoluto emiten radiación electromagnética en mayor o menor medida. Esta energía puede ser reflejada, absorbida o emitida por la superficie terrestre, y los sensores de teledetección registran esas variaciones.

La REM se organiza en lo que se conoce como el espectro electromagnético, que abarca desde ondas de radio de baja frecuencia hasta rayos gamma de alta energía.

Los satélites llevan instrumentos o sensores que miden la radiación electromagnética reflejada o emitida por fuentes tanto terrestres como atmosféricas. Con instrumentos calibrados, los científicos pueden medir la altura, la temperatura, el contenido de humedad (y más) para casi todos los atributos de la atmósfera, hidrosfera, litosfera y la biosfera de la Tierra. Sin embargo, los sensores remotos capturan solo ciertas regiones del espectro (por ejemplo, el visible, el infrarrojo y las microondas), dependiendo del tipo de aplicación.

Comprender cómo interactúa la REM con distintos tipos de superficies —agua, vegetación, suelo, construcciones— es esencial para poder interpretar correctamente las imágenes y datos satelitales.

¿Qué es una imagen satelital?


Una imagen satelital es una representación digital de una porción de la superficie terrestre, generada a partir de la información registrada por sensores remotos.

Estos sensores capturan datos en ciertas longitudes de onda del espectro electromagnético (EEM). Por eso, cada imagen corresponde a una banda espectral, y cada píxel de la imagen contiene un valor numérico que representa la intensidad de la energía reflejada por una unidad mínima de superficie en esa banda específica.

Los datos se organizan en una matriz bidimensional de filas × columnas, donde cada celda representa un píxel. Ese valor de píxel indica la reflectancia promedio registrada por el sensor en esa porción del terreno.

Cuando se visualiza una imagen de una sola banda, esta suele representarse en escala de grises:

  • Blanco: indica alta reflectancia (mayor energía reflejada).
  • Negro: indica baja reflectancia (menor energía reflejada).

Este gradiente continuo permite distinguir diferencias en la respuesta espectral de los distintos objetos o superficies.

Tipos de imágenes satelitales

Dependiendo de cuántas bandas espectrales se capturan y cómo se combinan, las imágenes pueden clasificarse en:

  • Monoespectral: contiene datos de una sola banda (por ejemplo, solo la banda del rojo). Se visualiza generalmente en escala de grises.
  • Multiespectral: combina varias bandas (habitualmente entre 3 y 10), como las del espectro visible (rojo, verde, azul) y el infrarrojo cercano. Permiten generar composiciones de color para distintos análisis (por ejemplo, vegetación, agua, suelo desnudo).
  • Hiperespectral: contiene decenas o cientos de bandas muy estrechas del espectro, lo que permite una mayor precisión en la identificación de materiales, tipos de cobertura o condiciones ambientales.
Imagen multiespectral
Imagen multiespectral

🛰️ Satélites y sensores


Los satélites transportan a bordo sensores remotos, que son los instrumentos encargados de captar la energía electromagnética reflejada o emitida por la superficie terrestre. Al conjunto de sensores más la plataforma satelital que los contiene se lo denomina sistema satelital.

Actualmente, se estima que hay alrededor de 12.000 satélites activos orbitando nuestro planeta (Jonathan’s Space Pages, 2025), muchos de ellos utilizados para observación de la Tierra.

Sensores remotos


Los sensores pueden estar montados en diferentes plataformas, como satélites, drones, aviones o globos. Según el tipo de energía que utilizan, se clasifican en:

  • Sensores pasivos: miden la energía radiante natural reflejada o emitida por la Tierra. Por ejemplo, los sensores ópticos que utilizan la luz solar como fuente.
  • Sensores activos: emiten su propia señal (como radar o láser) y miden el rebote de esa señal. Funcionan incluso de noche o con nubosidad. Ejemplos: Sentinel-1 (radar), GPM GMI (microondas), Landsat OLI/TIRS (infrarrojo térmico).
Sensores pasivos y activos
Sensores pasivos y activos

Tipos de plataformas

Según el tipo de órbita o el medio en que se transportan, las plataformas pueden ser:

  • Satélites de órbita polar o heliosincrónica: observan toda la superficie terrestre en franjas, pasando por cada punto a la misma hora solar local.
    Ejemplos: Landsat, Sentinel-2, MODIS.
  • Satélites geoestacionarios (geosincrónicos): se ubican a unos 36.000 km de altura y permanecen sobre el mismo punto del planeta. Son ideales para monitoreo meteorológico en tiempo real.
  • Drones y aviones: operan a escala local y permiten obtener imágenes de alta resolución espacial, útiles para estudios detallados.

¿Qué mide un sensor remoto?

Cada sensor capta la energía reflejada en determinadas longitudes de onda del espectro electromagnético, organizando los datos en forma de matriz de píxeles (filas × columnas). Cada píxel representa una unidad mínima de superficie (por ejemplo, 10 × 10 m) y contiene un valor numérico que indica la reflectancia promedio en una determinada banda espectral.

Características técnicas: resoluciones

Las imágenes satelitales presentan diferentes resoluciones, que determinan su nivel de detalle y periodicidad. Estas dependen en parte del sensor, del satélite o de ambos:

Tipo de resolución Qué mide Ejemplo
Espacial Tamaño del píxel en el terreno 10 m (Sentinel-2), 30 m (Landsat-8)
Temporal Frecuencia de observación de la misma zona Cada 5 días (Sentinel-2)
Espectral Número y ancho de las bandas espectrales captadas 13 bandas (Sentinel-2)
Radiométrica Capacidad para discriminar diferencias de intensidad 8 bits (256 niveles) o más

Ancho de barrido y resolución espacial

  • Ancho de la franja de barrido: es el ancho máximo de la superficie observada por el sensor. Depende del ángulo de observación.
  • Resolución espacial: es el tamaño de cada píxel. Determina el nivel de detalle.
Ancho del barrido y resolución espacial
Ancho del barrido y resolución espacial

Estas características están inversamente relacionadas: cuanto mayor la resolución espacial (píxeles más pequeños), menor el ancho de barrido (área cubierta en una pasada).

📌 Ejemplo: Sentinel-2 tiene una resolución espacial de 10 m y cubre un ancho de barrido de 290 km. SAOCOM, en cambio, tiene resolución de hasta 10 m pero menor cobertura por pasada.

Desafío

Ejercicio 1 - Responde a la encuesta

Q: ¿Qué es una imagen satelital?

  1. Una fotografía convencional tomada desde el espacio.
  2. Una matriz de colores RGB que representa la temperatura de la atmósfera.
  3. Una matriz de valores numéricos que representan la energía reflejada por cada unidad de superficie.
  1. Una matriz de valores numéricos que representan la energía reflejada por cada unidad de superficie.

Una imagen satelital no es simplemente una fotografía, sino una representación digital de datos captados por sensores remotos montados en satélites u otras plataformas. Cada imagen está compuesta por una matriz de píxeles, donde cada píxel contiene un valor numérico que representa la cantidad de energía electromagnética reflejada o emitida por una pequeña porción de la superficie terrestre en una determinada longitud de onda (o banda espectral). Estos valores numéricos no son colores en sí mismos, sino medidas cuantitativas de radiancia o reflectancia, que luego pueden visualizarse en escala de grises (una sola banda) o combinarse en falsas composiciones de color (por ejemplo, usando el infrarrojo cercano, el rojo y el verde). Por eso decimos que una imagen satelital es, en esencia, un conjunto de datos científicos que describe el estado físico de la superficie terrestre (como la vegetación, el agua, el suelo o las construcciones) en función de cómo interactúa con la radiación solar. Este tipo de información es clave para monitorear cambios ambientales, realizar mapas temáticos y detectar fenómenos como deforestación, incendios, inundaciones o urbanización.

Content from Sistemas de coordenadas


Última actualización: 2025-08-19 | Mejora esta página

Tiempo estimado: 15 minutos

Hoja de ruta

Preguntas

  • ¿Qué es un sistema de coordenadas proyectadas y en qué se diferencia de un sistema geográfico?
  • ¿Qué es el sistema UTM y cómo se utiliza para referenciar imágenes satelitales?

Objetivos

  • Comprender las diferencias entre los sistemas de coordenadas geográficas y proyectadas.
  • Reconocer el sistema de coordenadas UTM y cómo se subdivide el mundo en zonas.
  • Conocer el sistema MGRS y su utilidad para identificar mosaicos satelitales.

Lss personas que se dedican a la cartografía o a ma geografía prefieren trabajar con mapas en los que las distancias medidas entre los puntos del mapa sean aproximadamente proporcionales a las distancias reales. Este no es el caso cuando se usan directamente coordenadas de latitud y longitud, típicas de un sistema de coordenadas geográficas (GCS).

Un enfoque más práctico para representar el espacio terrestre es utilizar un sistema de referencia de coordenadas proyectado. Este sistema transforma la superficie curva de la Tierra en un plano bidimensional mediante una proyección cartográfica. Esto implica cierta distorsión, pero permite trabajar con unidades métricas (por ejemplo, metros) y realizar cálculos espaciales más precisos.

Distintas proyecciones preservan diferentes propiedades: forma, área, distancia o dirección. La elección de una proyección adecuada depende del tipo de análisis que se desea realizar.

Coordenadas Universal Transversal de Mercator (UTM)


El sistema de coordenadas UTM (Universal Transverse Mercator) es uno de los más utilizados para trabajar con datos satelitales. Divide el mundo en 60 zonas longitudinales de 6° de ancho cada una, numeradas del 1 al 60 de oeste a este, comenzando desde el meridiano 180°.

Cada zona UTM tiene su propio sistema de coordenadas proyectadas basado en el modelo WGS84. Las coordenadas se expresan en metros, lo que permite ubicar con precisión cualquier punto dentro de esa zona.

  • Las coordenadas se llaman este (Easting) y norte (Northing).
  • El meridiano central tiene un falso este de 500,000 m para evitar números negativos.
  • En el hemisferio sur, también se añade un falso norte de 10,000,000 m.

Por ejemplo: - EPSG:4326 corresponde a coordenadas geográficas (latitud-longitud) con WGS84. - EPSG:3857 es la proyección Web Mercator, usada en Google Maps. - EPSG:32610 representa la zona 10N del sistema UTM. - EPSG:32710 representa la misma zona 10 pero en el hemisferio sur.

Es posible explorar estos códigos en el registro EPSG que los documenta.

Sistema de Referencia de Cuadrículas Militares (MGRS)


El MGRS (Military Grid Reference System) es un estándar de coordenadas utilizado por organizaciones como la OTAN para identificar ubicaciones en la superficie terrestre. Se basa en el sistema UTM pero lo adapta con una notación más compacta y legible.

  • Divide el mundo en zonas UTM (60 zonas de 6°).
  • Cada zona se subdivide en bandas de 8° de latitud, identificadas con letras (de C a X, sin I ni O).
  • Luego se divide en mosaicos de 100 km × 100 km, identificados por dos letras adicionales (columna y fila).

Por ejemplo, el mosaico 10TEM indica: - Zona UTM 10 - Banda T (latitud) - Columna E, fila M dentro de esa zona

Este sistema permite referenciar fácilmente regiones asociadas a imágenes satelitales sin necesidad de usar coordenadas numéricas extensas, y es el sistema adoptado por muchos productos de la NASA Earthdata.

Content from Modelos de datos geoespaciales


Última actualización: 2025-08-19 | Mejora esta página

Tiempo estimado: 21 minutos

Hoja de ruta

Preguntas

  • ¿Qué son los modelos ráster y vectorial?
  • ¿Cuáles son las diferencias clave entre estos formatos?
  • ¿En qué situaciones conviene usar cada uno?

Objetivos

  • Comprender qué representan los modelos ráster y vectorial en el análisis geoespacial.
  • Diferenciar entre los formatos según su estructura de datos y aplicaciones.
  • Identificar casos de uso en los que se aplica cada modelo para resolver problemas ambientales.

¿Qué son los modelos de datos geoespaciales?


En teledetección y sistemas de información geográfica (SIG) (en inglés, Geographical Information System, GIS), los datos espaciales se representan principalmente en dos formatos: ráster y vectorial.

Datos ráster


El término “dato ráster” o “ráster” proviene de los gráficos por computadora. En esencia, un ráster se refiere a una secuencia de valores numéricos dispuestos en una tabla rectangular (similar a una matriz de álgebra lineal).

Los conjuntos de datos ráster son útiles para representar cantidades continuas, como presión, elevación, temperatura, clasificación de la cobertura terrestre, etc., muestreadas en una teselación, es decir, una cuadrícula discreta que divide una región bidimensional de extensión finita. En el contexto de los Sistemas de Información Geográfica (GIS, por sus siglas en inglés), la región espacial es la proyección plana de una porción de la superficie terrestre.

Los rásters se aproximan a las distribuciones numéricas continuas almacenando valores individuales dentro de cada celda de la cuadrícula o píxel. Los rásters pueden representar datos recopilados en varios tipos de celdas de cuadrícula no rectangulares (por ejemplo, hexágonos). Para nuestros fines, restringiremos nuestra atención a las cuadrículas en las que todos los píxeles son rectángulos que tienen el mismo ancho y alto.

En esta imagen se muestra un ejemplo de datos ráster. Fuente: National Ecological Observatory Network (NEON).


Cómo comprender los valores de los ráster

Una diferencia importante con las matrices del álgebra lineal es que los datos ráster reales a menudo están incompletos. Por eso, suelen incluir un esquema para representar los valores “Sin datos” de los píxeles en los que no es posible hacer una observación significativa. Este esquema puede usar “NaN” (Not-a-Number) o un valor testigo, como -1.

Además, los valores de los píxeles se almacenan utilizando un tipo de datos apropiado: números de punto flotante para variables continuas (como temperatura) y enteros para propiedades categóricas (como cobertura del suelo). Como los datos ráster suelen ser grandes, elegir un tipo de datos eficiente puede reducir mucho el tamaño del archivo.


Píxel vs. coordenadas continuas

Cada píxel de un ráster está indexado por su posición de fila y columna desde la esquina superior izquierda, usando indexación desde cero. Por ejemplo, en una matriz \(10\times10\):

  • (0,0) es la esquina superior izquierda
  • (0,9) es la esquina superior derecha
  • (9,0) es la esquina inferior izquierda
  • (9,9) es la esquina inferior derecha

La indexación desde cero no es universal. Por ejemplo, MATLAB utiliza indexación desde uno. Además:

  • Las coordenadas de imagen se expresan como (fila, columna), mientras que las coordenadas continuas se expresan como (x, y).
  • La orientación del eje vertical es inversa: en coordenadas de píxel, la fila aumenta hacia abajo; en coordenadas espaciales, la coordenada y aumenta hacia arriba.

Esto puede causar confusión. Es importante verificar:

  • qué convenciones usan los datos ráster de una fuente,
  • y qué espera la herramienta GIS que estemos usando.

Conservación de los metadatos

Los datos ráster usualmente incluyen metadatos, como:

  • Sistema de Referencia de Coordenadas (SRC): ver EPSG, WKT
  • Valor NoData: como -1, 255, etc.
  • Resolución espacial: tamaño de cada píxel
  • Límites espaciales: extensión geográfica cubierta
  • Fecha y hora de adquisición: usualmente en UTC

Por ejemplo, los productos OPERA de NASA incluyen esta información en sus nombres de archivo:

OPERA_L3_DIST-ALERT-HLS_T10TEM_20220815T185931Z_20220817T153514Z_S2A_30_v0.1_VEG-ANOM-MAX.tif

Este nombre incluye la fecha (20220815T185931Z) y una ubicación MGRS (10TEM). Esto permite identificar información clave sin tener que abrir el archivo completo.


Uso de GeoTIFF

GeoTIFF es un formato ampliamente utilizado para datos ráster georreferenciados. Está basado en el formato TIFF e incluye metadatos geoespaciales embebidos. Se usa para representar fotografías aéreas, imágenes satelitales y mapas.

Los metadatos comunes en un archivo .tif incluyen:

  • extensión espacial
  • SRC utilizado
  • resolución espacial
  • dimensiones del ráster
  • cantidad de capas
  • proyecciones cartográficas

El formato está documentado en el estándar OGC GeoTIFF.

Datos vectoriales


Ciertas propiedades físicas de interés para los SIG, no se capturan convenientemente mediante datos ráster en cuadrículas discretas. Por ejemplo, las características geométricas de un paisaje, como carreteras, ríos y límites entre regiones, se describen mejor utilizando líneas o curvas en un sistema de coordenadas proyectado de manera adecuada. En el contexto de los GIS, los datos vectoriales son representaciones geométricas de estos aspectos del paisaje.

Cómo comprender los datos vectoriales

Los datos vectoriales consisten en secuencias ordenadas de vértices, es decir, pares de números de la forma \((x,y)\). Las coordenadas continuas de cada vértice se asocian a una ubicación espacial física en algún Sistema de Referencia de Coordenadas (SRC) (en inglés, Coordinate Reference System, CRS) proyectado.

  • Puntos: Los vértices aislados representan funciones discretas de dimensión cero (por ejemplo, árboles, faroles, etc.).
  • Líneas o polilíneas: Cualquier secuencia ordenada de por lo menos dos vértices constituye una polilínea que puede visualizarse trazando líneas rectas entre vértices adyacentes. Las líneas o polilíneas son adecuadas para representar características unidimensionales como carreteras, caminos y ríos.
  • Polígonos: Cualquier secuencia ordenada de por lo menos tres vértices en la que el primero y el último coinciden constituye un polígono (es decir, una forma cerrada). Los polígonos son adecuados para representar regiones bidimensionales como un lago o el límite de un bosque.

Un conjunto único de datos vectoriales georreferenciados con un CRS en particular generalmente contiene cualquier número de puntos, líneas o polígonos.

Esta imagen muestra los tres tipos de datos vectoriales: puntos, líneas y polígonos. Fuente: National Ecological Observatory Network (NEON).

Vista aérea de un paisaje y su representación vectorial con puntos.
Fuente: Sistemas de Información Geográfica por Victor Olaya.

Vista aérea de un río y su representación vectorial con líneas.
Fuente: Sistemas de Información Geográfica por Victor Olaya.

Vista aérea de un lago y su representación vectorial como polígono.
Fuente: Sistemas de Información Geográfica por Victor Olaya.

Como ocurre con los datos ráster, generalmente las representaciones de datos vectoriales van acompañadas de metadatos para almacenar diversos atributos asociados al conjunto de datos. Los datos vectoriales usualmente se especifican con un nivel de precisión superior a la resolución que permiten la mayoría de las cuadrículas ráster. Además, las características geográficas representadas como datos vectoriales permiten efectuar cálculos que los datos ráster no permiten. Por ejemplo, es posible determinar diversas relaciones geométricas o topológicas:

  • ¿Un punto se encuentra dentro de los límites de una región geográfica?
  • ¿Dos carreteras se intersecan?
  • ¿Cuál es el punto más cercano de una carretera a otra región?

Otras magnitudes geométricas, como la longitud de un río o la superficie de un lago, se obtienen aplicando técnicas de geometría computacional a representaciones de datos vectoriales.

Uso de GeoJSON

GeoJSON es un subconjunto de notación de objeto de JavaScript (JSON). Fue desarrollado a principios de la década del 2000 para representar características geográficas simples junto con atributos no espaciales. El objetivo principal es ofrecer una especificación para la codificación de datos geoespaciales que sean decodificables por cualquier decodificador JSON.

Los detalles técnicos del formato GeoJSON se describen en el documento de estándares RFC7946.

Uso de archivos Shapefiles

El estándar shapefile es un formato digital para distribuir datos vectoriales geoespaciales y sus atributos asociados. El estándar, desarrollado por ESRI, es compatible con la mayoría de las herramientas de software SIG modernas. El nombre “shapefile” es un poco engañoso porque normalmente consiste en un conjunto de varios archivos (algunos obligatorios, otros opcionales) almacenados en un directorio común con un nombre de archivo común.

El formato shapefile almacena la geometría como formas geométricas primitivas como puntos, líneas y polígonos. Estas formas, junto con los atributos de datos vinculados a cada una de ellas, crean la representación de los datos geográficos. Los tres archivos obligatorios tienen las extensiones de archivo .shp, .shx y .dbf. El shapefile real se refiere específicamente al archivo .shp, pero por sí solo está incompleto para su distribución.

Los shapefiles utilizan el formato Well-known Binary (WKB) para codificar las geometrías. Algunas limitaciones incluyen la restricción de los nombres en los campos de los atributos a 10 caracteres o menos y la escasa compatibilidad con Unicode.

Puedes consultar el informe técnico de shapefile de ESRI (PDF) para obtener más información.

Archivos obligatorios

  • .shp: geometría espacial (puntos, líneas, polígonos)
  • .shx: índice de formas
  • .dbf: atributos asociados

Archivos opcionales

  • .prj: descripción del sistema de coordenadas en formato WKT
  • .xml: metadatos geoespaciales
  • .cpg: codificación de caracteres
  • .sbn y .sbx: índices espaciales para acelerar lectura
Desafío

Ejercicio 2 - Responde a la encuesta

Q: ¿Cuál es la diferencia entre los formatos ráster y vectorial?

  1. El formato vectorial almacena imágenes en escala de grises, mientras que el ráster utiliza colores reales.
  2. El formato ráster divide el espacio en celdas con valores numéricos; el vectorial representa objetos mediante coordenadas como puntos, líneas y polígonos.
  3. El formato ráster divide el espacio en celdas; el vectorial representa el área mediante píxeles agrupados en formas.

La respuesta correcta es:

  1. El formato ráster divide el espacio en celdas con valores numéricos; el vectorial representa objetos mediante coordenadas como puntos, líneas y polígonos.

Formato ráster:

  • Representa el espacio como una matriz de celdas (píxeles).
  • Cada celda tiene un valor numérico que puede representar, por ejemplo, la reflectancia en una banda espectral, la elevación, la temperatura, etc.
  • Es útil para datos continuos, como imágenes satelitales o modelos de elevación.

Formato vectorial:

  • Representa elementos espaciales como puntos (ej. estaciones meteorológicas), líneas (ej. ríos o rutas) y polígonos (ej. lagos o parcelas).
  • Utiliza coordenadas geográficas para definir las ubicaciones exactas.
  • Es ideal para datos discretos con límites bien definidos.

Content from NASA Earthdata Cloud y productos OPERA


Última actualización: 2025-08-19 | Mejora esta página

Tiempo estimado: 52 minutos

Hoja de ruta

Preguntas

  1. ¿Cómo podemos acceder a productos satelitales de OPERA mediante la plataforma Earthdata?
  2. ¿Qué tipo de información brindan los productos OPERA, en particular los productos DSWx?
  3. ¿Cómo utilizar la API de PySTAC para automatizar búsquedas y análisis de datos geoespaciales?

Objetivos

  • Conocer las plataformas de la NASA para acceso a datos satelitales.
  • Entender la estructura y contenido de los productos OPERA.
  • Utilizar PySTAC para realizar búsquedas programáticas de datos espaciales y generar visualizaciones.

NASA Earthdata


La plataforma NASA Earthdata brinda acceso a una gran cantidad de datos de observación terrestre recolectados por la NASA. Abarca diversas disciplinas como atmósfera, criósfera, superficie terrestre, agua, suelos y más. Estos datos, en su mayoría abiertos y gratuitos, se pueden explorar en forma de productos generados a partir de sensores satelitales como MODIS, Landsat, y Sentinel.

El sistema busca facilitar el acceso, visualización y análisis de datos para la comprensión del planeta. En este curso nos centraremos en un conjunto específico de productos derivados: los productos OPERA DIST, disponibles en la nube.

Productos OPERA


OPERA (Observational Products for End-Users from Remote Sensing Analysis) es una iniciativa de la NASA que genera productos de datos derivados de sensores ópticos y radar de satélites como Sentinel-1 A/B, Sentinel-2 A/B y Landsat-8/9. En lugar de ofrecer imágenes crudas, OPERA proporciona datos procesados que clasifican áreas del territorio según ciertas características físicas como presencia de agua, alteraciones en la vegetación o cambios en la superficie.

Los productos se publican en formatos ráster y están organizados como mosaicos georreferenciados. Los productos OPERA relacionados con la superficie terrestre incluyen:

  • DIST (Land Surface Disturbance): registra alteraciones de la superficie terrestre.
  • DSWx (Dynamic Surface Water Extent): registra la extensión de cuerpos de agua.

En este tutorial nos enfocaremos en DIST ALERT, diseñada para detectar cambios recientes en la vegetación como los causados por deforestación o incendios.

Producto OPERA DIST-ALERT


Los productos DIST-ALERT mapean la perturbación de la vegetación (en concreto, la pérdida de cubierta vegetal por píxel HLS siempre que haya una disminución indicada) a partir de escenas armonizadas Landsat-8 y Sentinel-2 A/B (HLS). Una de las aplicaciones de estos datos es cuantificar los daños causados por los incendios forestales. El producto DIST-ALERT_ALERT se publica a intervalos regulares (al igual que las imágenes HLS, aproximadamente cada 12 días en un determinado mosaico/región). El producto DIST-ALERT_ANN resume las mediciones de las alteraciones a lo largo de un año.

Los productos DIST-ALERT cuantifican los datos de reflectancia de la superficie (RS) (en inglés, Surface Reflectance, SR) adquiridos a partir de imágenes terrestres operacionales Operational Land Imager (OLI) (en español, Generador de Imágenes Terrestres Operacional) a bordo del satélite de teledetección Landsat-8 y del Multi-Spectral Instrument (MSI) (en español, Instrumento Multiespectral) a bordo del satélite de teledetección Sentinel-2 A/B. Los productos de datos HLS DIST-ALERT son archivos de tipo ráster, cada uno de ellos asociado a mosaicos de la superficie terrestre. Cada mosaico se representa mediante coordenadas cartográficas proyectadas alineadas con el Sistema de Referencia de Cuadrículas Militares (MGRS, por sus siglas en inglés de Military Grid Reference System). Cada mosaico se divide en 3,660 filas y 3,660 columnas con un espaciado de píxeles de 30 metros (así que un mosaico es de \(109.8\,\mathrm{km}\) largo en cada lado). Los mosaicos vecinos se solapan 4.900 metros en cada dirección (los detalles se describen detalladamente en la especificación de producto DIST-ALERT).

Los productos OPERA DIST-ALERT se distribuyen como GeoTIFFs optimizados para la nube; en la práctica, esto significa que las diferentes bandas se almacenan en archivos de formato TIFFs (TIFF, por sus siglas en inglés, Tagged Image File Format) distintos. La especificación TIFF permite el almacenamiento de matrices multidimensionales en un único archivo. El almacenamiento de bandas distintas en diferentes archivos TIFF permite que estos se descarguen de forma independiente.

Bandas

Los archivos DIST-ALERT contienen diferentes bandas, entre ellas:

  • VEG_ANOM_MAX: Para cada píxel, se trata de un valor entre 0% y 100% que representa la diferencia porcentual entre la cobertura vegetal que se observa actualmente y un valor de referencia histórico. Es decir, un valor de 100 corresponde a una pérdida total de vegetación en un píxel (100%) y un valor de 0 corresponde a que no hubo pérdida de vegetación. 255 representa un valor faltante.
  • VEG_DIST_DATE: Fecha (como número de días desde el 31/12/2020) en que se detectó la primera alteración. Permite observar la progresión de un evento como un incendio. En esta banda en particular, el valor 0 indica que no ha habido alteraciones en el último año y -1 es un valor que indica que faltan datos. Cualquier valor positivo es el número de días desde el 31 de diciembre del 2020 en los que se midió la primera alteración en ese píxel.
  • VEG_DIST_STATUS: Estado de la alteración en la vegetación:
    • 0: Sin alteración
    • 1: Alteración provisional (primera detección) con cambio en la cubierta vegetal < 50%
    • 2: Alteración confirmada (detección recurrente) con cambio en la cubierta vegetal < 50%
    • 3: Alteración provisional con cambio en la cobertura vegetal ≥ 50%
    • 4: Alteración confirmada con cambio en la cobertura vegetal ≥ 50%
    • 255: Datos no disponibles

Cada banda permite analizar diferentes aspectos del cambio en la cobertura vegetal, siendo útiles para estudios ambientales, evaluación de daños por incendios, y seguimiento de transformaciones del uso del suelo.

Content from Caso de Estudio


Última actualización: 2025-08-19 | Mejora esta página

Tiempo estimado: 20 minutos

Hoja de ruta

Preguntas

  • ¿Qué proporción del área de estudio presenta disturbios recientes en la cobertura vegetal según los datos VEG_DIST_STATUS filtrados por baja nubosidad?
  • ¿Cómo ha evolucionado la extensión de los disturbios a lo largo del período analizado en Buriticupu?
  • ¿En qué zonas y fechas específicas se detectaron los disturbios más intensos (≥50% de cambio en la cobertura vegetal)?

Objetivos

  • Procesar y filtrar los productos OPERA DIST-ALERT para extraer información relevante del área de estudio en Maranhão.
  • Visualizar y analizar los cambios en la cobertura vegetal a lo largo del tiempo, identificando patrones de disturbio recientes.
  • Elaborar mapas y gráficos que sinteticen la información geoespacial, facilitando la interpretación y comunicación de los resultados para la toma de decisiones en conservación.

Deforestación en Maranhão

La Amazonía es una de las regiones más biodiversas del planeta y un componente clave del sistema climático global que además sostiene múltiples comunidades indígenas. En particular el estado de Maranhão, en Brasil, es uno de los focos más críticos de deforestación en el país. Se estima que el 76 % de la cobertura original de bosque amazónico en este estado ha sido destruida. Según Global Forest Watch, Maranhão ha registrado una de las tasas más altas de pérdida de cobertura boscosa en Brasil en los últimos años, impulsada por incendios, expansión agropecuaria y tala ilegal. Estos procesos están estrechamente ligados a la fragmentación ecológica, la pérdida de biodiversidad y la violencia hacia comunidades indígenas. Frente a este escenario, el monitoreo sistemático de los cambios en la cobertura vegetal es fundamental. Los productos OPERA DIST-HLS, derivados principalmente de Landsat (NASA/USGS) y Sentinel-2 (ESA), ofrecen una herramienta poderosa para detectar disturbios recientes y aportar evidencia clave para la conservación y la formulación de políticas públicas basadas en datos.

Buriticupu - erosión
Foto: AFP / El País (2023)

Ruta de trabajo

Nuestro objetivo es evaluar la deforestación en un area cercana a la ciudad de Buriticupu en el estado Maranhao. Para eso en esta notebook vamos a :

  1. Filtrar y seleccionar los productos OPERA DIST-ALERT desde la nube
  2. Visualizar y explorar los subproductos VEG_DIST_STATUS
  3. Gráficar la evolución del disturbio a lo largo del tiempo.
  4. Generar un mapa de disturbios
  5. Explorar subproducto VEG_DIST_DATE

Antes de empezar - Importar librerías que vamos a utilizar

PYTHON


#librerias para manipulación de datos
from warnings import filterwarnings #suprime los warning
filterwarnings('ignore')
import numpy as np, pandas as pd, xarray as xr
import rioxarray as rio
import rasterio

#librerias para visualización
import hvplot.pandas, hvplot.xarray
import geoviews as gv
from geoviews import opts
gv.extension('bokeh')

#configuración de acceso a datos geoespaciales desde la nube
from pystac_client import Client
from osgeo import gdal
gdal.SetConfigOption('GDAL_HTTP_COOKIEFILE','~/.cookies.txt')
gdal.SetConfigOption('GDAL_HTTP_COOKIEJAR', '~/.cookies.txt')
gdal.SetConfigOption('GDAL_DISABLE_READDIR_ON_OPEN','EMPTY_DIR')
gdal.SetConfigOption('CPL_VSIL_CURL_ALLOWED_EXTENSIONS','TIF, TIFF')

FILTRAR Y SELECCIONAR LOS PRODUCTOS OPERA DESDE LA NUBE

1.a. Seleccionar el area de estudio

Usa la herramienta Bounding Box para obtener las coordenadas geográficas (latitud y longitud) del área seleccionada.

Bounding Box es un selector visual de cajas geográficas (bounding boxes) que permite:

  • Dibujar un rectángulo o polígono directamente sobre un mapa interactivo para delimitar un área específica-
  • Obtener las coordenadas geográficas (latitud y longitud) del área seleccionada y copiarlas fácilmente en diversos formatos útiles como MARC, DublinCore, KML, GeoJSON, OGC WKT, CSV, FGDC, entre otros.

Sigue los siguientes pasos:

  1. Navega hasta la página https://boundingbox.klokantech.com/
  2. Busca la zona de interés y dibuja un rectángulo sobre el mapa.
  3. En la sección “Copy & Paste”, selecciona el formato “CSV”.
  4. Copia las coordenadas

Estas coordenadas están en el orden correcto requerido por STAC:

bbox = [xmin, ymin, xmax, ymax] = [long_oeste, lat_sur, long_este, lat_norte]

El siguiente ejemplo supone que las coordenadas copiadas de boundingbox son -46.52993,-4.383815,-43.363075,-4.243793

  1. Define el area utilizando las coordenadas copiadas y define el rango de fechas de interés.

PYTHON


#Definir el AOI con las coordenadas 
AOI = [-46.52993,-4.383815,-46.363075,-4.243793]
rango_fechas = "2022-01-01/2024-03-31"

1.b. Explorar y buscar los productos OPERA DIST-ALERT

PYTHON


# Realizamos la búsqueda de productos OPERA DIST-ALERT para ver fechas disponibles
from pystac_client import Client

# Retomamos los parámetros de búsqueda definidos en el punto anterior
search_params = {
    "bbox": AOI,
    "datetime": rango_fechas,
    "collections": ["OPERA_L3_DIST-ALERT-HLS_V1_1"]
}

client = Client.open("https://cmr.earthdata.nasa.gov/stac/LPCLOUD/")
items = list(client.search(**search_params).get_items())

# Extraemos fechas disponibles
fechas = sorted({item.datetime.date() for item in items})
print(f"Fechas disponibles ({len(fechas)}):")
print(fechas)

Fechas disponibles (109):

[datetime.date(2023, 1, 2), datetime.date(2023, 1, 5), datetime.date(2023, 1, 7), datetime.date(2023, 1, 12), datetime.date(2023, 1, 13), datetime.date(2023, 1, 17), datetime.date(2023, 1, 21), datetime.date(2023, 1, 22), datetime.date(2023, 1, 27), datetime.date(2023, 2, 1), datetime.date(2023, 2, 6), datetime.date(2023, 2, 11), datetime.date(2023, 2, 14), datetime.date(2023, 2, 16), datetime.date(2023, 2, 21), datetime.date(2023, 2, 26), datetime.date(2023, 3, 3), datetime.date(2023, 3, 8), datetime.date(2023, 3, 10), datetime.date(2023, 3, 18), datetime.date(2023, 3, 23), datetime.date(2023, 3, 26), datetime.date(2023, 3, 28), datetime.date(2023, 4, 2), datetime.date(2023, 4, 3), datetime.date(2023, 4, 7), datetime.date(2023, 4, 12), datetime.date(2023, 4, 17), datetime.date(2023, 4, 22), datetime.date(2023, 4, 27), datetime.date(2023, 5, 2), datetime.date(2023, 5, 5), datetime.date(2023, 5, 12), datetime.date(2023, 5, 17), datetime.date(2023, 5, 21), datetime.date(2023, 5, 22), datetime.date(2023, 5, 27), datetime.date(2023, 5, 29), datetime.date(2023, 6, 1), datetime.date(2023, 6, 6), datetime.date(2023, 6, 11), datetime.date(2023, 6, 14), datetime.date(2023, 6, 16), datetime.date(2023, 6, 21), datetime.date(2023, 6, 22), datetime.date(2023, 6, 26), datetime.date(2023, 6, 30), datetime.date(2023, 7, 1), datetime.date(2023, 7, 6), datetime.date(2023, 7, 8), datetime.date(2023, 7, 11), datetime.date(2023, 7, 16), datetime.date(2023, 7, 21), datetime.date(2023, 7, 24), datetime.date(2023, 7, 26), datetime.date(2023, 7, 31), datetime.date(2023, 8, 1), datetime.date(2023, 8, 5), datetime.date(2023, 8, 10), datetime.date(2023, 8, 15), datetime.date(2023, 8, 20), datetime.date(2023, 8, 25), datetime.date(2023, 8, 30), datetime.date(2023, 9, 2), datetime.date(2023, 9, 4), datetime.date(2023, 9, 9), datetime.date(2023, 9, 10), datetime.date(2023, 9, 14), datetime.date(2023, 9, 18), datetime.date(2023, 9, 19), datetime.date(2023, 9, 24), datetime.date(2023, 9, 26), datetime.date(2023, 9, 29), datetime.date(2023, 10, 4), datetime.date(2023, 10, 9), datetime.date(2023, 10, 12), datetime.date(2023, 10, 14), datetime.date(2023, 10, 19), datetime.date(2023, 10, 20), datetime.date(2023, 10, 28), datetime.date(2023, 11, 5), datetime.date(2023, 11, 13), datetime.date(2023, 11, 18), datetime.date(2023, 11, 21), datetime.date(2023, 11, 28), datetime.date(2023, 12, 8), datetime.date(2023, 12, 13), datetime.date(2023, 12, 18), datetime.date(2023, 12, 23), datetime.date(2023, 12, 28), datetime.date(2024, 1, 7), datetime.date(2024, 1, 8), datetime.date(2024, 1, 16), datetime.date(2024, 1, 17), datetime.date(2024, 1, 22), datetime.date(2024, 1, 27), datetime.date(2024, 2, 1), datetime.date(2024, 2, 6), datetime.date(2024, 2, 11), datetime.date(2024, 2, 16), datetime.date(2024, 2, 17), datetime.date(2024, 2, 21), datetime.date(2024, 2, 25), datetime.date(2024, 2, 26), datetime.date(2024, 3, 2), datetime.date(2024, 3, 12), datetime.date(2024, 3, 17), datetime.date(2024, 3, 27), datetime.date(2024, 3, 28)]

Cada item OPERA DIST-ALERT incluye varios assets .tif, y cada uno representa una capa de información distinta:

  • VEG-DIST-STATUS.tif: detección de disturbio
  • VEG-DIST-CONF.tif: nivel de confianza de la detección
  • VEG-DIST-DATE.tif: fecha en que se detectó el disturbio
  • VEG-ANOM.tif: anomalía de la vegetación
  • VEG-IND.tif: índice de vegetación
  • VEG-LAST-DATE.tif: última fecha sin disturbio detectado
  • VEG-DIST-DUR.tif: duración acumulada del disturbio
  • VEG-DIST-COUNT.tif: número de disturbios detectados

PYTHON


#Imprimimos los archivos que se encuentran dentro de 1 item
item = items[0]  

print(f"Item - Fecha: {item.datetime.date()}")
for asset_key, asset in item.assets.items():
    print(f"  Asset: {asset_key}{asset.href}")
    

Item - Fecha: 2023-01-02

Asset: browse → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-public/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS.png

Asset: thumbnail_0 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-public/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS.png

Asset: thumbnail_1 → s3://lp-prod-public/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS.png

Asset: gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS.tif

Asset: gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-IND → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-IND.tif

..

Asset: s3_s3://lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_DATA-MASK → s3://lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_DATA-MASK.tif

Asset: metadata → https://cmr.earthdata.nasa.gov/search/concepts/G2865237949-LPCLOUD.xml

Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings…


1.c Filtramos los asset VEG_DIST-STATUS con baja nubosidad

PYTHON


# Recorremos todos los productos encontrados y seleccionamos solo los archivos .tif
# correspondientes al asset 'VEG-DIST-STATUS'
# Guardamos la fecha del producto y el link al archivo 

veg_status_assets = []

for item in items:
    for key, asset in item.assets.items():
        if "VEG-DIST-STATUS" in key and asset.href.endswith(".tif"):
            veg_status_assets.append({
                "fecha": item.datetime.date(),
                "url": asset.href
            })

print(f"Se encontraron {len(veg_status_assets)} archivos VEG-DIST-STATUS.")

#imprimimos los primeros 10
for registro in veg_status_assets[:10]:
    print(f"  {registro['fecha']}{registro['url']}")
    

Se encontraron 234 archivos VEG-DIST-STATUS.

2023-01-02 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS.tif

2023-01-02 → s3://lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230102T133149Z_20231221T081031Z_S2B_30_v1_VEG-DIST-STATUS.tif

2023-01-05 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230105T131743Z_20231221T081050Z_L8_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230105T131743Z_20231221T081050Z_L8_30_v1_VEG-DIST-STATUS.tif

2023-01-05 → s3://lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230105T131743Z_20231221T081050Z_L8_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230105T131743Z_20231221T081050Z_L8_30_v1_VEG-DIST-STATUS.tif

2023-01-07 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230107T133151Z_20231221T081127Z_S2A_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230107T133151Z_20231221T081127Z_S2A_30_v1_VEG-DIST-STATUS.tif

PYTHON


# Imprimimos cloud_cover de los items con asset VEG-DIST-STATUS
for item in items:
    if any("VEG-DIST-STATUS" in k for k in item.assets):
        print(f"{item.datetime.date()} → Cloud cover: {item.properties.get('eo:cloud_cover', 'No disponible')}")

2023-01-02 → Cloud cover: 81

2023-01-05 → Cloud cover: 79

2023-01-07 → Cloud cover: 99

2023-01-12 → Cloud cover: 80

2023-01-13 → Cloud cover: 90

2023-01-17 → Cloud cover: 81

2024-03-12 → Cloud cover: 92

2024-03-17 → Cloud cover: 99

2024-03-27 → Cloud cover: 72

2024-03-28 → Cloud cover: 89

Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings…

PYTHON


filtrados = []

for item in items:
    cloud = item.properties.get('eo:cloud_cover', None)
    if cloud is not None and cloud < 40:
        for key, asset in item.assets.items():
            if (
                "VEG-DIST-STATUS" in key and 
                asset.href.endswith(".tif") and 
                asset.href.startswith("https")
            ):
                filtrados.append({
                    "fecha": item.datetime.date(),
                    "url": asset.href,
                    "nubes": cloud
                })
print(f"Se encontraron {len(filtrados)} archivos con menos de 40% de nubes.")
for registro in filtrados[:10]:
    print(f"{registro['fecha']} → Cloud cover: {registro['nubes']}{registro['url']}")
    

Se encontraron 12 archivos con menos de 40% de nubes.

2023-06-26 → Cloud cover: 9 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230626T133151Z_20231221T083621Z_S2A_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230626T133151Z_20231221T083621Z_S2A_30_v1_VEG-DIST-STATUS.tif

2023-07-06 → Cloud cover: 0 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230706T133151Z_20231221T083820Z_S2A_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230706T133151Z_20231221T083820Z_S2A_30_v1_VEG-DIST-STATUS.tif

2023-07-21 → Cloud cover: 0 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230721T133149Z_20231221T084137Z_S2B_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230721T133149Z_20231221T084137Z_S2B_30_v1_VEG-DIST-STATUS.tif

2023-07-24 → Cloud cover: 26 → https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230724T131653Z_20231221T084202Z_L9_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230724T131653Z_20231221T084202Z_L9_30_v1_VEG-DIST-STATUS.tif

VISUALIZAR Y EXPLORAR Productos VEG_DIST_STATUS

PYTHON


#Visualizar productos VEG_DIST_STATUS en el area de interes.

#convertir a shp las coordenadas del area de interes (AOI)
from shapely.geometry import box
import geopandas as gpd

# AOI definido como bounding box
aoi_coords = [-46.78, -4.61, -46.58, -4.41]  # xmin, ymin, xmax, ymax
aoi_geom = box(*aoi_coords)
AOI = gpd.GeoDataFrame(geometry=[aoi_geom], crs="EPSG:4326")

#Visualizar la primer y ultima fecha del los productos filtrados
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import geopandas as gpd
import rioxarray

# Crear colormap personalizado
white_to_red = mcolors.LinearSegmentedColormap.from_list("white_to_red", ["white", "red"])

# URLs de los dos productos
urls = [
    ("26/06/2023", "https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230626T133151Z_20231221T083621Z_S2A_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230626T133151Z_20231221T083621Z_S2A_30_v1_VEG-DIST-STATUS.tif"),
    ("18/09/2023", "https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230918T131723Z_20231221T085043Z_L8_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230918T131723Z_20231221T085043Z_L8_30_v1_VEG-DIST-STATUS.tif")
]

# Crear figura
fig, axes = plt.subplots(1, 2, figsize=(12, 6), constrained_layout=True)

for ax, (label, url) in zip(axes, urls):
    da = rioxarray.open_rasterio(url, masked=True).squeeze()
    # Reproyectar AOI al CRS del raster
    aoi_proj = AOI.to_crs(da.rio.crs)
    # Recorte
    da_clip = da.rio.clip(aoi_proj.geometry, aoi_proj.crs)
    # Plot
    img = da_clip.plot(
        ax=ax,
        cmap=white_to_red,
        vmin=0,
        vmax=8,
        add_colorbar=False
    )
    aoi_proj.boundary.plot(ax=ax, edgecolor="black", linewidth=0.5)
    ax.set_title(f"Disturbios detectados\n{label}")
    ax.axis("off")

# Agregar colorbar común
cbar = fig.colorbar(img, ax=axes.ravel().tolist(), shrink=0.6, label="Vegetation_disturbance_status")
plt.show()

Valores del producto VEG-DIST-STATUS:

  • 0: Sin alteración
  • 1: Primera detección de alteraciones con cambios en la cobertura vegetal <50%
  • 2: Detección provisional de alteraciones con cambios en la cobertura vegetal <50%
  • 3: Detección confirmada de alteraciones con cambios en la cobertura vegetal < 50%
  • 4: Primera detección de alteraciones con cambios en la cobertura vegetal ≥50%
  • 5: Detección provisional de alteraciones con cambios en la cobertura vegetal ≥50%
  • 6: Detección confirmada de alteraciones con cambios en la cobertura vegetal ≥50%
  • 7: Detección finalizada de alteraciones con cambios en la cobertura vegetal <50%
  • 8: Detección finalizada de alteraciones con cambios en lacobertura vegetal ≥50%
  • 255 Datos faltantes

PYTHON


#Graficar la distribución de los valores de disturbios en dos subproductos DIST-VEG-ALERT

import matplotlib.pyplot as plt
import numpy as np
import rioxarray

# URLs de los dos productos
urls = [
    ("26/06/2023", "https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230626T133151Z_20231221T083621Z_S2A_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230626T133151Z_20231221T083621Z_S2A_30_v1_VEG-DIST-STATUS.tif"),
    ("18/09/2023", "https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230918T131723Z_20231221T085043Z_L8_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230918T131723Z_20231221T085043Z_L8_30_v1_VEG-DIST-STATUS.tif")
]

# Leer y calcular frecuencias primero
frecuencias = []
for label, url in urls:
    da = rioxarray.open_rasterio(url, masked=True).squeeze()
    aoi_proj = AOI.to_crs(da.rio.crs)
    da_clip = da.rio.clip(aoi_proj.geometry, aoi_proj.crs)
    vals = da_clip.values.flatten()
    vals = vals[(vals > 0) & (~np.isnan(vals))]
    hist, _ = np.histogram(vals, bins=np.arange(0.5, 9.5, 1))
    frecuencias.append((label, hist))

# Encontrar el máximo para escalar ambos plots
ymax = max(hist.max() for _, hist in frecuencias)

# Gráfico
fig, axes = plt.subplots(1, 2, figsize=(12, 4), constrained_layout=True)
for ax, (label, hist) in zip(axes, frecuencias):
    ax.bar(range(1, 9), hist, color='crimson', edgecolor='black', alpha=0.7)
    ax.set_xticks(range(1, 9))
    ax.set_ylim(0, ymax + ymax * 0.1)
    ax.set_title(f"Histograma - {label}")
    ax.set_xlabel("Clase de disturbio")
    ax.set_ylabel("Frecuencia")

plt.suptitle("Distribución de clases de disturbio detectadas", fontsize=14)
plt.show()

EVOLUCIÓN DEL DISTURBIO A LO LARGO DEL TIEMPO

PYTHON

# Stack de los 12 subproductos VEG-DIST-STATUS

from rioxarray import open_rasterio
import xarray as xr
import numpy as np
import pandas as pd

# Recortar cada raster al AOI y luego apilar
raster_list = []
fechas = []

for f in filtrados:    
    da = open_rasterio(f["url"], masked=True).squeeze()
    aoi_proj = AOI.to_crs(da.rio.crs)
    da_clip = da.rio.clip(aoi_proj.geometry, aoi_proj.crs)
    
    raster_list.append(da_clip)
    fechas.append(pd.Timestamp(f["fecha"]))

# Crear el stack recortado
stack = xr.concat(raster_list, dim="time")
stack["time"] = fechas

stack

xarray.DataArraytime: 12y: 738x: 741 array([[[nan, nan, nan, …, 0., 0., nan], [nan, nan, nan, …, 2., 0., nan], [ 0., 0., 0., …, 0., 1., nan], …, [nan, nan, 0., …, 0., 0., 0.], [nan, nan, 0., …, 0., 0., 0.], [nan, nan, 0., …, 0., 0., 0.]],

SH

   [[nan, nan, nan, ...,  1.,  0., nan],
    [nan, nan, nan, ...,  2.,  1., nan],
    [ 0.,  0.,  0., ...,  0.,  2., nan],
    ...,
    [nan, nan,  0., ...,  0.,  0.,  0.],
    [nan, nan,  0., ...,  0.,  0.,  0.],
    [nan, nan,  0., ...,  0.,  0.,  0.]],

    ...,
    
    [nan, nan,  1., ...,  0.,  0.,  0.],
    [nan, nan,  0., ...,  0.,  0.,  0.],
    [nan, nan,  0., ...,  0.,  0.,  0.]]], dtype=float32)
    
    

PYTHON


#Graficar el area disturbada acumulada en el area de estudio

import matplotlib.pyplot as plt

#ordenaar el stack por fecha
stack_sorted = stack.sortby("time")

# Crear máscara booleana donde el valor sea 6 (disturbio confirmado)
disturbios = stack_sorted == 6

# Sumar la cantidad de píxeles por fecha
pixeles_por_fecha = disturbios.sum(dim=["x", "y"])

# Convertir a km² (cada píxel es de 30m x 30m = 900 m² = 0.0009 km²)
km2_por_fecha = pixeles_por_fecha * 0.0009

# Graficar
plt.figure(figsize=(8, 5))
km2_por_fecha.to_series().plot(marker='o')
plt.title("Evolución de disturbios confirmados (valor 6)")
plt.ylabel("Área acumulada (km²)")
plt.xlabel("Fecha")
plt.grid(True)
plt.tight_layout()
plt.show()
Aviso

¿Hay algo raro en los gráficos?

Tal vez notes que una fecha tiene dos puntos. Eso es porque el producto OPERA usa imágenes SENTINEL y LANDSAT, y puede ocurrir que en alguna fecha haya dos productos. En ese caso, es necesario seleccionar alguno de ellos en base a algún criterio. Debajo, seleccionamos la imagen con menos nubes y, de esa forma, cuando volvemos a ejecutar el código que genera el gráfico encontramos solo un producto por fecha.

PYTHON


# Convertir a DataFrame 
df_filtrados = pd.DataFrame(filtrados)
df_filtrados["fecha"] = pd.to_datetime(df_filtrados["fecha"])

# Ordenar por menor cobertura de nubes 
df_filtrados = df_filtrados.sort_values("nubes")
#Seleccionar el producto con Sentinel

# Eliminar duplicados dejando el que tiene menor nubosidad
df_filtrados = df_filtrados.drop_duplicates(subset="fecha", keep="first")

# Reconstruir la lista filtrada
filtrados_unicos = df_filtrados.to_dict(orient="records")

#VOLVEMOS A CORRER EL STACK USANDO filtrados_unicos

# Stack de los subproductos VEG-DIST-STATUS

from rioxarray import open_rasterio
import xarray as xr
import numpy as np
import pandas as pd

# Recortar cada raster al AOI y luego apilar
raster_list = []
fechas = []

for f in filtrados_unicos: 
    da = open_rasterio(f["url"], masked=True).squeeze()
    aoi_proj = AOI.to_crs(da.rio.crs)
    da_clip = da.rio.clip(aoi_proj.geometry, aoi_proj.crs)
    
    raster_list.append(da_clip)
    fechas.append(pd.Timestamp(f["fecha"]))

# Crear el stack recortado
stack = xr.concat(raster_list, dim="time")
stack["time"] = fechas

GENERAR UN MAPA DE DISTUBIOS

PYTHON


import hvplot.xarray
import geoviews as gv
import numpy as np

# Enmascarar valores 0 para que sean transparentes
stack_masked = stack.where(stack != 0)

# Submuestreo para que no sea tan pesado
stack_sub = stack_masked.isel(x=slice(0, None, 4), y=slice(0, None, 4))

# Colormap rojo fuerte
cmap = ["#fff5f5", "#fcbfbf", "#f78787", "#f25454", "#e93232", "#d40000", "#a50000", "#730000"]

# Visualización interactiva
hvplot_map = stack_sub.hvplot(
    x='x',
    y='y',
    groupby='time',
    cmap=cmap,
    clim=(1, 8),
    rasterize=True,
    crs=stack.rio.crs,
    tiles=gv.tile_sources.EsriImagery,
    alpha=0.9,
    frame_width=500,    
    frame_height=500,
    title="Evolución de disturbios detectados",
    widget_location='bottom',   # Deslizador de tiempo abajo
    colorbar=True
)

hvplot_map

EXPLORAR SUBPRODUCTO VEG_DIST-DATE

PYTHON


from pystac_client import Client
import pandas as pd

# Abrir el catálogo STAC de LP DAAC
catalog = Client.open("https://cmr.earthdata.nasa.gov/stac/LPCLOUD/")

# Parámetros de búsqueda
search_params = {
    "bbox": [-46.78, -4.61, -46.58, -4.41],  # AOI
    "datetime": "2025-01-01/2025-07-26",     # rango de fechas
    "collections": ["OPERA_L3_DIST-ALERT-HLS_V1_1"]
}

# Buscar items en el catálogo
items = list(catalog.search(**search_params).get_items())

# Filtrar solo los assets VEG-DIST-DATE accesibles por HTTPS
filtrado_date = []

for item in items:
    for asset_key, asset in item.assets.items():
        if "VEG-DIST-DATE" in asset_key and asset.href.startswith("https"):
            filtrado_date.append({
                "start_datetime": item.properties.get("start_datetime"),
                "end_datetime": item.properties.get("end_datetime"),
                "datetime": item.datetime,
                "cloud_cover": item.properties.get("eo:cloud_cover"),
                "url": asset.href
            })

# Convertir a DataFrame para explorar
df = pd.DataFrame(filtrado_date)

# Mostrar resumen
print(f"Se encontraron {len(df)} assets únicos con VEG-DIST-DATE vía HTTPS.")
df.head()

Se encontraron 226 assets únicos con VEG-DIST-DATE vía HTTPS.

| start_datetime | end_datetime | datetime | cloud_cover | url

0 | 2025-01-01T13:33:27.790Z | 2025-01-01T13:33:27.790Z | 2025-01-01 13:33:27.790000+00:00 | 88 | https://data.lpdaac.earthdatacloud.nasa.gov/lp… 1 | 2025-01-01T13:33:30.822Z | 2025-01-01T13:33:30.822Z | 2025-01-01 13:33:30.822000+00:00 | 83 | https://data.lpdaac.earthdatacloud.nasa.gov/lp… 2 | 2025-01-01T13:33:42.170Z | 2025-01-01T13:33:42.170Z | 2025-01-01 13:33:42.170000+00:00 | 92 | https://data.lpdaac.earthdatacloud.nasa.gov/lp… 3 | 2025-01-01T13:33:45.292Z | 2025-01-01T13:33:45.292Z | 2025-01-01 13:33:45.292000+00:00 | 88 | https://data.lpdaac.earthdatacloud.nasa.gov/lp… 4 | 2025-01-02T13:17:23.274Z | 2025-01-02T13:17:47.190Z | 2025-01-02 13:17:23.274000+00:00 | 83 | https://data.lpdaac.earthdatacloud.nasa.gov/lp..

PYTHON


import matplotlib.pyplot as plt

df["cloud_cover"] = pd.to_numeric(df["cloud_cover"], errors='coerce')
df.plot(
   #x="datetime", 
    y="cloud_cover", 
    kind="bar", 
    figsize=(10, 5), 
    color="skyblue", 
    title="Cobertura de nubes por escena"
)
# Ocultar etiquetas del eje X
plt.xticks([])

plt.tight_layout()
plt.show()

PYTHON



df_bajanubosidad = df[df["cloud_cover"] < 20]

df_bajanubosidad.plot(
   #x="datetime", 
    y="cloud_cover", 
    kind="bar", 
    figsize=(10, 5), 
    color="skyblue", 
    title="Cobertura de nubes por fecha"
)

PYTHON


# Asegurarse de que la columna de fechas esté como datetime
df_bajanubosidad["end_datetime"] = pd.to_datetime(df_bajanubosidad["end_datetime"])

# Ordenar por fecha final y seleccionar el más reciente
más_reciente_baja_nubosidad = df_bajanubosidad.sort_values("end_datetime", ascending=False).iloc[0]

# Mostrar resultado
print("Producto más reciente con menos de 20% de nubosidad:")
print(más_reciente_baja_nubosidad)

Producto más reciente con menos de 20% de nubosidad:

|——————————-|———————————-:| |start_datetime | 2025-07-17T13:34:04.242Z | |end_datetime | 2025-07-17 13:34:04.242000+00:00 | |datetime | 2025-07-17 13:34:04.242000+00:00 | |cloud_cover | 0 |

url https://data.lpdaac.earthdatacloud.nasa.gov/lp

Name: 218, dtype: object

PYTHON


#seleccionamos la url del producto mas reciente con nubosidad < 20%
url=más_reciente_baja_nubosidad["url"]

#Visualizar el subproducto VEG_DIST_DATE en comparación con el subproducto VEG_DIST_STATE

import matplotlib.pyplot as plt
import geopandas as gpd
import rioxarray
import numpy as np
from shapely.geometry import box

# AOI
aoi_geom = gpd.GeoDataFrame(geometry=[box(-46.78, -4.61, -46.58, -4.41)], crs="EPSG:4326")

# Subproducto VEG_DIST_DATE
url1 = más_reciente_baja_nubosidad["url"]
da1 = rioxarray.open_rasterio(url1, masked=True).squeeze()
aoi_proj = aoi_geom.to_crs(da1.rio.crs)
da1_clip = da1.rio.clip(aoi_proj.geometry, aoi_proj.crs)
masked1 = np.ma.masked_where(da1_clip <= 0, da1_clip)

# Subproducto VEG_DIST_STATUS
url2= "https://data.lpdaac.earthdatacloud.nasa.gov/lp-prod-protected/OPERA_L3_DIST-ALERT-HLS_V1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230918T131723Z_20231221T085043Z_L8_30_v1/OPERA_L3_DIST-ALERT-HLS_T23MLR_20230918T131723Z_20231221T085043Z_L8_30_v1_VEG-DIST-STATUS.tif"
da2 = rioxarray.open_rasterio(url2, masked=True).squeeze()
da2_clip = da2.rio.clip(aoi_proj.geometry, aoi_proj.crs)
masked2 = np.ma.masked_where(da2_clip <= 0, da2_clip)

# Gráfico de los 2 subproductos
fig, axes = plt.subplots(1, 2, figsize=(14, 6))

# Mapa 1
img1 = axes[0].imshow(
    masked1,
    cmap="viridis",
    extent=da1_clip.rio.bounds(),
    interpolation="nearest"
)
axes[0].set_title("VEG_DIST_DATE 17/07/2025")
axes[0].set_frame_on(True)
cbar1 = plt.colorbar(img1, ax=axes[0], shrink=0.7)
cbar1.set_label("Día desde 2020-12-31")

# colormap personalizado
white_to_red = mcolors.LinearSegmentedColormap.from_list("white_to_red", ["white", "red"])
# Mapa 2
img2 = axes[1].imshow(
    masked2,
    cmap= white_to_red,
    extent=da2_clip.rio.bounds(),
    interpolation="nearest"
)
axes[1].set_title("VEG_DIST-STATUS 18/09/2023")
axes[1].set_frame_on(True)
cbar2 = plt.colorbar(img2, ax=axes[1], shrink=0.7)
cbar2.set_label("Valor de disturbio")

plt.tight_layout()
plt.show()

Content from Diapositivas


Última actualización: 2025-08-19 | Mejora esta página

Puedes descargar las diapositivas desde este enlace

Si quieres referenciarlas o reutilizarlas, puedes hacerlo libremente. Nuestros materiales se publican bajo una licencia Creative Commons Atribución (CC BY 4.0).

Solo te pedimos que nos cites:

Gonzalez, E., Gayol, M., Formoso, J., Palopoli, N., & Buede, J. (2025, agosto 11). Introducción al uso de datos NASA Earthdata Cloud para el monitoreo de cambios y disturbios ambientales. Zenodo. https://doi.org/10.5281/zenodo.16808923