2

I have 3 global images of land cover (300m spatial resolution). I simply want to clip each land cover image into 3 different regions (9 total). I also want to reclassify the images.

The way I would usually do it is to repeat the code per desired output using .clip(), .remap() and Export.image.toDrive(). To know exactly what I want to achieve, see Part 1; lines 1-90. However, I keep getting the error; "User memory limit exceeded." I am not sure why, maybe the region is too big?

Nonetheless, I now want to loop over the whole process to make the code more efficient. I attempt a "loop" in Part 2; lines 91-134. I insert the code for the loop here.

//  Load vector boundary
var pantropics = ee.FeatureCollection('users/jjohanness1992/ESA_Equatorial_Tropics/boundary_pantropics');

//  Define start and end value for vector layer attribute 'label'
var start_region = 1;
var end_region = 3;
//  label = 1 (Americas), label = 2 (Australasia), label = 3 (Africa)

//  Load images
var esa1995 = ee.Image('users/jjohanness1992/ESA_1992_to_2018/ESA1995');
var esa2000 = ee.Image('users/jjohanness1992/ESA_1992_to_2018/ESA2000');
var esa2005 = ee.Image('users/jjohanness1992/ESA_1992_to_2018/ESA2005');

//  Prepare image reclassification codes
var oldgroup = ee.List([0,10,11,12,20,30,40,50,60,61,62,70,71,72,80,81,82,90,100,110,120,121,122,130,140,150,151,152,153,160,170,180,190,200,201,202,210,220]);
var newgroup = ee.List([0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,5,5,5,5,6,6,6,7,8,8,8,9,10]);

//  Perform 'loop' operation
var i;
  for (i=0;i<=2;i++){
    var imagestack = ee.List([esa1995,esa2000,esa2005]);
    var year_dict = ee.Dictionary({
      '0':'1995',
      '1':'2000',
      '2':'2005'
    });
    var year_string = year_dict.get(ee.Number(i).format()).getInfo();
var j;
  for (j=start_region;j<=end_region;j++){
    var region = pantropics.filter(ee.Filter.eq('label', 'j'));
    var imagexregion = ee.Image(imagestack.get(i))
    .clip(region).remap(oldgroup,newgroup);
    var region_string = ee.Number(j).format().getInfo();
Export.image.toDrive({
  image:imagexregion.uint8(),
  description:'esa-'+region_string+'-'+year_string,
  folder:'esa-loop-test',
  region:region,
  scale:300,
  crs:'EPSG:4326',
  maxPixels:1e13,
  fileFormat:'GeoTIFF'});
  }
}

However, I cannot get my "loop" to run. After running the task in the 'Tasks' tab, it turns red after a ~30 seconds, with the following error message; "Error: Image.clipToBoundsAndScale: The geometry for image clipping must not be empty.". Please find my GEE script here.

I find this weird because firstly, I used .clip() not .clipToBoundsAndScale(). This is because I do not want the image to be clipped to the bounding box of the regions, I want them clipped to the exact region boundary. Secondly, this error message means that the regions are not identified, or are blank, which is why the clipping cannot be conducted. Unless .clip() is wrong and I should be using .clipToBoundsAndScale({geometry:region,scale:300}) instead.

Maybe I am wrongly using some functions in my code.

Edit:

The pantropics asset took up ~64 Mb in GEE space. I exported it to Google Drive to inspect it. The Shapefile is now ~124 Mb, and when previewed in QGIS, looks fine. The only difference is that previously, the Shapefile had only 3 dissolved regions for Americas, Africa and Australasia, but this export has 12 features in total. See picture for comparison (maybe the geographical region was too big, and GEE had to segment it into these 12 smaller subregions).

I re-ingest this new asset into GEE, and re-run the loop. Although the code looks like it runs, as tasks are being created in the Tasks tab, after some time, the browser crashes.

2 Answers 2

2

I think you may have a problem here:

var region = pantropics.filter(ee.Filter.eq('label', 'j'));

This line is not comparing your property value against the loop variable j but the literal text "j", which would explain the missing region.


By the way, it's not a problem, but this line can also be improved:

var region_string = ee.Number(j).format().getInfo();

This makes an unnecessary server call to format the number as a string and will slow down your script. You can replace it with the plain JavaScript

var region_string = String(j);
1
  • Thank you, I appreciate your suggestion because I was unaware that I was making unnecessary server calls. Will update the post after trying your recommendation.
    – Johanness
    Commented Mar 23, 2020 at 1:53
2

Based in your error message, I copied your script in my GEE code editor, changed your pantropics variable for an arbitrary geometry in my assets (in India) and, I also changed region in exporting routine to Drive (also for pantropics). This is the link to my script.

After running it, I ran one of tasks and result was successful after 43 seconds; as it can be observed in following image:

enter image description here

Afterward, I saw in my Google Drive and, effectively, exported image was right there. Geometry region created in your loop could be not valid.

Editing Note:

Definitively, there is an issue with the creation of geometries in the loop. With this new version of script, that uses your images, I got a result in *.tif images imported to Google Drive.

It can be observed in following image visualized in QGIS. It worked.

enter image description here

5
  • My guess is that you are right, for some reason the geometries I am using is invalid. But, I tested viewing the individual geometries separately (e.g. var australasia = pantropics.filter(ee.Filter.eq('label', 3));), and I was able to inspect them in the Map viewer. So, I am not really sure why it works outside of the loop but not inside it. Wondering if my approach is wrong, and i should try to use 'function's instead.
    – Johanness
    Commented Mar 22, 2020 at 15:37
  • Issue is related with creation of your geometries in the loop. With my region used in the loop it works without any problems.
    – xunilk
    Commented Mar 22, 2020 at 16:14
  • 1
    I tried to print in Console your feature collection and it was produced this error: FeatureCollection (Error) Invalid JSON. I also tried with suggestions in @Kevin Reid answer and they didn't work. Definitively, your Feature Collection is invalid.
    – xunilk
    Commented Mar 22, 2020 at 16:34
  • Thank you, that is weird because I was able to load them in another script, and view them in the Map viewer. However, I am getting the same result as you when I try to print the Feature Collection. Most interestingly, when I view the 'pantropics' asset in GEE, it's file size is only half of its original size, which indicates there must have been some error during the asset ingestion process. I will delete this asset, re-ingest it and try again.
    – Johanness
    Commented Mar 23, 2020 at 1:53
  • You're welcome. I will wait the update in your question.
    – xunilk
    Commented Mar 23, 2020 at 2:10

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.