0

I am trying to figure out when an image (or observation in general) was uploaded to Earth Engine. I have a script that gives me the most recent image date, but as far as I can see this refers specifically to the image acquisition date (i.e. as seen in system:index: and system:time_start[end]:).

Ultimately, I'd like to take an image collection (e.g. Sentinel 2 TOA over 6 months) and determine both the mean time between images plus the average time difference between the image acquisition itself and the processed image uploaded to GEE.

I've checked on answers at Earth Engine get latest image from an imageCollection and linked below.

Here is a sample script, with the function coming from Get all dates of image collection when it was created/loaded on sentinel 2 dataset. The list of satellites is the full list I eventually want to run these statistics on.

var pt = ee.Geometry.Point([95.219623, 23.029892]).buffer(300000)

var sat =
  ["COPERNICUS/S1_GRD",         //sentinel 1 SAR-GRD cband (2014-10-03) 4825 features
    "COPERNICUS/S2",            //sentinel 2 TOA Level 1C (2015-06-23) 7425 features
    "COPERNICUS/S2_SR",         //sentinel2 SR Level 2A (2017-03-28) 2810 features
    "LANDSAT/LC08/C01/T1_TOA",  //landsat8 TOA (April 2013) 2324 features
    "LANDSAT/LC08/C01/T1_SR",   //landsat8 SR (April 2013) 2324 features
    "MODIS/006/MOD09GQ",        //modis 250m (2000-02-24) 33420 features
    "MODIS/006/MOD09GA"         //modis 500m (2000-02-24) 33400 features aka rows in table
];

var coll = ee.ImageCollection(sat[1])
.filterDate('2020-10-01', '2020-10-31')
.filterBounds(pt)
print('sample image', coll.first())

var get_dates = function(collection, month, year) {
  var filtered = collection.filter(ee.Filter.calendarRange(year, year, 'year'))
                           .filter(ee.Filter.calendarRange(month, month, 'month'))

  return ee.List(filtered.toList(filtered.size()).map(function(img){
    return ee.Image(img).date().format('YYYY-MM-dd')
  }))
}

var dates = get_dates(coll, 10, 2020).distinct();
var num = dates.size();
print(dates)
print('Max date from image.date()', dates.get(num.subtract(1)))

print('current date time', ee.Date(Date.now()))
0

I have found the answer after playing around a bit more, plus with help from Simon on the GEE Developers page Ingestion datetime for landsat scenes (see post from 6 Nov. 2020). He mentioned that the current ingestion delay from when USGS/ESA posts images and when they're uploaded to GEE is the following:

  • Landsat: ~18h
  • Sentinel-1: ~36h
  • Sentinel-2 L1: ~12h
  • Sentinel-2 L2: ~18h

This alone answers the broad aspect of my question, but I also got the GEE script to report this and the other metrics I specified from my question in the console. One thing to consider in this script (as illuminated by Simon in the linked website above) is that for L8 ingestion time I use the last date in the full product id, then add 24 hours to ensure I've captured the average ingestion time.

The script here will report the wanted parameters for a specified point, satellite sensor, and date timeframe. The .multiply(1000) is to have a common time in microseconds.

//---------------------------------------------------------------------------//
// Step 1: Define functions
//---------------------------------------------------------------------------//
// get specific ImageCollection and filter
var getImgColl = function(i, focalPoint, dateStart, dateEnd){
  return ee.ImageCollection(sat[i])
  .filterDate(dateStart, dateEnd)
  .filterBounds(pt);
};

// get dates from IC into list
var get_dates = function(collection) {
  return ee.List(collection.toList(collection.size()).map(function(img){
    return ee.Image(img).date().format('YYYY-MM-dd');
  }));
};

// time conversions
var microSecToHour = function(aNum){
    return aNum.multiply(ee.Number(2.77778).multiply(ee.Number(10).pow(-10)));
};
  
var microSecToDays = function(aNum){
  return aNum.multiply(ee.Number(1.15741).multiply(ee.Number(10).pow(-11)));
};

// full time difference retrieval function
var getDates = function(collection, list_of_dates, satellite){
  var findDates = function(x){
    var l8 = i == 3 || x == 4; print('is l8?', l8);
    
    //We look at an image and its previous one for comparison. This way,
    //in a collection we have a value for every image save for the first.
    var origDate = ee.Date(ee.Date(list_of_dates.get(ee.Number(x))).format('YYYY-MM-dd'));
    var origImg = collection.filterDate(origDate, origDate.advance(1, "day")).first();
  
    var prevDate = ee.Date(ee.Date(list_of_dates.get(ee.Number(x).subtract(1))).format('YYYY-MM-dd'));
    var prevImg = collection.filterDate(prevDate, prevDate.advance(1, "day")).first();
  
    // L8 has a different variable for ingestion time, so it needs its own
    // function and if statement
    var l8Calc = function(str){
      var stringNum = ee.String(str).rindex('2020');
      var dateTest = ee.String(str).slice(stringNum, stringNum.add(8));
      var finalDate = ee.Date.parse('YYYYMMdd', dateTest)
      .advance(1, 'day').millis().multiply(1000);
      return finalDate;
    };
    
    var origIngest = ee.Algorithms.If(l8,
    l8Calc(origImg.get('LANDSAT_PRODUCT_ID')),
    ee.Number(origImg.get('system:version'))); 
    
    var prevIngest = ee.Algorithms.If(l8,
    l8Calc(prevImg.get('LANDSAT_PRODUCT_ID')),
    ee.Number(prevImg.get('system:version')));
  
    var origObserve = ee.Number(origImg.get('system:time_end')).multiply(1000);
    var prevObserve = ee.Number(prevImg.get('system:time_end')).multiply(1000); 

    // difference in time btwn observation and ingestion (hours)
    var time_diffHour = microSecToHour(ee.Number(origIngest).subtract(origObserve));
  
   // difference in time between first and next image observation (days)
   var time_diffObs = microSecToDays(origObserve.subtract(prevObserve));
  
   // difference btwn this and previous image ingestion (days)
   var time_diffIng = microSecToDays(ee.Number(origIngest).subtract(prevIngest));
  
   var output = ee.Feature(pt,
   {date: origDate, obsToIngHours: time_diffHour, obsDiffDays: time_diffObs,
      ingDiffDays: time_diffIng
    });
    return output;
  };
  return findDates;
};

//---------------------------------------------------------------------------//
// Step 2. Define the necessary variables (pt, i, and dates)
//---------------------------------------------------------------------------//

// define initial variables
var pt = ee.Geometry.Point([95.219623, 23.029892]).buffer(10);
//var pt = ee.Geometry.Point([-78.664414, 35.769955]).buffer(10);
var i = 3;
var date_start = '2020-02-20';
var date_end = '2020-10-20';

var sat =
  ["COPERNICUS/S1_GRD",         //sentinel 1 SAR-GRD cband (2014-10-03) >4800 features
    "COPERNICUS/S2",            //sentinel 2 TOA Level 1C (2015-06-23) >7400 features
    "COPERNICUS/S2_SR",         //sentinel2 SR Level 2A (2017-03-28) >2800 features
    "LANDSAT/LC08/C01/T1_TOA",  //landsat8 TOA (April 2013) >2300 features
    "LANDSAT/LC08/C01/T1_SR",   //landsat8 SR (April 2013) >2300 features
    "MODIS/006/MOD09GQ",        //modis 250m (2000-02-24) >33000 features
    "MODIS/006/MOD09GA"         //modis 500m (2000-02-24) >33000 features
];

//---------------------------------------------------------------------------//
// Step 3: Run the functions (results are in the properties)
//          `numList` is defined in order to focus on images in the collection
//          except for the first.
//---------------------------------------------------------------------------//
var coll = getImgColl(i, pt, date_start, date_end);
//print(coll);
var dateList = get_dates(coll).distinct().sort();
var numList = ee.List.sequence(1, ee.Number(dateList.size().subtract(1)));
print('dates', dateList);
print('numList', numList);

var testFull = numList.map(getDates(coll, dateList));
var testFullFC = ee.FeatureCollection(testFull);
print('output FeatureColl', testFullFC);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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