0

I built a function landcov(area, date) to calculate the share of land types 0 to 3 in year "date" from MODIS12Q1 within the polygons of the "area" parameter. I want to use iterate() in a loop-like fashion to do that for many "date" parameter values. The function is set as

var landcov = function(area, date) {
  // loading MODIS and filetring ICGB classification:
  var feature = ee.Image("MODIS/006/MCD12Q1/" + date).select(['LC_Type1']);
  // first feature with class==0:
  var l = ee.List.sequence(0,17);
  var feat = feature.remap(l, ee.List.repeat(0,17).insert(0,1));

  // adding subsequent layers (impossible to loop it :/):
  var feat = feat.addBands(feature.remap(l, ee.List.repeat(0,17).insert(1,1)));
  var feat = feat.addBands(feature.remap(l, ee.List.repeat(0,17).insert(2,1)));
  var feat = feat.addBands(feature.remap(l, ee.List.repeat(0,17).insert(3,1)));

  // Map land cover area per polygon (zonal stats):
  var feat = feat.reduceRegions({
    collection: area,
    reducer: ee.Reducer.mean(),
    scale: feat.projection().nominalScale(),
  });

  var feat = feat.map(function(ft){
    return ee.Feature(ft).set('date', date)
  });

  // exporting it to .csv:
  Export.table.toDrive({
    collection: feat,
    description: "land_cover_" + date,
    fileFormat: 'CSV'
  });

}

Now, suppose I want to do that function for 2001 to 2003 for the polygon called aoi. The only way I found is to run:

// load "aoi":
var aoi = ee.FeatureCollection('ft:1S4EB6319wWW2sWQDPhDvmSBIVrD3iEmCLYB7nMM').filter(ee.Filter.eq('StateName', 'Maine')).select(['CntyFips']);

landcov(aoi, '2001_01_01');
landcov(aoi, '2002_01_01');
landcov(aoi, '2003_01_01');

How would one loop over a sequence '2001_01_01' to '2003_01_01'?

  • I think this could be easily accomplished by mapping over the MODIS collection. However, I do not get what results you actually want. What would you like to have returned from this function? What is meant by 'calculating the share of land types'? – Kuik Dec 22 '18 at 16:52
0

Your biggest problem is that you're mixing server-side and client-side logic. For instance, you shouldn't be using "+" anywhere. Other things you shouldn't do:

  • don't construct the image ID as a string, filter the collection instead. Better yet, map over the collection directly, then you don't have to manually deal with dates at all.
  • use promotion to split the image into 1 band per landcover class instead of trying to iterate or enumerate the classes.
  • Don't do the export inside the function; return the collection(s) and export them all at once (but you'll need to flatten them).

Something like this:

var percentage = function(image) {
  // Get a 0/1 mask for each landcover type.
  var areas = image.select(['LC_Type1'])
    .eq([0, 1, 2, 3])
    .rename(["type0", "type1", "type2", "type3"])
    .reduceRegions({
        collection: aoi,
        reducer: ee.Reducer.mean(),
        crs: image.projection()
  }).map(function(ft) {
    return ee.Feature(ft).set('date', image.date().format('YYYY-MM-dd'))
  });
  return areas
}

var aoi = ee.FeatureCollection('ft:1S4EB6319wWW2sWQDPhDvmSBIVrD3iEmCLYB7nMM')
   .filter(ee.Filter.eq('StateName', 'Maine'))
   .select(['CntyFips']);

var result = ee.ImageCollection("MODIS/006/MCD12Q1").map(percentage).flatten()    
Export.table.toDrive({
    collection: result,
    description: "land_cover_percentages",
    fileFormat: 'CSV'
});

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.