1

I would like to use Earth Engine to sample raster data via points and save that information to a local file. Currently I do this by creating a FeatureCollection of point geometries and then pass that structure to a reduceRegions call. I iterate over the result of getInfo to get the sampled raster data. However, the runtime of this function is much much slower than I would have expected. Is there any way to get runtime feedback about a job that is being processed on GEE, or a better way to asynchronously request jobs for a client side download?

This is a simplified, but functional, version of what I'm trying to do that takes 30ish seconds the first time I run it. My actual data includes thousands of points and the wait time makes me wonder if I've done something wrong.

import ee


def main():
    """Entry point."""
    ee.Initialize()

    pts = ee.FeatureCollection([
      ee.Feature(ee.Geometry.Point([-118.6010, 37.0777])),
      ee.Feature(ee.Geometry.Point([-118.5896, 37.0778])),
      ee.Feature(ee.Geometry.Point([-118.5842, 37.0805])),
      ee.Feature(ee.Geometry.Point([-118.5994, 37.0936])),
      ee.Feature(ee.Geometry.Point([-118.5861, 37.0567]))
    ])

    img = ee.ImageCollection("LANDSAT/LT05/C01/T1_8DAY_NDVI").filterDate('1997-01-01', '2019-01-01')
    mean_img = img.reduce(ee.Reducer.mean())
    samples = mean_img.reduceRegions(**{
        'collection': pts,
        'scale': 30,
        'reducer': 'mean'}).getInfo()  #  <<< takes a long time to run! better way to do this?
    for sample in samples['features']:
        print(f"{sample['geometry']['coordinates']}, {sample['properties']['mean']}")


if __name__ == '__main__':
    main()
1

1 Answer 1

2

The collection you're starting from is a computed collection and the result of each 8 day mosaic is a global image. That means creating the mean image you're using involves every image in the collection from 1997 to 2019, even though you're only using a small portion of each image.

You would get much better performance by computing the NDVI yourself, so you can apply a filterBounds to the lower-level collection and limit the images involved.

expr = "ndvi = clamp(float(b('B4') - b('B3')) / (b('B4') + b('B3')), -1, 1)"

img = (ee.ImageCollection("LANDSAT/LT05/C01/T1_TOA")
       .filterDate('1997-01-02', '2019-01-01')
       .filterBounds(pts.geometry().bounds())
       .map(lambda img : img.expression(expr)))
mean_img = img.select('ndvi').reduce(ee.Reducer.mean())

That said, neither approach is accounting for clouds or cloud shadows, so the mean NDVI computed this way isn't particularly valid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.