google-earth-engine – Calculate Distance Between Points and Polygon in a Feature Collection in GEE

distancegoogle-earth-enginegoogle-earth-engine-javascript-apiproximity

I have a feature collection containing 100 points and a raster of ice present in Greenland. My goal is to calculate the distance between each individual point and the patch of ice closest to that point. I have used the following code but the export results in all zeroes.

var ROI = ee.Geometry.Polygon([-51.835,66.947],
                              [-49.626,66.947],
                              [-49.626,67.479],
                              [-51.835,67.479],
                              [-51.835,66.947]);

var points = ee.FeatureCollection.randomPoints({
              region: ROI,
              points: 100,
              seed: 0,
              maxError: 1
});

var gimp_mask = ee.Image('OSU/GIMP/2000_ICE_OCEAN_MASK');

var ice = gimp_mask.select('ice_mask').eq(1).reduceToVectors({
  geometry: ROI,
  scale: 90,
  crs: 'EPSG:4326',
  maxPixels: 1e13
}).geometry();

var proxToIce = ee.FeatureCollection(points).map(function(feat){
  var point = feat.geometry();
  var dist = ice.distance({'right': point, 'maxError': 1})
  return feat.set({'distance': dist})
});

Export.table.toDrive({
  collection: proxToIce,
  folder: 'variable_data',
  description: 'iceDit_data_test',
  fileFormat: 'CSV'
})

I have also tried calculating distance from the ice using a Euclidean kernel and using reduceRegions with the point data but this is too memory intensive for the scale I am operating on (the ROI and number of points in the code above are for example only).

Any help on what I may be doing wrong or an alternative way of approaching this would be greatly appreciated.

Best Answer

reduceToVectors produces polygons for every pixel, so even though you've tested for ice == 1, there's still a bunch of not-ice pixels in your image, and there's a not-ice polygon. So you're getting 0s because the distance to the not-ice polygon is 0.

Mask off the not-ice part before reduceToVectors.

gimp_mask.select('ice_mask').eq(1).selfMask().reduceToVectors(

Also, if you plan to scale this up, you could just use fastDistanceTransform on the raster and sample that with reduceRegions, and not need to go through reduceToVectors. If you're really just going with 100 points in this limited region, don't bother; you're already there.

Related Question