4

In Google Earth Engine I have a FeatureCollection of 14,002 points. For each of the points I want to find the next nearest point's distance away. I don't need to record the nearest point ID, only the distance to it and save it in the feature. I haven't been able to find anything in the Docs that would do this.

Essentially I am trying to implement ArcMap's NEAR tool (found here: http://desktop.arcgis.com/en/arcmap/10.3/tools/analysis-toolbox/near.htm into something similar in GEE but haven't found a way yet.

1 Answer 1

4

It's a multi-step process, but can be done with a spatial join (see this doc):

var points = ee.FeatureCollection.randomPoints(geometry, 14000, 0, 10);
Map.addLayer(points, {}, 'points')

// Max search distance is 5 km.
var spatialFilter = ee.Filter.withinDistance({
  distance: 5000,
  leftField: '.geo',
  rightField: '.geo',
  maxError: 10
})

// Join the points to themselves.
var joined = ee.Join.saveAll({
  matchesKey: 'neighbors', 
  measureKey: 'distance',
  ordering: 'distance'
}).apply({
  primary: points, 
  secondary: points, 
  condition: spatialFilter
});

// Get rid of points w/o neighbors.
// Increase distance in the spatialFilter if
// you want them all to have neighbors.
var hasNearest = joined.map(function(f) {
  var neighsSize = ee.List(f.get('neighbors')).size();
  return f.set('neighsSize', neighsSize);
}).filter(ee.Filter.gt('neighsSize', 1));
Map.addLayer(hasNearest, {color: 'red'}, 'hasNearest');

// Get distance to nearest point.
var withNearestDist = hasNearest.map(function(f) {
  var nearestDist = ee.Feature(ee.List(f.get('neighbors')).get(1))
      .get('distance');
  return f.set('nearestDist', nearestDist);
});
Map.addLayer(withNearestDist, {color: 'blue'}, 'withNearestDist');

Note that you get all the neighbors, whether you want them or not.

3
  • How would you modify this if some of the points are stacked (e.g. have exactly the same lat/long) and therefore sometimes there are multiple nearest neighbors? And also just return those nearest neighbors, not the others? Thanks!
    – l_r
    Commented Jan 10, 2021 at 19:22
  • Here's the rough shape: You have all the neighbors (f.get('neighbors')) and their distances. Call distinct() on those, get the smallest distance, get all the features with the smallest distance and then do something to them. Commented Jan 11, 2021 at 14:36
  • Thank you I did get that working in the way you suggested. Question: what if you wanted this interactive, so just wanted the nearest point to where someone clicked. Is there a fast approach (using Map.getBounds() and buffer are quite slow with this many points like the Op has)
    – l_r
    Commented Feb 16, 2021 at 17:56

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.