Skip to main content
5 of 7
added 151 characters in body

How to extract Landsat time series for multiple location

I want to extract Landsat time series for multiple locations. I refer to the code in this tutorial.The time I choose is from 2019-01-01 to 2019-12-30. The resulting time series should be multi-column,but I only got two columns of NDVI data,like this:enter image description here

This is the code

var points = table.map(function(feature) {
  return ee.Feature(feature.geometry(), {'id': feature.id()})
})

// Cloud masking *** from Example:"Landsat8 TOA Reflectance QA Band"
var maskL8 = function(image) {
  var qa = image.select('BQA');
  /// Check that the cloud bit is off.
  // See https://www.usgs.gov/land-resources/nli/landsat/landsat-collection-1-level-1-quality-assessment-band
  var mask = qa.bitwiseAnd(1 << 4).eq(0);
  return image.updateMask(mask);
}

// Adding a NDVI band
function addNDVI(image) {
  var ndvi = image.normalizedDifference(['B5', 'B4']).rename('ndvi')
  return image.addBands([ndvi])
}

var startDate = '2019-01-01'
var endDate = '2019-12-31'
var collection = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
              // ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
    .filterDate(startDate, endDate)
    // .map(maskL8sr)
    .map(maskL8)
    .map(addNDVI)
    .filter(ee.Filter.bounds(points))

// // Show the farm locations in green
Map.addLayer(points, {color: 'green'}, 'Farm Locations')

// handling masked pixels
var triplets = collection.map(function(image) {
  return image.select('ndvi').reduceRegions({
    collection: points, 
    reducer: ee.Reducer.first().setOutputs(['ndvi']), 
    scale: 10,
  })// reduceRegion doesn't return any output if the image doesn't intersect
    // with the point or if the image is masked out due to cloud
    // If there was no ndvi value found, we set the ndvi to a NoData value -9999
    .map(function(feature) {
    var ndvi = ee.List([feature.get('ndvi'), null])
      .reduce(ee.Reducer.firstNonNull())
    return feature.set({'ndvi': ndvi, 'imageID': image.id()})
    })
  }).flatten();
  
// Granules overlap
var format = function(table, rowId, colId) {
  var rows = table.distinct(rowId); 
  var joined = ee.Join.saveAll('matches').apply({
    primary: rows, 
    secondary: table, 
    condition: ee.Filter.equals({
      leftField: rowId, 
      rightField: rowId
    })
  });
        
  return joined.map(function(row) {
      var values = ee.List(row.get('matches'))
        .map(function(feature) {
          feature = ee.Feature(feature);
          return [feature.get(colId), feature.get('ndvi')];
        });
      return row.select([rowId]).set(ee.Dictionary(values.flatten()));
    });
};
var sentinelResults = format(triplets, 'id', 'imageID');
// There are multiple image granules for the same date processed from the same orbit
// Granules overlap with each other and since they are processed independently
// the pixel values can differ slightly. So the same pixel can have different NDVI 
// values for the same date from overlapping granules.
// So to simplify the output, we can merge observations for each day
// And take the max ndvi value from overlapping observations
var merge = function(table, rowId) {
  return table.map(function(feature) {
    var id = feature.get(rowId)
    var allKeys = feature.toDictionary().keys().remove(rowId)
    var substrKeys = ee.List(allKeys.map(function(val) { 
        return ee.String(val).slice(0,8)}
        ))
    var uniqueKeys = substrKeys.distinct()
    var pairs = uniqueKeys.map(function(key) {
      var matches = feature.toDictionary().select(allKeys.filter(ee.Filter.stringContains('item', key))).values()
      var val = matches.reduce(ee.Reducer.max())
      return [key, val]
    })
    return feature.select([rowId]).set(ee.Dictionary(pairs.flatten()))
  })
}
var sentinelMerged = merge(sentinelResults, 'id');

Export.table.toDrive({
    collection: sentinelMerged,
    description: 'landsat_Multiple_Locations_NDVI_time_series',
    folder: 'earthengine',
    fileNamePrefix: 'landsat_ndvi_time_series_multiple',
    fileFormat: 'CSV'
})

What went wrong? Please give me some advice.