0

In Earth Engine I have a table asset of coordinates and dates (properties `LAT', 'LONG', 'DATE') for which I would like to return a pixel value from my ImageCollection dswe_ic, which gives a monthly DSWE (Dynamic Surface Water Extent) value.

// get a DSWE value (integers of 0, 1, 2, 3, 4, or 9)
var dswe_ic = ee.ImageCollection.fromImages(months.map(function(m){
  var start = start_date.advance(m, 'month'); // Advance start date by m months
  var end = start.advance(1, 'month');        // End date is start month +1 
  return img_indices_all.filterDate(start, end) 
          .select(['dswe'])
          .reduce(ee.Reducer.min()) //  Produces band 'dswe_min'
          .set('date', start.format("YYYYMM")) // Sets yr/mo as property 'date'
          .cast({'dswe': 'uint8'})  // Adds empty band 'dswe'
          .remap([0,1,2,3,4,8,9], [0,1,2,3,4,9,9]).rename('dswe'); // remap takes the 1st band unless otherwise specified
          // return a monthly DSWE value, taking the lowest DSWE value (i.e. highest confidence value)
          // of the month if there are multiple DSWE values to pick from
          // (due to potential availability of more than 1 high quality Landsat scenes)

I can map over my coordinates of interest with dswe_ic easily enough and generate a CSV list of monthly pixel values from my start date (May 21, 2003) to my end date (Nov 17, 2016).

var results = points_of_interest.map(function(f) {
  return dswe_ic.map(function(i) {
    var mean = i.reduceRegion({
      geometry: f.geometry(),
      scale: 30,
      crs: 'EPSG:4326',
      reducer: ee.Reducer.first(),
    });

    return f.setMulti(mean).set('date', i.get('date'))
  })
})
results = results.flatten()

Export.table.toDrive({
  collection: results,
  description: 'results_all_coords_allmonths_from_may2003_to_nov2016,
  fileFormat: 'CSV'
});

However, I am more interested in directly appending my original table with a new column for the pixel value from dswe_ic for each particular 'DATE' and coordinate. Unfortunately, my GEE skills are quite limited to do this. Any suggestions?

1 Answer 1

0

You can join your feature collection with your image collection. This script creates monthly images with a yearMonth property, and add a corresponding yearMonth property to each feature. These properties are then used as a condition when joining the collections. Obviously, it doesn't use neither your image collection or features, but you hopefully get the gist.

var features = ee.FeatureCollection([
    ee.Feature(ee.Geometry.Point([14.803, 41.314]), {date: '2019-01-01'}),
    ee.Feature(ee.Geometry.Point([11.858, 44.468]), {date: '2020-01-01'})
  ])
  .map(function (feature) {
    return feature.set('yearMonth', ee.Date(feature.getString('date')).format('yyyyMM'))
  })

var startDate = ee.Date('2016-01-01')
var endDate = ee.Date(new Date())
var months = endDate.difference(startDate, 'months')
var monthOffsets = ee.List.sequence(0, months.subtract(1))

var monthlyImages = ee.ImageCollection(monthOffsets
  .map(function (monthOffset) {
    var start = startDate.advance(monthOffset, 'months')
    var end = start.advance(1, 'months')
    return ee.ImageCollection('COPERNICUS/S2')
      .filterBounds(features.geometry())
      .filterDate(start, end)
      .min()
      .set('yearMonth', start.format('yyyyMM'))
  })
)

var featuresWithMean = ee.Join.saveFirst('image')
  .apply({
    primary: features, 
    secondary: monthlyImages, 
    condition: ee.Filter.equals({leftField: 'yearMonth', rightField: 'yearMonth'})
  })
  .map(function (feature) {
    var image = ee.Image(feature.get('image'))
    var mean = image
      .select('B4')
      .reduceRegion({
        geometry: feature.geometry(),
        scale: 30,
        crs: 'EPSG:4326',
        reducer: ee.Reducer.mean(),
      }).get('B4')
    return feature
      .set('mean', mean)
      .set('yearMonth', null).set('image', null) // Drop redundant properties
  })

print(featuresWithMean)  

https://code.earthengine.google.com/f918871f8879f24113d96062a4c721d1

1

Your Answer

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

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