1

I am trying to export to drive an image in GEE. I have created a string made from other variables and I would like to use it as name of the file.

If I print the variable as a string, I get the name I would like to have for my file. But if I use it to name the file in the export to drive the name results something like:

ee.Image({ "type": "Invocation", "arguments": { "collection": { "type": "Invocation", "arguments": { "collection": { "type": "Invocation",

A script reproducing the error is the following:

https://code.earthengine.google.com/18768850e984659e9a3f409b02ad5835

var geometry = ee.Geometry.Point([-105.483203125, 41.85704089594469]);

var date1=ee.Date('2018-01-01')

var date2= ee.Date('2023-01-01')

var BUFF= 10000 

var AOI=geometry.buffer(BUFF)

var nameSite='NameSite'

var name = ee.String(nameSite).cat('_').cat(date1.get('year')).cat('_').cat(date2.get('year')).cat('_').cat(ee.String(ee.Number(BUFF/1000))).cat('km')

print(name)

var img = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate('2020-01-01', '2020-01-30').filterBounds(AOI).first()


Export.image.toDrive({
  image: img,
  description: img,
  scale: 30,
  crs:  'EPSG:4326',
  maxPixels: 1e10, 
  region: AOI,
  fileFormat: 'GeoTIFF',
  formatOptions: {
    cloudOptimized: true
  }
});

What I am doing wrong here?

2 Answers 2

1

I have a solution for you:

After a quick browser search I came across: Converting ee:Date object to client string in Google Earth Engine

I would recommend to use the .getInfo() Method to return a new variable like OutputName with the information of your string. Here is your modified code:

var geometry = ee.Geometry.Point([-105.483203125, 41.85704089594469]);

var date1=ee.Date('2018-01-01')

var date2= ee.Date('2023-01-01')

var BUFF= 10000 //10 km

var AOI=geometry.buffer(BUFF)

var nameSite='NameSite'

var ImageName = ee.String(nameSite).cat('_').cat(date1.get('year')).cat('_').cat(date2.get('year')).cat('_').cat(ee.String(ee.Number(BUFF/1000))).cat('km');
var OutputName = ImageName.getInfo();

print(OutputName)


var img = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate('2020-01-01', '2020-01-30').filterBounds(AOI).first()


Export.image.toDrive({
  image: img,
  description: OutputName,
  fileNamePrefix: OutputName,
  scale: 30,
  crs:  'EPSG:4326',
  maxPixels: 1e10, 
  region: AOI,
  fileFormat: 'GeoTIFF',
  formatOptions: {
    cloudOptimized: true
  }
});

When I run the Code in the GEE it correctly assigns automatically the desired name from the variable ImageName (I renamed your variables). I think this is what you wanted.

4
  • This is exactly what I was looking for, thanks!
    – Fra3v
    Commented Jul 13, 2023 at 15:57
  • This is a very bad solution if you have a lot of points and images because getInfo method will freeze the API.
    – xunilk
    Commented Jul 13, 2023 at 16:42
  • 1
    Agreed with xunilk, you can also do a client-side string by replacing "cat" by "+" and removing all instances of "ee.", for example, if your string is nameSite + '_' + BUFF +'_km' then you won't need to use getInfo.
    – M. Nicolas
    Commented Jul 13, 2023 at 19:47
  • 2
    Yes, you're rigth @M.Nicolas, he won't need to use getInfo for one point and one image. However, his approach for several points (his variable is nameSite) and a lot of images (only was considered the first one) probably won't work without getInfo. I will post an answer later.
    – xunilk
    Commented Jul 13, 2023 at 21:47
1

Automatically naming an image for exporting to Google Drive makes more sense when we have a Feature Collection of points and a lot of images to export. The geometry (one point) considered above is going to be transformed into a Feature Collection of two points that will illustrate the iteration process if more points are considered. It looks as follows. Observe that it has a name (could be NameSite) and one id.

var pt1 = ee.Feature(ee.Geometry.Point([-105.483203125, 41.85704089594469]),
        {
          "name": "pt1",
          "system:index": "0"
        }),
    pt2 = ee.Feature(ee.Geometry.Point([-96.08964045047759, 39.855638770726664]),
            {
          "name": "pt2",
          "system:index": "1"
        });

Related to the Image Collection, the dates range above considered would produce 894 elements for these two points so, I considered one year to get only 12 images to exemplify the process.

For avoiding to use the getInfo method in the exporting process, the image name will be created directly when simultaneously to map both Feature and Image collections and added to images as a property. The name of image will be composed by the date, the name site and the 'MGRS_TILE' property (to differentiate images with the same date). This name will also be used for adding and displaying the images at the Map Canvas of GEE. Complete code looks as follows:

var pt1 = ee.Feature(ee.Geometry.Point([-105.483203125, 41.85704089594469]),
        {
          "name": "pt1",
          "system:index": "0"
        }),
    pt2 = ee.Feature(ee.Geometry.Point([-96.08964045047759, 39.855638770726664]),
            {
          "name": "pt2",
          "system:index": "1"
        });

var col_feats = ee.FeatureCollection([pt1, pt2]);

Map.addLayer(col_feats, {}, 'col_feats');
Map.centerObject(col_feats);

var date1 = ee.Date('2018-01-01');
var date2 = ee.Date('2019-01-01'); //'2023-01-01'

var col_img = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
                  .filterDate(date1, date2);

var col_img = col_feats.map(function (ele) {
  
  var new_col = col_img.filterBounds(ee.Feature(ele).geometry());
  
  var setName = new_col.map(function (e) {
    
    var name = ee.Feature(ele).get('name');
    
    var date = ee.Date(ee.Image(e).get('system:time_start')).format().slice(0, 10);
    var tile = ee.Image(e).get('MGRS_TILE');
    
    var nameFile = ee.String('image_').cat(date)
                                      .cat('_')
                                      .cat(ee.String(name))
                                      .cat('_')
                                      .cat(tile);
    
    return ee.Image(e).set('nameFile', nameFile);
    
  });
  
  return setName;
  
}).flatten();

print("col_img", col_img);

var exportImage = function(image, fileName) {
  Export.image.toDrive({
    image: image,
    description: fileName,
    folder: 'GEE_Folder',
    region: col_feats,
    fileFormat: 'GeoTIFF'
  });
};

col_img.aggregate_array('nameFile').evaluate(function (fileNames) {
  fileNames.forEach(function(fileName) {
    
    var image = col_img
      .filter(ee.Filter.eq('nameFile', fileName))
      .first();
    
    Map.addLayer(ee.Image(image), {}, fileName, false);
    
    exportImage(image, fileName);
  
  });
});

After running it at GEE code editor, I got the result of following picture. It can be observed two of the 12 images capable of being displayed and the 12 waiting export tasks.

enter image description here

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.