[GIS] Nearest Pixel Value from Point Dataset Google Earth Engine

extractgoogle-earth-engine

I'm trying to extract the raster value of the nearest pixel for a group of points.

I want the value for each point rather than the mean for example. Also, some of the points are in masked areas, hence the nearest pixel value.

//import Pekel data
var gsw = ee.Image('JRC/GSW1_0/GlobalSurfaceWater');
var change = gsw.select("change_abs");


//points 
var p1 = ee.Geometry.Point([89.74319458007812,22.076065830651526])
var p2 = ee.Geometry.Point([89.87743377685547,22.0827468707419])
var p3 = ee.Geometry.Point([89.95536804199219,21.943622724707772])
var pts = ee.FeatureCollection(ee.List([ee.Feature(p1),ee.Feature(p2),ee.Feature(p3)]))


//////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////

var VIS_CHANGE = {
    min:-100,
    max:100,
    palette: ['red', 'black', 'limegreen']
};




//////////////////////////////////////////////////////////////
// Map Layers
//////////////////////////////////////////////////////////////

//Change in water intensity
Map.addLayer({
  eeObject: change,
  visParams: VIS_CHANGE,
  name: 'occurrence change intensity', 
  shown: true
});


Map.addLayer(pts, {'color': 'blue'}, 'points'); 

Best Answer

You can compute the distance to the nearest unmasked value, buffer the points by that much, and then reduce within each buffer. Something like this:

var distance = change.fastDistanceTransform().sqrt().multiply(ee.Image.pixelArea().sqrt()).rename("distance")
pts = distance.reduceRegions(pts, ee.Reducer.first().setOutputs(["distance"]))
  .map(function(f) {
    var distance = ee.Number(f.get('distance'))
    f = ee.Algorithms.If(distance, 
        f.buffer(distance.add(30), 1),
        f)
    f = ee.Feature(f)
    return f.set(change.reduceRegion(ee.Reducer.mean().unweighted(), f.geometry(), 30))
  })
print(pts)

You buffer by 1 extra pixel to make sure the buffer hits something; for the pixels that have a distance of 0, you skip the buffer step. Unweighted mean reducer will take any fraction of a pixel it encounters without normalizing by the fractional portion.

Related Question