I am developing a yearly NDVI trend analysis using Landsat data in Earth Engine over the last decades. My process is to add a NDVI band to every scene for each summer (green) month, then to reduce the collection by median to one image per month and finally to reduce all monthly images by max to generate one image for one year. My plan is to create a time series to see the positive/negative trends of NDVI over the years, but somewhere along the way the system:time_start
property gets lost while reducing the images. I want to generate a chart but I always end up with: Error generating chart: No features contain non-null values of "system:time_start".
I know you can copyProperties(image, ['system:time_start'])
but I cannot find out where and how.
To reduce the length of the code, I cut it to two months:
//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 1‐Year Time Series',
vAxis: {title: 'NDVI'}, });
print(chart);