0

Reference is to a tread I posed years ago and was solved Extract pixel values from several bands of an image and export in a single table in Google Earth Engine The challenge now is to create S2 NDVI time series for each point location of a feature collection.

var listOfFeatures = [
  ee.Feature(ee.Geometry.Point(-62.54, -27.32), {key: 'val1'}),
  ee.Feature(ee.Geometry.Point(-69.18, -10.64), {key: 'val2'}),
  ee.Feature(ee.Geometry.Point(-45.98, -18.09), {key: 'val3'})
];
var listOfFeaturesFc = ee.FeatureCollection(listOfFeatures);
print('FeatureCollection from a list of features', listOfFeaturesFc);

var startDate = '2019-03-29'; // initial date of the image collection
var endDate = '2019-05-05'; //final date of the image collection

//Mask clouds
function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

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


// Function to calculate and add an NDVI band
var addNDVI = function(image) {
  var ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI');
  return image.addBands(ndvi);
};

// Download the Sentinel-2 imagery collection
var sentinel2 = ee.ImageCollection('COPERNICUS/S2')
    .filterDate(startDate, endDate)
    .filterBounds(listOfFeatures)
    .map(maskS2clouds)
    .map(addNDVI);

var NDVI = ee.ImageCollection(sentinel2)
              .select(['NDVI']);

var chart =
    ui.Chart.image
        .series({
          imageCollection: NDVI,
          region: listOfFeatures,
          reducer: ee.Reducer.mean(),
          scale: 10,
          
        })
        .setSeriesNames(['NDVI'])
        .setOptions({
          title: 'NDVI time series',
          hAxis: {title: 'Date', titleTextStyle: {italic: false, bold: true}},
          vAxis: {
            title: 'NDVI',
            titleTextStyle: {italic: false, bold: true}
          },
          lineWidth: 5,
          colors: ['e37d05', '1d6b99'],
          curveType: 'function'
        });
print(chart);

At this point I get the following error: No features contain non-null values of "system:time_start"

Moreover I would also like to export a table (.csv) that associate at each point name the NDVI values of the time range, and the dates as column names. I guess this can be exported directly from the chart window, but since I could not get there I do not whether something else is missing.

1 Answer 1

0

I found a partial solution to this, please see below the working code:

var listOfFeatures = [
  ee.Feature(ee.Geometry.Point(-62.54, -27.32), {key: 'val1'}),
  ee.Feature(ee.Geometry.Point(-69.18, -10.64), {key: 'val2'}),
  ee.Feature(ee.Geometry.Point(-45.98, -18.09), {key: 'val3'})
];
var listOfFeaturesFc = ee.FeatureCollection(listOfFeatures);
print('FeatureCollection from a list of features', listOfFeaturesFc);

var startdate = '2019-01-01';
var enddate = '2019-04-30';



function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

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

var addNDVI = function(image) {
  var ndvi = image.normalizedDifference(['B8','B4']).rename('NDVI');
  return image.addBands(ndvi);
};



var S2_NDVI = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate(startdate, enddate)
                  .filterBounds(listOfFeatures)
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20))
                  //.map(maskS2clouds)
                  .map(addNDVI)
                  .select('NDVI');

print (S2_NDVI);

var chart = ui.Chart.image.seriesByRegion({
  imageCollection: S2_NDVI,
  regions:listOfFeatures,
  reducer:ee.Reducer.mean(),
  scale:10,
  xProperty:'system:time_start',
  
})

As you can see I had to slash out the cloud masking at pixel level, since it was kind of reducing the collection to a single image, returning me the error: No features contain non-null values of "system:time_start" I partially overcome the problem by applying a filter for cloud coverage at scene level, but that is not optimal, since It does not exclude cloudy pixels from the time series. Do someone have suggestion for this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.