1

Context

I am using the MODIS layer. I divide the layer into classification bins and would like to assess change between two consecutive years (e.g., year 2005 to year 2006) for the years 2000 to 2020 (see Filter pixel values from a list in every Image in an ImageCollection in Google Earth Engine).

Question

How can I map over an image collection, selecting bands of different (adjacent) images in that collection?

What I tried

I wrote a function calcLUC which I am trying to map over an image collection, but cannot wrap my head around that.

// Load MODIS layer    
modisLandCover = ee.ImageCollection("MODIS/061/MCD12Q1");
// select 'LC_Type1' band
var LCType1 = modisLandCover.select('LC_Type1');

// reclassify values to have only 3 bins
var reclass_function = function(image) {
  // Select band and reclassify
  var LC_Type1 = image.select('LC_Type1');
  var type1bins = LC_Type1
    .where(LC_Type1.lt(12), 1) // Forest
    .where(LC_Type1.gte(12), 2) // Cropland
    .where(LC_Type1.gt(14), 3); // Other
  return image.addBands(type1bins.rename('bin')); // Add new band with the tree bins
};

var reclassified = LCType1.map(reclass_function);
print('reclassified', reclassified)

// Filter consecutive years
var calcLUC = function(img, y1) {
    var y1_classificaiton = img.filter(ee.Filter.calendarRange(y1, y1, 'year')).first().select('bin');
    var y2_classification = img.filter(ee.Filter.calendarRange(y1+1, y1+1, 'year')).first().select('bin');
    return y1_classificaiton.eq(1).and(y2_classification.eq(2))
}

// use the function calcLUC to map over image collection
// ...

I also tried to copy the image collection (IC), resulting in IC1 and IC2, then deleting the first year from IC1 and last year from IC2, combining the two with IC1.combine(IC2), but the combination seems to follow an inner join based on the meta properties of the IC (so I cannot combine the year 2005 of IC1 with the year 2006 of IC2 as bands within the same image). However, in this format, where the same image has a band of year i and one of year i+1, I could map over that image collection.

2
  • This answer might be useful. It shows hot to map over a collection based on its date: gis.stackexchange.com/a/402218/156904 Commented Jan 13, 2023 at 15:48
  • Thanks Jonathan. I opted for another solution for now (see answer below) but will keep this in mind.
    – Thierry
    Commented Jan 15, 2023 at 14:23

2 Answers 2

0

I don't get where HCS comes from, but if you want to filter by years, use the following approach:

var months = ee.List.sequence(1, 19).map(function(n) {
  var start = ee.Date('2000-01-01').advance(n, 'year');
  var end = start.advance(2, 'year');
  return reclassified.filterDate(start, end);
});

print(months.get(0));
// type: ImageCollection
// id: MODIS/061/MCD12Q1
// version: 1669290141970467
// bands: []
// features: List (2 elements)
// properties: Object (1 property)
1
  • Thanks aldo_tapia, I edited the question accordingly. My challenge is that I would like to do calculations on image 1 band 1 and image 2 band 1 of the image collection, and apply the calcLUC function to those bands via mapping.
    – Thierry
    Commented Jan 13, 2023 at 13:43
0

I found an answer here: Calculate difference of subsequent images in a collection. This solution does not consider the dates itself but works with slicing a list and zipping it. The code works for my case, but the other answers to this question should be considered if considering the dates is important.

Code

var imageNames = reclassified.sort('system:time_start').toList(reclassified.size())

var LUC = imageNames.slice(0,-1)
// see https://gis.stackexchange.com/questions/300473/calculate-difference-of-subsequent-images-in-a-collection
  .zip(imageNames.slice(1))
  .map(function(f) {
    var y1_classification = ee.Image(ee.List(f).get(0)).select('bin');
    var y2_classification = ee.Image(ee.List(f).get(1)).select('bin');
    return y1_classification.eq(1).and(y2_classification.eq(2));
   });

Explanation

The code starts from the reclassified image (see steps before that in the question)

  1. imageNames are the names of the images within the reclassified image collection, with reclassified land cover (LC) values [y1_LC, ..., y21_LC]]
  2. imageNames.slice(0, -1) returns [y1_LC, ..., y20_LC]
  3. imageNames.slice(1) returns [y2_LC, ..., y21_LC]
  4. zipping 2. and 3. together returns a list of lists: [[y1_LC, y2_LC], ..., [y20LC, y21LC]
  5. .map() over the lists of lists by getting the first and second element (e.g. y1_LC and y2_LC) of the nested list and select pixels of interest
  6. Returns a list of images with one band each of the selected pixels

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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