datetimetime-seriesgoogle-earth-engineexport-csvlandsat

How to export a csv file from Google Earth Engine with attribute data and associated dates in a user defined date format?


Good Day

I am trying to generate an Enhanced Vegetation Index (EVI) in Google Earth Engine using Landsat 7 and 8 data. I have compiled the code below to filter the image collections, for a specific time period and region of interest, as well as to mask out a majority of the cloud cover in the images. I have then proceeded to calculate the EVI and add these values to the image collections as an attribute that I can select for further processing. I have undertaken this process separately for Landsat 7 and Landsat 8. However, since I am interested in the EVI that is generated from both these data sets I have merged these into one image collection.

Using this image collection, I would like to calculate the mean EVI value for a particular region of interest and then export these values along with the associated date (in the format dd-mm-yyyy) as a ".csv" file. I am aware that this is possible by clicking on the chart that is generated and downloading the associated ".csv" file or by exporting the data using the "Export.table.toDrive" function. However, none of these options provide the output in the structure as shown in the table below.

enter image description here

A sample of the code is provided here. Any assistance with this will be greatly appreciated. Kind Regards.

/// Add region of interest
var ROI = ee.FeatureCollection("users/shaedengokool/Eben_Sluis_15YO")
Map.addLayer(ROI, {}, 'ROI')
Map.centerObject(ROI, 10)

//1. Import the Landsat 8 TOA image collection.
var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
              .filterDate('2002-01-01','2020-01-01')
              .filterBounds(ROI)
              .map(function(image){return image.clip(ROI)})
              
var L8cloudlessEVI = l8.map(function(image) {
  // Get a cloud score in [0, 100].
  var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');

  // Create a mask of cloudy pixels from an arbitrary threshold.
  var mask = cloud.lte(10);

  // Compute EVI.
  var evi = image.expression(
    '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
      'NIR': image.select('B5'),
      'RED': image.select('B4'),
      'BLUE': image.select('B2')
}).rename('EVI');

  // Return the masked image with an EVI band.
  return image.addBands(evi).updateMask(mask);
});

var L8EVI_collection = L8cloudlessEVI

//2. Import the Landsat 7 TOA image collection.
var l7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_TOA')
              .filterDate('2002-01-01','2020-01-01')
              .filterBounds(ROI)
              .map(function(image){return image.clip(ROI)})

var L7cloudlessEVI = l7.map(function(image) {
  // Get a cloud score in [0, 100].
  var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');

  // Create a mask of cloudy pixels from an arbitrary threshold.
  var mask = cloud.lte(10);

  // Compute EVI.
  var evi = image.expression(
    '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
      'NIR': image.select('B4'),
      'RED': image.select('B3'),
      'BLUE': image.select('B1')
}).rename('EVI');

  // Return the masked image with an EVI band.
  return image.addBands(evi).updateMask(mask);
});

var L7EVI_collection = L7cloudlessEVI

var merged = ee.ImageCollection(L7EVI_collection.merge(L8EVI_collection));
print(merged, 'Merged')

var chart = ui.Chart.image.series({
    imageCollection: merged.select('EVI'),
    region: ROI,
    reducer: ee.Reducer.mean(),
    scale: 30,
})

print(chart, "EVI")

// get the mean value for the region from each image
var meanEVI = merged.map(function(image){
  var date = image.get('system:time_start');
  var mean = image.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: ROI,
    scale: 30
  });
  // and return a feature with 'null' geometry with properties (dictionary)  
  return ee.Feature(null, {'mean': mean.get('EVI'),
                            'date': date})
});

// Export a .csv table of date, mean NDVI for watershed
Export.table.toDrive({
  collection: meanEVI,
  description: 'EVI_Timeseries',
  folder: 'Genus_Exchange_GEE_Data',
  fileFormat: 'CSV',
})

;


Solution

  • In the code below I've added a date as an image property and exported it to a CSV. I also rearranged some of the code to decrease the computational time.

    Here is the code:

    var roi = ee.FeatureCollection("users/shaedengokool/Eben_Sluis_15YO")
    
    // Define time of interest
    var startdate = '2019-06-01' // insert
    var enddate = '2020-06-01' // insert
    
    var years = ee.List.sequence(ee.Date(startdate).get('year'), ee.Date(enddate).get('year'));
    
    /// EVI calculations from Landsat
    
    // This function masks clouds in Landsat 8 imagery.
    function maskL8(im) {
      var qa = im.select('BQA');
      var mask = qa.eq(2720);
      return im.updateMask(mask).copyProperties(im);
    }
    // This function masks clouds in Landsat 7 imagery.
    function maskL7(im) {
      var qa = im.select('BQA');
      var mask = qa.eq(672);
      return im.updateMask(mask).copyProperties(im);
    }
    // see: https://landsat.usgs.gov/sites/default/files/documents/landsat_QA_tools_userguide.pdf
    
    var ls8toa = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
    .filterBounds(roi)
      .filterDate(startdate, enddate)
        .map(function(im) {return maskL8(im)})
    
    var ls7toa = ee.ImageCollection('LANDSAT/LE07/C01/T1_TOA').filterBounds(roi).filterDate(startdate, enddate)
    .map(function(im) {return maskL7(im)})
        
    var ls7_evi = ls7toa.map(function(image) {
      var evi = image.expression(
        '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
          'NIR': image.select('B4'),
          'RED': image.select('B3'),
          'BLUE': image.select('B1')
    }).rename('EVI')
    return image.addBands(evi)
    })
    
    var ls8_evi = ls8toa.map(function(image) {
      var evi = image.expression(
        '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
          'NIR': image.select('B5'),
          'RED': image.select('B4'),
          'BLUE': image.select('B2')
    }).rename('EVI')
    return image.addBands(evi)
    })
    
    var landsat = ee.ImageCollection(ls7_evi.merge(ls8_evi));
    var EVI = landsat.select(['EVI'])
    print(EVI, 'EVI')
    
    //create function to calculate mean values for each polygon
    var pointsmean = function(image) {
      var means = image.reduceRegions({
        collection: roi, // used to be roi.select(['Id'])
        reducer: ee.Reducer.mean(),
        scale: 30
      })
      
      // assign time for every feature
      means = means.map(function(f) { return f.set({date: image.date().format("YYYY-MM-dd")}) })
      
      return means.copyProperties(image)
    };
    
    var finalEVI = EVI.map(pointsmean).flatten()
    .sort('date', false)
    .select(['date', 'mean'])
    print(finalEVI.limit(100), 'final EVI')
    
    Export.table.toDrive({
    collection: finalEVI,
      description: 'EVI_'+startdate+'TO'+enddate,
    fileFormat: 'CSV'
    });