1 votos

Implementar system:time_start para el análisis de la tendencia del NDVI en GEE

Estoy desarrollando un análisis de la tendencia anual del NDVI utilizando datos del Landsat en Earth Engine durante las últimas décadas. Mi proceso es añadir una banda de NDVI a cada escena para cada mes de verano (verde), luego reducir la colección por la mediana a una imagen por mes y finalmente reducir todas las imágenes mensuales por el máximo para generar una imagen para un año. Mi plan es crear una serie temporal para ver las tendencias positivas/negativas del NDVI a lo largo de los años, pero en algún punto del camino el system:time_start se pierde al reducir las imágenes. Quiero generar un gráfico pero siempre termino con: Error generating chart: No features contain non-null values of "system:time_start". Sé que puedes copyProperties(image, ['system:time_start']) pero no puedo encontrar dónde y cómo. Para reducir la longitud del código, lo reduje a dos meses:

//cloud mask & UNIX time
var timeField = 'system:time_start';

function maskL8sr(image) {
  var cloudShadowBitMask = (1 << 3);
  var cloudBitMask = (1 << 5);
  var qa = image.select('pixel_qa');
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
              .and(qa.bitwiseAnd(cloudBitMask).eq(0));
  return image.updateMask(mask)
    .select('B[0-9]*')
    .copyProperties(image, ['system:time_start']);
}

var geometryexpl = ee.Geometry.Polygon([[155.23045236462508,69.80628971253647],
                                      [159.03172189587508,70.77679819617978],
                                      [155.23045236462508,70.77679819617978],
                                      [155.23045236462508,69.80628971253647]]);

var landsat = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR");

//compute NDVI of biweekly plots
var addVariables = function(image) {
  //compute time in fractional years since the epoch
  var date = ee.Date(image.get(timeField));
  var years = date.difference(ee.Date('1970-01-01'), 'year');
  //return image with added bands
  return image
    //add NDVI band
    .addBands(image.normalizedDifference(['B5', 'B4']).rename('NDVI'))
    //add time band
    .addBands(ee.Image(years).rename('t'))
    .float()
    //add a constant band
    .addBands(ee.Image.constant(1));
};

//filter landsat8 data by county boundary, date, apply cloud mask, add variables
var NDVImap_may_2014 = (landsat
  .filterBounds(geometryexpl)
  .filterDate('2014-05-01', '2014-05-31')
  .map(maskL8sr)
  .map(addVariables));

var NDVImap_june_2014 = (landsat
  .filterBounds(geometryexpl)
  .filterDate('2014-06-01', '2014-06-30')
  .map(maskL8sr)
  .map(addVariables));  

//reduce collection to one image using median of the rasters
var NDVI_may_2014 = NDVImap_may_2014.reduce(ee.Reducer.median());
var may_2014_NDVIbound = NDVI_may_2014.reduceRegions({
  collection: geometryexpl,
  reducer: ee.Reducer.median(),
  scale: 30
});

var NDVI_june_2014 = NDVImap_june_2014.reduce(ee.Reducer.median());
var june_2014_NDVIbound = NDVI_june_2014.reduceRegions({
  collection: geometryexpl,
  reducer: ee.Reducer.median(),
  scale: 30
});

var collection_2014_median = ee.ImageCollection.fromImages(
  [ee.Image(NDVI_may_2014), ee.Image(NDVI_june_2014)]);

var max_2014 = collection_2014_median.reduce(ee.Reducer.max());
var max_2014_bound = max_2014.reduceRegions({
  collection: geometryexpl,
  reducer: ee.Reducer.max(),
  scale: 30
});

var palettes = require('users/gena/packages:palettes');
print(palettes, 'palettes');
var palette_ndvi = palettes.colorbrewer.BuGn[5];

var ndviParams = {min: -1, max: 1, palette: palette_ndvi};

Map.addLayer(max_2014.select('NDVI_median_max').clip(geometryexpl), ndviParams, 'NDVI');

var chart = ui.Chart.image.series(
  collection_2014_median.select('NDVI_median'), 
  geometryexpl, 
  ee.Reducer.mean(), // default 
  400, // nominal scale Landsat imagery 
  'system:time_start')
    .setOptions({title: 'NDVI 1Year Time Series',
                 vAxis: {title: 'NDVI'}, });

print(chart);

2voto

Lunar Mushrooms Puntos 123

Esto ya funciona: https://code.earthengine.google.com/256b9a98c0f280e703fa5ad03a6dacf0

Es necesario copiar las propiedades en cada función, en segundo lugar cuando se reduce a la mediana se pierden los datos de la hora del sistema. Por lo tanto, puede manualmente mediante la definición de la fecha var may_date = ee.Date('2014-05-01') y luego usar .set({'system:time_start': may_date}) en el extremo del reductor. Tal que así:

var may_date = ee.Date('2014-05-01')

//reduce collection to one image using median of the rasters

var NDVI_may_2014 = NDVImap_may_2014.reduce(ee.Reducer.median()).set({'system:time_start': may_date});

No parece que esté utilizando el NDVIbound_may_2014, sin embargo, si lo hace, tendrá que establecer la hora de inicio del sistema como se indica más arriba.

Por el aspecto de tu código lo estás haciendo manualmente para cada mes, yo buscaría crear funciones para hacer esto. Yo empezaría por aquí: https://developers.google.com/earth-engine/guides/ic_iterating Sólo una sugerencia

0 votos

Ya está, muchas gracias. Sí tengo la intención de crear un código más elegante por funciones, quería ver si todo tiene sentido en primer lugar

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X