3

I'm trying to extract band values from a Daymet image collection (V4) at specific sampling locations, averaged over the course of year (daily average). I'm using the Google Earth Engine Python API (geemap) to do so. The bands are raster datasets (1 km resolution) of variables such as maximum temperature, shortwave radiation, and other environmental variables.

Currently, I'm able to extract all of the daily values for each band over the time period using the following code:

ee.Initialize()

daymet = ee.ImageCollection('NASA/ORNL/DAYMET_V4') \
     .filter(ee.Filter.date('2000-01-01', '2000-12-31'))

DaymetImage = daymet.toBands() ##convert to ee.Image in order to extract_values_to_points

##export data
out_dir = os.path.expanduser('~/Downloads')
out_csv = os.path.join(out_dir, 'daymet2000.csv') 
geemap.extract_values_to_points(fc_coords, DaymetImage, out_csv)

##Note: fc_coords contains sampling points (lat/long) and other variables of interest

While this has all of the information I need, the resulting .csv file is bulky and would require a lot of work to clean up. I would like to be able to directly extract the daily average value for each band in the ImageCollection. The code I have so far is:

ee.Initialize()

daymet = ee.ImageCollection('NASA/ORNL/DAYMET_V4') \
     .filter(ee.Filter.date('2000-01-01', '2000-12-31')) \
     .mean() 

And this is where I get stuck. The .mean function appears to turn it from an ee.ImageCollection to an ee.Image; however, when I try to extract_values_to_points from this Image, I get the following error message: EEException: Image.reduceRegions: The default WGS84 projection is invalid for aggregations. Specify a scale or crs & crs_transform.

As it is an ee.Image, the toBands() function (which I used earlier on an ImageCollection) does not work. Is there any way I can extract the average band values from this ImageCollection easily?

2 Answers 2

1

Update to this one: if you're looking for a solution, the best way I've found is to filter the image collection and then apply a function that samples your coordinates using sampleRegions. You can apply these to an image or .map() it over an image collection and create a pandas dataframe. It seems to work well! Example:

years_dm = range(2000, 2021)

def rasterExtraction(image):
    feature = image.sampleRegions(
        collection = fc_coords,
        scale = 30 #Or 1000 for Daymet data
    )
    return feature


def monthly_Avg (collection, years):
  avg = []
  for year in years: 
      Monthly_avg = collection.filter(ee.Filter.calendarRange(year, year, 'year')) \
                              .filter(ee.Filter.calendarRange(1, 12, 'month')) \
                              .mean() \
                              .set({'year': year})
      avg.append (Monthly_avg)
  return ee.ImageCollection.fromImages(avg)

daymet = ee.ImageCollection('NASA/ORNL/DAYMET_V4').filterBounds(fc_coords)

monthly_dm = monthly_Avg(daymet, years = years_dm)

daymet_vals = geemap.ee_to_pandas(monthly_dm.map(rasterExtraction).flatten())

1

A quick fix will be to include the scale parameters for the extract_values_to_points

E.g., geemap.extract_values_to_points(fc_coords, DaymetImage, out_csv, scale=1000)

You may provide your scale value, or use the native scale of the bands: daymet.toBands().projection().nominalScale()

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.