davemlz / eemont

A python package that extends Google Earth Engine.
https://eemont.readthedocs.io/
MIT License
417 stars 69 forks source link

ee.Image.index raises AttributeError on median-reduced image #42

Open aazuspan opened 3 years ago

aazuspan commented 3 years ago

Hi @davemlz! I don't think this is really an eemont bug, but I'm wondering if you know of a good workaround or if maybe there's an eemont feature that could help with this.

Describe the bug If you use a reducer other than ee.Reducer.first on an ImageCollection and then try to use the index method, an attribute error is thrown. I think this is because Earth Engine reducers like ee.Reducer.median don't preserve image metadata that's needed for _get_platform_STAC to work.

I'm not sure exactly what metadata _get_platform_STAC needs, but maybe I could fix this by setting or copying some properties after running median?

To Reproduce

import ee, eemont
ee.Initialize()

s2 = ee.ImageCollection("COPERNICUS/S2_SR")
pt = ee.Geometry.Point([-122.276437, 44.803428])
img = (s2
    .filterBounds(pt)
    .filterDate("2020-01-01", "2020-01-30")
    # Using .first() instead would fix the problem
    .median()
)

img = img.index("NDSI")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_14264/966081019.py in <module>
     10 )
     11 
---> 12 img = img.index("NDSI")

~\anaconda3\envs\salvage\lib\site-packages\eemont\image.py in index(self, index, G, C1, C2, L, cexp, nexp, alpha, slope, intercept, kernel, sigma, p, c, online)
    746     )
    747 
--> 748     return _index(
    749         self,
    750         index,

~\anaconda3\envs\salvage\lib\site-packages\eemont\common.py in _index(self, index, G, C1, C2, L, cexp, nexp, alpha, slope, intercept, kernel, sigma, p, c, online)
    417         Image (or Image Collection) with the computed spectral index, or indices, as new bands.
    418     """
--> 419     platformDict = _get_platform_STAC(self)
    420 
    421     if isinstance(sigma, int) or isinstance(sigma, float):

~\anaconda3\envs\salvage\lib\site-packages\eemont\common.py in _get_platform_STAC(args)
     46             args, ee.image.Image
     47         ):
---> 48             pltID = "/".join(ID.split("/")[:-1])
     49         elif eeDict[platform]["gee:type"] == "image" and isinstance(
     50             args, ee.imagecollection.ImageCollection

AttributeError: 'NoneType' object has no attribute 'split'

Setup (please complete the following information):

Additional context Thanks!

davemlz commented 3 years ago

Hi, @aazuspan!

You're totally right. The problem here is that after reducing an image it loses all its properties. Most eemont methods depend on the system:id property, so it is necessary to have it. Given this, here is a workaround:

s2 = ee.ImageCollection("COPERNICUS/S2_SR")
pt = ee.Geometry.Point([-122.276437, 44.803428])
img = (s2
    .filterBounds(pt)
    .filterDate("2020-01-01", "2020-01-30")
    # Using .first() instead would fix the problem
    .median()
    .copyProperties(s2.first(),["system:id"])
)

img = ee.Image(img).scaleAndOffset().spectralIndices("NDSI")

I will leave this issue open, maybe I can find a way to fix this in the future :)

Cheers!

aazuspan commented 3 years ago

Awesome, thanks so much for the quick workaround! :)