Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

index() does not work when called within .map() #2

Closed
andresfchamorro opened this issue Apr 13, 2021 · 4 comments
Closed

index() does not work when called within .map() #2

andresfchamorro opened this issue Apr 13, 2021 · 4 comments

Comments

@andresfchamorro
Copy link

andresfchamorro commented Apr 13, 2021

Hey!

First of all great work, very useful package. I am trying to create a time series dataset of indices based on Landsat collections. I have prepared a basic function that works well when it's run with one feature, but it fails when mapped to a feature collection. Here is a simplified version of the function:

def getStats(feature):
    oliCol = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').filterBounds(feature.geometry()).filterDate('2013-01-01','2015-01-01')
    oliNDVI = oliCol.scale().index('NDVI').select('NDVI').toBands()
    zs = ee.Image(oliNDVI).reduceRegion(
        geometry = feature.geometry(),
        reducer = ee.Reducer.mean(),
        scale = 1000,
        tileScale = 4,
        bestEffort = True,
        maxPixels = 10e15
    )
    return feature.setMulti(zs)

This works:

res = getStats(aoi)

But this fails:

res = AOIs.map(getStats)

with the following error

image

Something is happening that prevents _get_platform from running properly. Is this expected? Any ideas how to fix?

@davemlz
Copy link
Owner

davemlz commented Apr 13, 2021

Hi Andres!

Thank you very much for pointing this out, I will check it. Is there any chance I can get access to the feature collection to try it?

In the meantime, let me tell you that you can get the time series from a feature collection by using the getTimeSeriesByRegions() method from eemont 0.1.9 (example here):

oliCol = (ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
   .filterBounds(featurecollection)
   .filterDate('2013-01-01','2015-01-01')
   .scale()
   .index('NDVI'))

ts = oliCol.getTimeSeriesByRegions(collection = featurecollection,
   reducer = ee.Reducer.mean(),
   bands = 'NDVI',
   scale = 1000,
   tileScale = 4)

Let me know if it works! And I will check the error to see what's happening.

Cheers!

@andresfchamorro
Copy link
Author

Thanks, I'll look into getTimeSeriesByRegions. I am doing a bit of harmonization prior (merging different Landsat collections) and running this for multiple countries, which is why I was implementing a custom function - if I don't use filterBounds for each country it will probably time out.

Sure, send me your gmail and I'll share the feature collection.

@davemlz
Copy link
Owner

davemlz commented Apr 15, 2021

Hi Andres!

Ok, now I understand.

You can share your feature collection to this gmail.

Thanks!

@davemlz
Copy link
Owner

davemlz commented Apr 19, 2021

Hi Andres!

I have checked your script, and now I know what's happening: The problem is associated to the _get_platform function. This function uses the getInfo() client method in order to get the ID of the ee.Image (or ee.ImageCollection) so different eemont methods such as scale(), maskClouds() or index() can be computed according to the parameters of the specific satellite platform.

Since getInfo() is a client method and not a server method, it can't be mapped (it can't be used within a map() function). Check the Debugging Guide.

In this case, the problem can be solved by working in the client-side and not in the server-side. This works perfectly:

countries = ['Ethiopia','Ghana','Nicaragua'] # client-side object, don't use here an ee.List since it is a server-side object
features = []
for country in countries: # client-side loop
    # Here, the name of each country (a client-side object)
    # is used to filter the feature collection and a
    # server-side object is retrieved (an ee.Feature)
    # and it is appended to the list
    features.append(getStats(AOIs.filterMetadata('WB_ADM0_NA', 'equals',country)))
# Here, the list of ee.Feature objects is converted into an ee.FeatureCollection
ee.FeatureCollection(features)

I'll close this issue for now and I'll open a new issue regarding the use of the getInfo() method inside the _get_platform function. I hope to find a way to use just server-side methods inside eemont soon.

Thank you very much for your time and attention here!

Cheers!

@davemlz davemlz closed this as completed Apr 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants