0

I am learning Earth Engine with Python and I am stuck when I want to split the entire terraclimate Image Collection with province feature collection.

admin = ee.FeatureCollection('FAO/GAUL_SIMPLIFIED_500m/2015/level2')
terraclimate = ee.ImageCollection('IDAHO_EPSCOR/TERRACLIMATE')

province_names = list(
    np.unique(
        np.array(
            admin.filter(
                ee.Filter.eq('ADM0_NAME', 'Indonesia')
            ).aggregate_array('ADM1_NAME').getInfo()
        )
    )
)

province_list = ee.List(province_names)

def get_province(province):
    img_col = terraclimate.filterBounds(admin.filter(ee.Filter.eq('ADM1_NAME', province)))
    return img_col.set({'province':province})

new_img_col = province_list.map(get_province)

What I get from the code above is a list of ImageCollection. How can I convert this into a single ImageCollection? I try to unpack the list with another map but it gave me error:

'ComputedObject' object has no attribute 'map'

What I'm trying to achieve with this is to get an image collection where each image is separated by province, and afterward, I will use it to calculate mean yearly temperature for each province.

1 Answer 1

1

First, a general note: Always try to avoid getInfo() calls whenever you can. It evaluates the value server-side, and returns a client-side object. This often makes your script significantly slower than it needs to be. You can read up on it here.

You have a list where each element is an ImageCollection that you want to merge into a single ImageCollection. Below are two approaches for doing this.

First approach uses iterate(). It manually accumulates the images into a single collection. It's quite explicit in what it does while being quite verbose, due to all the casts needed.

Second approach uses a trick where the list of collections are put into a FeatureCollection, which then is flattened. More compact, but maybe a bit magical.

import ee

ee.Initialize()

admin = ee.FeatureCollection('FAO/GAUL_SIMPLIFIED_500m/2015/level2')
terraclimate = ee.ImageCollection('IDAHO_EPSCOR/TERRACLIMATE')

province_names = admin \
  .filter(ee.Filter.eq('ADM0_NAME', 'Indonesia')) \
  .aggregate_array('ADM1_NAME') \
  .distinct() # Remove duplicates directly in EE. Avoids getInfo() call

def get_province(province):
    img_col = terraclimate.filterBounds(admin.filter(ee.Filter.eq('ADM1_NAME', province)))
    return img_col.set({'province':province})


# Option 1 - iterate
new_img_col = province_names.map(get_province)
collection1 = ee.ImageCollection( # Cast result of iterate() to ImageCollection
  new_img_col.iterate(
    lambda proviceCollection, acc:
      ee.ImageCollection(acc).merge( # Both arguments must be cast too
        ee.ImageCollection(proviceCollection)
      ),
    ee.ImageCollection([])
  )
)

# Option 2 - flatten
collection2 = ee.ImageCollection( # Cast result to ImageCollection
  ee.FeatureCollection( # Create an intermediate FeatureCollection containing ImageCollections
    province_names.map(get_province)
  ).flatten() # Remove the intermediate feature collection with the merged image collections
)
2
  • very clear explanation. And thanks for the tip to avoid using getInfo(). One question, at the second option, why do using flatten() method directly to Image Collection wont work? Feb 11, 2022 at 13:20
  • You have a list with collections, not collection with collections. Feb 11, 2022 at 14:03

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.