[GIS] How to export a set of images from Google Earth Engine

google-earth-engine

I'm trying to export images of a bunch of latitude and longitude points, but I keep getting errors. For example, I am trying to export an image of this single point in this fusion table, but this is what happens:

  • 3 instances of the image I want to export pop up in the Tasks.
  • The first gives error "Unknown variable references: [_MAPPING_VAR_0_0]."
  • The second and third give error "Failed to decode JSON.
    Error: Field 'value' of object '{"type":"ArgumentRef","value":null}' is missing or null.
    Object: {"type":"ArgumentRef","value":null}."

Below is my code.

// Import points from fusion table into feature collection
var fc = ee.FeatureCollection('ft:1i3_jdpBy0lorCbZ7eNVnsGL3NaZWyDGRVCUrmKGl');
print(fc);

var pairImage = function(feature) {
  var point = ee.Geometry.Point([feature.get('lat'), feature.get('lon')]);

  // USGS Landsat 8 TOA Reflectance (Orthorectified) Set
  var l8 = ee.ImageCollection('LANDSAT/LC8_L1T_TOA');

  // Only get images that intersect lat/lon point
  var spatialFiltered = l8.filterBounds(point);

  // Only get images for year of 2016
  var temporalFiltered = spatialFiltered.filterDate('2016-01-01', '2016-12-31');

  // This will sort from least to most cloudy.
  var sorted = temporalFiltered.sort('CLOUD_COVER');

  // Get the first (least cloudy) image.
  var scene = ee.Image(sorted.first()).select(['B4', 'B3', 'B2']);

  var visualization = scene.visualize({
    bands: ['B4', 'B3', 'B2'],
    max: 0.3
  });
  return visualization;
}

// Get all images of points
var images = fc.map(pairImage);

var saveImages = function(image) {
  Export.image.toDrive({
    image: image,
    description: 'true-color-composite',
    scale: 13
  });
  return null;
}

// Export the images
images.map(saveImages);

Best Answer

Well, the documentation (https://developers.google.com/earth-engine/client_server#client-and-server-functions) says that Export is a client-side function, and map() executes on the Server-side, and I think that is the problem. Although you'll find in the same documentation that client-side for loops ain't recommended, in this case that you want to go over a client-side function, I'd use it, like:

// Import points from fusion table into feature collection
var fc = ee.FeatureCollection('ft:1i3_jdpBy0lorCbZ7eNVnsGL3NaZWyDGRVCUrmKGl');
print(fc);

var pairImage = function(feature) {
  var point = ee.Geometry.Point([feature.get('lat'), 
                                 feature.get('lon')]);

  // USGS Landsat 8 TOA Reflectance (Orthorectified) Set
  var l8 = ee.ImageCollection('LANDSAT/LC8_L1T_TOA');

  // Only get images that intersect lat/lon point
  var spatialFiltered = l8.filterBounds(point);

  // Only get images for year of 2016
  var temporalFiltered = spatialFiltered.filterDate('2016-01-01', '2016-12-31');

  // This will sort from least to most cloudy.
  var sorted = temporalFiltered.sort('CLOUD_COVER');

  // Get the first (least cloudy) image.
  var scene = ee.Image(sorted.first()).select(['B4', 'B3', 'B2']);

  var visualization = scene.visualize({
    bands: ['B4', 'B3', 'B2'],
    max: 0.3
  });
  return visualization;
}

// Get all images of points
var images = fc.map(pairImage);

// list of images (client side)
var imgs = images.getInfo()["features"]

// loop on client side
for (var i = 0; i<imgs.length;i++) {
  var im = ee.Image(imgs[i]["id"]);
  Map.addLayer(im)
  Export.image.toDrive({
    image: im,
    description: 'true-color-composite',
    scale: 30
  });
}

If you have shapes, you could make the fusion table with those, but I assume you have a list of places with lat & long values.

Related Question