0

I am trying to export a multi-polygon clipped image with the python API. The problem is that the code in python does not clipped the image correctly (I have just one polygon saved instead of two like the example given below). Probably I am doing something wrong but I do not know where my mistake is. I applied the same code on the Google earth Engine editor with a similar Javascript code and everything is correctly done.

Javascript code:

 var geometry = ee.Geometry.Polygon([[[37.24154695,  8.01665693],
 [37.26876315,  8.01665693],
 [37.26876315,  8.04378808],
 [37.24154695 , 8.04378808],
 [37.24154695,  8.01665693]],
 [[37.34154695,  8.11665693],
 [37.36876315,  8.11665693],
 [37.36876315,  8.14378808],
 [37.34154695 , 8.14378808],
 [37.34154695,  8.11665693]]]);

/**
 * Function to mask clouds based on the pixel_qa band of Landsat 8 SR data.
 * @param {ee.Image} image input Landsat 8 SR image
 * @return {ee.Image} cloudmasked Landsat 8 image
 */
function maskL8sr(image) {
  // Bits 3 and 5 are cloud shadow and cloud, respectively.
  var cloudShadowBitMask = (1 << 3);
  var cloudsBitMask = (1 << 5);
  // Get the pixel QA band.
  var qa = image.select('pixel_qa');
  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
                 .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  return image.updateMask(mask);
}

var dataset = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
                  .filterBounds(geometry)
                  .filterDate('2016-01-01', '2016-12-31')
                  .map(maskL8sr);
var image = dataset.median()
Export.image.toDrive({
  image: image.clip(geometry),
  folder: "test",
  description: 'imageToCOGeoTiffExample2',
  scale: 30,
  region: geometry,
  fileFormat: 'geotiff',
  skipEmptyTiles: true
});

Python code:

t = [[[37.24154695, 8.01665693],
          [37.26876315, 8.01665693],
          [37.26876315, 8.04378808],
          [37.24154695, 8.04378808],
          [37.24154695, 8.01665693]],
         [[37.34154695, 8.11665693],
          [37.36876315, 8.11665693],
          [37.36876315, 8.14378808],
          [37.34154695, 8.14378808],
          [37.34154695, 8.11665693]]]

    region = ee.Geometry.Polygon(t)
    dataset = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR') \
        .filterBounds(region) \
        .filterDate('2016-01-01', '2016-12-31') \
        .map(_mask_l8_sr)
    dataset = dataset.reduce('median')
    task = ee.batch.Export.image.toDrive(image=dataset.clip(region),
                                         description="test",
                                         folder="testing",
                                         region=region['coordinates'],
                                         scale=30,
                                         fileFormat='GeoTIFF',
                                         skipEmptyTiles=True)
    task.start()
1

The difference is that you're passing a geometry in the javascript and a list of coordinates in the python, and those are interpreted differently because there's no enclosing object to identify how to interpret the coordinates, and it's more complex than a single list of coordinates.

Getting a region for the export in python is always a little tricky; I suggest this:

region=region.bounds().getInfo()['coordinates'],
  • I have just tried your suggestion. But there is no changes. – Loic L. Nov 21 '18 at 14:15
0

As I understand, and Noel can correct me (he knows what's happening in 'the other side'), when using the JS API you can pass a geometry and EE will know what to do, but when using the Python API you cannot pass a geometry, so you have to do something about it. This is what I'd do in this case (MultiPolygon)

t = [[[37.24154695, 8.01665693],
      [37.26876315, 8.01665693],
      [37.26876315, 8.04378808],
      [37.24154695, 8.04378808],
      [37.24154695, 8.01665693]],
      [[37.34154695, 8.11665693],
      [37.36876315, 8.11665693],
      [37.36876315, 8.14378808],
      [37.34154695, 8.14378808],
      [37.34154695, 8.11665693]]]

region = ee.Geometry.Polygon(t)
dataset = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR') \
            .filterBounds(region) \
            .filterDate('2016-01-01', '2016-12-31') \
            .map(_mask_l8_sr)
dataset = dataset.reduce('median')
coords = region['coordinates']

# loop over the MultiPolygon parts
for r in range(len(coords)):
    pol = ee.Geometry.Polygon(coords[r])

    task = ee.batch.Export.image.toDrive(image=dataset.clip(pol),
                                         description="test",
                                         folder="testing",
                                         region=pol['coordinates'],
                                         scale=30,
                                         fileFormat='GeoTIFF',
                                         skipEmptyTiles=True)
    task.start()

There is a python package called geetools that has a function that does some logic over this issue. It's not perfect and I'll improve it along the way. This case (MultiPolygons) it's not handled yet, but it's a good opportunity to include it. After you install it, you could:

from geetools import tools

region = tools.geometry.getRegion(object)
  • First of all thank you for your answer. I used this method previously but the problem with that method is that it generates a task on gee for each image. Since I have a large amount of requests to achieve, this technique explodes my number of tasks an then I reach the limit. That is why I want to use clip since with this methodology you just have a single request and from the image generated I divide it into single polygon with gdalwarp. – Loic L. Nov 21 '18 at 15:32
  • Ah, ok, so Noel's answer should work, but you'll get one image where pixels outside the geometry will be masked. – Rodrigo E. Principe Nov 21 '18 at 15:56
  • The thing is that it seems that it does not work and I do not know why because I followed What He suggests... – Loic L. Nov 21 '18 at 16:12
  • Thus I suppose there is no solution right now that allows me to clip several regions of interest into a single task. – Loic L. Nov 22 '18 at 10:22
  • To download two separated images in one task, I guess not in EE. You should download the clipped image and split it locally. Maybe with GDAL or rasterio you could automate the process – Rodrigo E. Principe Nov 22 '18 at 10:28

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.