How to iterate over and download each image in an image collection from the Google Earth Engine python api

krishnab picture krishnab · Oct 26, 2017 · Viewed 7.4k times · Source

I am new to google earth engine and was trying to understand how to use the Google Earth Engine python api. I can create an image collection, but apparently the getdownloadurl() method operates only on individual images. So I am trying to understand how to iterate over and download all of the images in the collection.

Here is my basic code. I broke it out in great detail for some other work I am doing.

import ee
ee.Initialize()
col = ee.ImageCollection('LANDSAT/LC08/C01/T1')
col.filterDate('1/1/2015', '4/30/2015')
pt = ee.Geometry.Point([-2.40986111110000012, 26.76033333330000019])
buff = pt.buffer(300)
region = ee.Feature.bounds(buff)
col.filterBounds(region)

So I pulled the Landsat collection, filtered by date and a buffer geometry. So I should have something like 7-8 images in the collection (with all bands).

However, I could not seem to get iteration to work over the collection.

for example:

for i in col:
    print(i)

The error indicates TypeError: 'ImageCollection' object is not iterable

So if the collection is not iterable, how can I access the individual images?

Once I have an image, I should be able to use the usual

path = col[i].getDownloadUrl({
    'scale': 30,
    'crs': 'EPSG:4326',
    'region': region
})

Answer

Nicholas Clinton picture Nicholas Clinton · Oct 26, 2017

It's a good idea to use ee.batch.Export for this. Also, it's good practice to avoid mixing client and server functions (reference). For that reason, a for-loop can be used, since Export is a client function. Here's a simple example to get you started:

import ee
ee.Initialize()

rectangle = ee.Geometry.Rectangle([-1, -1, 1, 1])
sillyCollection = ee.ImageCollection([ee.Image(1), ee.Image(2), ee.Image(3)])

# This is OK for small collections
collectionList = sillyCollection.toList(sillyCollection.size())
collectionSize = collectionList.size().getInfo()
for i in xrange(collectionSize):
    ee.batch.Export.image.toDrive(
        image = ee.Image(collectionList.get(i)).clip(rectangle), 
        fileNamePrefix = 'foo' + str(i + 1), 
        dimensions = '128x128').start()

Note that converting a collection to a list in this manner is also dangerous for large collections (reference). However, this is probably the most scalable method if you really need to download.