1

I am quite new to GEE and trying to extract the NDVI value for a set of GPS points (X, Y, and date). I have constructed my NDVI layer and am able to obtain NDVI values for my points, however the date associated with the NDVI values I extract do not correspond to the date my GPS point was obtained. In other words, I am looking to obtain the NDVI value from the date my GPS point was transmitted (or the closest date). In my GPS featureCollection I have a column 'fixtimes' formatted in dd-mm-yyyy hh:mm:ss that corresponds to the time the GPS point was transmitted.

I've attached the code I have used so far below. I suspect I will need to modify the 'date' function but am not entirely sure how.

/////////////////////////////
//// Obtain NDVI layer //////
/////////////////////////////
var filtered = L8.filterDate('2017-01-01', '2021-06-01').filterBounds(pts);
var rgb_vis = {min:0, max: 0.3, bands:['B4', 'B3', 'B2']};
var image = ee.Image(filtered.first());

function addNDVI(image) {
  var ndvi = image.normalizedDifference(['B5', 'B4']);
  return image.addBands(ndvi)
}
var NDVI = addNDVI(image);
var with_ndvi = filtered.map(addNDVI);
Map.addLayer(filtered, rgb_vis, 'RGB');
Map.addLayer(NDVI, {bands: 'nd', min:0, max:1}, 'NDVI');
Map.addLayer(with_ndvi, {bands: 'nd', min:0, max:1}, 'withNDVI');

///// Function to add NDVI to GPS points /////
    var ft = ee.FeatureCollection(ee.List([]));
    var fill = function(img, ini) {
      var inift = ee.FeatureCollection(ini)
      var ft2 = img.reduceRegions(pts, ee.Reducer.first(), 30)
      var date = img.date().format()
      var ft3 = ft2.map(function(f){return f.set("date", date)})
      return inift.merge(ft3)
    };
    var newft=ee.FeatureCollection(with_ndvi.iterate(fill, ft));
    print(newft.first());

Output (redacted due to sensitive data) :

geometry with coordinates X and Y

properties: fixtime = 13/11/2020 ndvi band = 0.715 date = 2017-02-20 T07:40:30

I would like to get fixtime and date to correspond - and obtain the correct NDVI value for that date.

2 Answers 2

0

You could do that by mapping a function that takes each Feature in your FeatureCollection and filters the ImageCollection according to the date contained in its "fixtimes" field. You will need to parse the date in the "fixtimes" string as date (check this link to understand the used notation: http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html). The only issue is that you will need to define the time window that you can consider as closest to that date. In this example I chose 1 week before and after of the "fixtime" date, but you can adjust it to your needs.

// Use the pts date field to filter the image collection
// and then extract the image values of the filtered image
var extractpts = pts.map(function(feat){
  // Get date from each pts feature
  var date = feat.get('fixtimes');
  // Convert it to date format, indicating the format
  date = ee.Date.parse('d/M/y H:m',date);
  
  // Create range to filter image, e.g, one week before or after
  var start = date.advance(-1, 'week');
  var end = date.advance(1, 'week');
  
  // Filter using the date ranges and get first image
  var filtIm = filtered.filterDate(start, end)
                       .first();

  // Sample image info using the feature                     
  var extract = filtIm.sample({
    region: feat.geometry(),
    scale: 30
  });
  
  return extract;
});

// Flatten FeatureCollections into a single FeatureCollection
extractpts = extractpts.flatten();
print(extractpts);

// Export
Export.table.toDrive({
  collection: extractpts,
  description: 'StackOverflowQ',
  fileFormat: 'CSV'
});
10
  • Hi Jonathan - thank you so much, that sounds like what I need. I tried running the code but I get the following error : FeatureCollection (Error) Error in map(ID=00000000000000000757): Date.parse: Date/time '13/11/2020 05:55' cannot be parsed with format 'dd/mm/yyyy hh:mm:ss'. I tried changing the date format to no avail Do you have any idea what might be going on? (Sorry very new to this)
    – EmmaE
    Jul 13, 2021 at 15:15
  • Hmmm, it is difficult to tell without seeing the actual script. Try sharing a link to your code using the Get Link button in the API and posting it here. Jul 13, 2021 at 15:20
  • code.earthengine.google.com/1b3a6b855d4e41a90b7bebcad05bb036 I have tried removing :ss but that does not seem to solve the problem - thank you for having a look
    – EmmaE
    Jul 13, 2021 at 15:23
  • Could you also set the "pts" asset as public? Jul 13, 2021 at 15:29
  • I'm afraid the data set contains sensitive locations - but I can quickly upload a subset of points that I can make public. I managed to get rid of the Date.parse error but now I'm left with the following: FeatureCollection (Error) Error in map(ID=00000000000000000b80): Image.sample: Parameter 'image' is required. Will make a subset of pts public now
    – EmmaE
    Jul 13, 2021 at 15:33
0

How exact do you want the date to be? You likely won't be able to get a Landsat image for your exact day, and even if you do it might be cloudy which will mess up your NDVI.

You can get the GPS point date and then use ee.Date.parse to create a date object, then use that in filterDate to get a Landsat image.

var fixtime = ee.String("12-05-2020") //I made this date up, you might have to 
                                      //map through your GPS feature collection to get dates

var dateParse = ee.Date.parse("dd-MM-yyyy", fixtime)

//returns a ee.Date object, formatted as: "2020-05-12"

Are your GPS points from different days, or the same day? If they're the same (or within a short range), just input that date in your filterbounds for the L8 image. Likely, you'll have to create a range of a month or so to get a good image, but that's better than the multi-year range there now. You can do this quickly with getRange():

var dateRange = dateParse.getRange("month") //creates a dateRange spanning the
                                            // month that your date is in, 
                                            //i.e. for my example: [2020-05-01, 2020-06-01]

I'd also recommend adding .sort("CLOUD_COVER") before selecting an image with .first(), as this will give you a better chance of getting a cloudless image.

1
  • Hi - thank you so much for your answer! I have over 100 000 different GPS points spanning over the years I set as my filter bounds. I do understand it might not be possible to get an NDVI value for that exact date - but that's fine, I'm just looking for the closest possible NDVI value to my fixtime (which is a column in my GPS point asset) .
    – EmmaE
    Jul 13, 2021 at 14:55

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.