Google Earth Engine – Extracting Pixel Values by Points from Multi-Band Image and Converting to Table

google-earth-enginegoogle-fusion-tablessentinel-1

I would like to extend this answer to Extracting pixel values by points and converting to table in Google Earth Engine? in order to extract values from a multi-band image.

I am using the example linked to manually select the band and export each GLCM texture measure as a 2D table (w/ values from each scene ID in columns). I was hoping to run it as a single command (based on original answer from Rodrigo Principe). The solution can either write a file for each texture (in a loop) or export a single, really wide table.

The collection is Sentinel-1 and the IW_H_OG is a feature collection of images over a study region (with the data converted from dB back to Original scale for GLCM calculations).

I've tried placing the mapfunc function in a for loop, but can't seem to get it right. I've also tried lopping the .get("VH_diss"); off the end of the value variable (this might be working but GEE takes ages to export even a small test subset- so unsure if this is the simple solution).

I've pasted the tail end of the code below. please excuse all the extra comments, I'm still coming to grips with JavaScript.

    //subset out only the GLCMs I want
        function subset(IMG){
          return IMG.select([0,1,2,3,4,5,8,14,18,19,20,21,22,23,26,32]); 
          }
        var glcm_sub = IW_H_OG_glcm.map(subset);

    // create function that extracts pixel values for each point 
    // from each image and writes to a table
    var mapfunc = function(feat) {
      var geom = feat.geometry();
      var addProp = function(IMG, f) {
        var newf = ee.Feature(f);

        // MY (BAD) WAY OF GETTING DATE INFO- STILL DEBUGGING
        var date = IMG.get('system:index');

        // SELECT BAND HERE- haven't figured out how to grab all
        var value = IMG.reduceRegion(ee.Reducer.first(), geom, 10).get("VH_diss");
        return ee.Feature(ee.Algorithms.If(value,
                                           newf.set(date, ee.String(value)),
                                           newf.set(date, ee.String('No data'))));
      };
      var newfeat = ee.Feature(glcm_sub.iterate(addProp, feat)); 
      return newfeat;
    }; // end of function


    // now apply function (with map) to our FeatureCollection (the cuts)
    // like ratio, these will be calculated and left on the OG scale
    var MY_pixels = myPoints.map(mapfunc);
    //print(MY_pixels.first());
    //01 VV_asm
    //02 VV_contrast
    //03 VV_corr
    //04 VV_var
    //05 VV_idm (homogeneity- Inverse Difference Moment)
    //06 VV_savg
    //07 VV_ent
    //08 VV_diss
    //09 VH_asm
    //10 VH_contrast
    //11 VH_corr
    //12 VH_var
    //13 VH_idm 
    //14 VH_savg
    //15 VH_ent
    //16 VH_diss



    // export to drive
    Export.table.toDrive(MY_pixels,
    "Jam_III_2015_GLCM_16-16", //job name
    "test_GEE_export", //folder name
    "Jam_III_2015_GLCM_16-16"); //file name

Best Answer

For a single (and big) table it's just one more piece of the mamushka:

var mapfunc = function(feat) {
  var geom = feat.geometry()
  var addProp = function(img, f) {
    var newf = ee.Feature(f)
    var date = img.date().format('yyyy-MM-dd')
    var bands = img.bandNames()
    var value = img.select(bands)
    .reduceRegion(ee.Reducer.first(), geom, 30)

    var fun = function(name, ini) {
      var ini = ee.Feature(ini)
      var val = value.get(name)
      var newname = ee.String(date).cat('-').cat(name)
      return ee.Feature(ee.Algorithms.If(val,
                        ini.set(newname, ee.String(val)),
                        ini.set(newname, ee.String('No data'))))
    }

    return ee.Feature(bands.iterate(fun, newf)) 

  }
  var newfeat = ee.Feature(glcm_sub.iterate(addProp, feat))
  return newfeat
};

and for exporting one table per band you have to make some client-side code because Export is a client-side function

var compute_band = function(bandname) {
  var mapfunc = function(feat) {
    var geom = feat.geometry()
    var addProp = function(img, f) {
      var newf = ee.Feature(f)
      var date = img.date().format('yyyy-MM-dd')
      var value = img.reduceRegion(ee.Reducer.first(), geom, 30).get(bandname)
      return ee.Feature(ee.Algorithms.If(value,
                                         newf.set(date, ee.String(value)),
                                         newf.set(date, ee.String('No data'))))
    }
    var newfeat = ee.Feature(glcm_sub.iterate(addProp, feat))
    return newfeat
  };
  return fg_points.map(mapfunc);
}

var bands = glcm_sub.bandNames().getInfo()
for (var band in bands) {
  var name = bands[band]
  var table = compute_band(name)
  // export to drive
  Export.table.toDrive(table,
  "Jam_III_2015_GLCM_16-16-"+name, //job name
  "test_GEE_export", //folder name
  "Jam_III_2015_GLCM_16-16-"+name); //file name
}
Related Question