13

I realise that this question has been asked before as Extract pixel values by points and convert to a table in Google Earth Engine at Stack Overflow. However, I can't get the code to work. It runs, but the value of the raster isn't added to the table it just prints the point attributes

var yearly = ee.ImageCollection('JRC/GSW1_0/YearlyHistory');

Map.addLayer(yearly, {}, 'yearly', false); 

var fg_points = ee.FeatureCollection('ft:1quTYHcLHQNy1yrssUPaubflVBEkGGMoPFLdbc_-J')

// Empty Collection to fill
var ft = ee.FeatureCollection(ee.List([]))

var fill = function(img, ini) {
  // type cast
  var inift = ee.FeatureCollection(ini)

  // gets the values for the points in the current img
  var ft2 = img.reduceRegions(fg_points, ee.Reducer.first(),30)    
  // gets the date of the img
  var date = img.date().format()

  // writes the date in each feature
  var ft3 = ft2.map(function(f){return f.set("date", date)})

  // merges the FeatureCollections
  return inift.merge(ft3)
}

// Iterates over the ImageCollection
var newft = ee.FeatureCollection(yearly.iterate(fill, ft));

// Export
Export.table.toDrive(newft,
"export_Points",
"export_Points",
"export_Points");  

1 Answer 1

18

I have no access to your fusion table, so I made up one to make the answer.

First approach: 2D table

var yearly = ee.ImageCollection('JRC/GSW1_0/YearlyHistory');
// function to map over the FeatureCollection
var mapfunc = function(feat) {
  // get feature geometry
  var geom = feat.geometry()
  // function to iterate over the yearly ImageCollection
  // the initial object for the iteration is the feature
  var addProp = function(img, f) {
    // cast Feature
    var newf = ee.Feature(f)
    // get date as string
    var date = img.date().format()
    // extract the value (first) of 'waterClass' in the feature
    var value = img.reduceRegion(ee.Reducer.first(), geom, 30).get('waterClass')
    // if the value is not null, set the values as a property of the feature. The name of the property will be the date
    return ee.Feature(ee.Algorithms.If(value,
                                       newf.set(date, ee.String(value)),
                                       newf.set(date, ee.String('No data'))))
  }
  var newfeat = ee.Feature(yearly.iterate(addProp, feat))
  return newfeat
};

var newft = fg_points.map(mapfunc);

// Export
Export.table.toDrive(newft,
"export_Points",
"export_Points",
"export_Points");

Second approach: 1D table

var yearly = ee.ImageCollection('JRC/GSW1_0/YearlyHistory');
// function to map over the FeatureCollection
var mapfunc = function(feat) {
  // get feature id
  var id = ee.String(feat.id())
  // get feature geometry
  var geom = feat.geometry()
  // make an empty list to store the features
  var newfc = ee.List([])
  // function to iterate over the ImageCollection
  var addProp = function(img, fc) {
    // the initial value is the empty list
    fc = ee.List(fc)
    // get the date as string
    var date = img.date().format()
    // extract the value of 'waterClass'
    var value = img.reduceRegion(ee.Reducer.first(), geom, 30).get('waterClass')
    // If the value is null then store it as 'No data'
    var val = ee.String(ee.Algorithms.If(value, ee.String(value), ee.String('No data')))
    // make the name of the feature (feat_id-date)
    var featname = ee.String("feat_").cat(id).cat(ee.String("-")).cat(date)
    // make the Feature
    var newfeat = ee.Feature(geom, {name:featname,
                                    value:val})
    // add the value to the list
    return fc.add(newfeat)
  }
  var newfeat = ee.FeatureCollection(ee.List(yearly.iterate(addProp, newfc)))
  return newfeat
};

var newft = fg_points.map(mapfunc).flatten();

Export.table.toDrive(newft,
"export_Points",
"export_Points",
"export_Points");

If features in your FeatureCollection have a name property (or something that identifies each feat) you can change in the second approach:

var id = ee.String(feat.id())

for

var id = ee.String(feat.get('name'))
4
  • 2
    I would recommend annotating the code, commenting on what, each line, is doing.
    – csheth
    Commented Oct 10, 2018 at 7:21
  • Hi, Thanks a lot Rodrigo, your answer worked for me as well. Just there was one error in the 2D table part of the answer. It should be this newf.set(date, ee.Number(value)) instead of this newf.set(date, ee.String(value)) since, I got the error that object cannot be converted to string. But thanks a ton. Commented Sep 23, 2019 at 6:48
  • Hi @user1021713, I don't think it should be like that, because date variable is a string since I apply the method .format() to the image date (which returns a string, not a number) Commented Sep 23, 2019 at 11:33
  • Hi @RodrigoE.Principe, how a row of Image IDs can be added when using your 2D table version?
    – Ayda Aktas
    Commented Apr 30, 2021 at 15:52

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.