Lazaros Stam
Lazaros Stam

Reputation: 25

Find closest date in list to date of interest with google earth engine

I have created a list of Sentinel 2 images. I have also extracted the date value from the DATATAKE_IDENTIFIER field and pasted it back as a property named "DATE" of ee.Date type for every image of my list. Now i am trying to retrieve the image which is chronologically closest to a date of interest specified by the user.For example if i have dates for: 5-May, 10-May, 15-May, 20-May and the user chooses 14th-May i want to return 15-May. Can someone please help? Here is my code:

var startDate = ee.Date('2017-07-01');
var finishDate = ee.Date('2017-07-31');

//Create imageCollection with the sentinel2 data and the date filters
var interestImageCollection = ee.ImageCollection(sentinel2_1C_ImageCollection)
.filterBounds(interestRectangle) //changed here your geometrical shape
.filterDate(startDate, finishDate)
.sort('CLOUDY_PIXEL_PERCENTAGE', false);



  //function which will extract the date from the 'DATATAKE_IDENTIFIER' field and add it as a new one to every image
var add_date = function(interestImageCollection){

  //iterate over the image Collection
  //.map must always return something
  return interestImageCollection.map(function(image){
    //take the image property containing the date
    var identifier = ee.String(image.get('DATATAKE_IDENTIFIER'));
    //regex
    var splitOn = "_|T";
    //split
    var splitted = identifier.split(splitOn,"");
    var date = ee.String(splitted.get(1));

    //DATE OPTION
    var year = ee.Number.parse(date.slice(0,4));   
    var month = ee.Number.parse(date.slice(4,6));
    var day = ee.Number.parse(date.slice(6,8));

    var dateTaken = ee.Date.fromYMD(year, month, day);

   return image.set('DATE',dateTaken);
  });
};

//list conversion
var subList = interestImageCollection.toList(interestImageCollection.size());

//get the image with the chronologically closest date to my date of interest
var dateOfInterest = ee.Date('2017-07-10');

//failed attempt to use sort for difference in dates calculation and get the closest date
    var c = subList.sort(function(a, b){
          var distancea = dateOfInterest.difference(a.get['DATE'],'day').round().abs();
          var distanceb = dateOfInterest.difference(b.get['DATE'],'day').round().abs();
          return distancea - distanceb; // sort a before b when the distance is smaller
        }).first();

For programming languages i would use a loop which at every iteration would check if the difference between my desired date and the retrieved date is lower than any previous value and update some temporal variables. But i think that earth engine has a more automated way to do that.

I also tried to use the sort function with a custom comparator but that did not work as well.

Also some regular javascript (like closestTo) functions seem to not be working in earth engine.

Upvotes: 1

Views: 2844

Answers (1)

Nishanta Khanal
Nishanta Khanal

Reputation: 334

I think there is a much shorter and easier solution to this. Each image should have a property named system:time_start that we can use can use to our advantage. Since we know our date, we can add a new property to our images that signify distance to our required date in terms of milliseconds as we can just treat it as numeric operation that going through all the day month considerations that come with YMD format.

ic = ic.map(function(image){
  return image.set(
    'dateDist',
    ee.Number(image.get('system:time_start')).subtract(dateOfInterest.millis()).abs()
  );
});

This new field 'dateDist' can now be used to sort the image collection.

ic = ic.sort('dateDist');

The default way of sorting is ascending so this should be good. And you can get the closest scene by taking the first image. One thing to consider is that if your ROI rectangle covers enough area to look at multiple row/path then there might be multiple scenes with closest dates. In such case it might be good idea to inspect how many scenes fall within same date range.

Upvotes: 3

Related Questions