I have a large Image in Google Earth Engine that I would like to export as CSV. However, due to its size, I am having a hard time converting it to FeatureCollection to make the export, and I don't know if there is a way around that.

The ideal CSV output will have the following columns:

lat | lon | age | biomass | biomass_sd | cwd

With each row containing data from a 30x30m pixel.

var age = ee.Image(
var biomass = ee.Image('projects/ee-ana-zonia/assets/biomass_2020') // anyone can read
var sd = ee.Image('projects/ee-ana-zonia/assets/biomass_sd_2020') // anyone can read
var cwd = ee.Image('projects/ee-ana-zonia/assets/cwd_chave') // anyone can read
var amazon_biome = ee.FeatureCollection('projects/ee-ana-zonia/assets/amazon_biome_border'); // anyone can read

// Clip to Amazon biome
var age = age.clip(amazon_biome)
                         .updateMask(age.gt(0)); // select only pixels with age 1 or greater
var biomass = biomass.clip(amazon_biome);
var sd = sd.clip(amazon_biome);
var cwd = cwd.clip(amazon_biome);

// set visualization parameters
var ageviz = { min: 0, max: 33, palette: ['00FFFF', '0000FF'] };
var agbdviz = { min: 0, max: 415, palette: ['00FFFF', '0000FF'] };
var cwdviz = { min: -831.75, max: 0, palette: ['00FFFF', '0000FF'] };

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// this section is done to account for the "edge" pixels. To attribute a more accurate biomass value
// for a 30x30 age pixel that is at the edge of a 100x100 biomass pixel, I downsample biomass,
// average the values, and then reaggregate the 10x10 pixels to 30x30, realigning with age.

// reproject to 10m
var biomass_10m = biomass.reproject({crs: age.projection(), scale: 10});
var cwd_10m = cwd.reproject({crs: age.projection(), scale: 10});
var sd_10m = sd.reproject({crs: age.projection(), scale: 10});

// mask only to regions with age greater than zero (secondary forests)
var biomass = biomass.updateMask(age);
var sd_10m = sd_10m.updateMask(age);
var cwd_10m = cwd_10m.updateMask(age);

// reaggregate to 30m(mean value)
var aggregated_biomass = biomass_10m
    .reduceResolution({reducer: ee.Reducer.mean(), maxPixels: 1024})
    .reproject({crs: age.projection().crs(), scale: 30});
var aggregated_cwd = cwd_10m
    .reduceResolution({reducer: ee.Reducer.mean(), maxPixels: 1024})
    .reproject({crs: age.projection().crs(), scale: 30});
var aggregated_sd = sd_10m
    .reduceResolution({reducer: ee.Reducer.mean(), maxPixels: 1024})
    .reproject({crs: age.projection().crs(), scale: 30});
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

var amazon_imgcol = ee.Image(age.rename('age'))

var grid = age.geometry().coveringGrid(age.geometry().projection(), 100000);

// as an example, let's pick one cell of the grid
var grid_square = ee.Feature(grid.toList(grid.size().getInfo()).get(500));

var amazon_imgcol_square = amazon_imgcol.clip(grid_square).select('age')

var featurize = amazon_imgcol_square.reduceToVectors({
  geometry: amazon_imgcol_square.geometry(),
  scale: 30,
  labelProperty: 'label',
  maxPixels: 1e10

// // Export all features in a FeatureCollection as one file
// Export.table.toDrive({
// collection: second_tiles_featcol,
// fileNamePrefix: 'age' + f,
// fileFormat: 'CSV'});

When running this, I get that "User memory limit exceeded", and that would be with 100s of tiles!

How can I get a CSV out of this?

  • If there's no much processing involved with the images, I would recommend to simply export the images as rasters (GeoTiff), then extract the values that you need as a table in post-processing. If you really want to do this in GEE, I wouldn't recommend reduceToVectors in this scenario. I would first build a feature collection of points, split it into multiple parts, then use image.reduceRegions to one of these mini-batches of features to create an export task. Then do the same for each mini-batch. Nov 20, 2023 at 5:43
  • Hi Oliver, thank you for your help. I've worked on what you said, and it works, thanks a lot! I'm finding that part of the issue is something with the first part of the code, that I've just posted as a separate question to make sure the issues are addressed differently in different posts. Nov 27, 2023 at 1:45


Your Answer

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