1

I have a bunch of points representing bird observations, and I need to convert this to an image in GEE where each pixel value is the total number of observations in each 1 km pixel. This is a very common task with ecological data, and in ArcGIS I would use Point to Raster. But I can't figure out what the equivalent would be in GEE.

As an example, here are some points and a bounding polygon:

var points = ee.Feature(ee.Geometry.MultiPoint(
    [[57.43610672115551, -20.298790475544028],
     [57.566569367639886, -20.221490947834383],
     [57.695658723108636, -20.319397176387103],
     [57.676432648889886, -20.171225637115814],
     [57.58991531490551, -20.216336278108052],
     [57.57892898678051, -20.225356838032646],
     [57.572062531702386, -20.227934044777072]]),{});

var poly =
  ee.Feature(
    ee.Geometry.Polygon(
    [[[57.36469558834301, -20.087414125113316],
      [57.36469558834301, -20.499588506612334],
      [57.85908035396801, -20.499588506612334],
      [57.85908035396801, -20.087414125113316]]], null, false), {});

So the resulting image should have the extent of poly, a scale of 1 km, and pixel values corresponding to the number of points in each pixel. I thought reduceToImage would do this, but that seems to be more for summarising properties of polygon geometries.

1

The reduceToImage function only converts a featureCollection to an Image with unknown spatial information (no scale or projection) based on a property you select. You will have take the undefined Image and perform some operations to get point count per pixel. You do this by projecting the converted image and then reducing the image scale to desired resolution with a reprojection, however, there are some fun EE quirks with reduceResolution along the way. Here is an example:

var points = ee.Feature(ee.Geometry.MultiPoint(
    [[57.43610672115551, -20.298790475544028],
     [57.566569367639886, -20.221490947834383],
     [57.695658723108636, -20.319397176387103],
     [57.676432648889886, -20.171225637115814],
     [57.58991531490551, -20.216336278108052],
     [57.57892898678051, -20.225356838032646],
     [57.572062531702386, -20.227934044777072]]),{});

var poly =
  ee.Feature(
    ee.Geometry.Polygon(
    [[[57.36469558834301, -20.087414125113316],
      [57.36469558834301, -20.499588506612334],
      [57.85908035396801, -20.499588506612334],
      [57.85908035396801, -20.087414125113316]]], null, false), {});

// add dummy property to use for reduceToImage
points = ee.FeatureCollection(points).map(function(feature){
  return feature.set('dummy',1);
});

// specify scale in meters to project point Image to
var ptScale = ee.Number(50);

// convert featureCollection to Image and add geoinformation
var ptImg = points.reduceToImage(['dummy'],ee.Reducer.firstNonNull())
  .unmask(0) // take into account areas without points for reduction
  .reproject('epsg:4326',null,ptScale);

// specify output scale, in this case 1km
var outScale = ee.Number(1000);

// reduce resolution of Image and reproject from ptScale to outScale and clip to polygon
var countImg = ptImg.reduceResolution(ee.Reducer.mean(),false,1024)
  .reproject('epsg:4326',null,outScale).clip(poly)
  // perform some operations to convert reduced weighted pixel image to meaningful values
  // these conversions are based on pixel scale
  // use hard coded values to prevent weird results from EE display request scaling
  .multiply(outScale.pow(2)).divide(ptScale.pow(2)).round().int();

// display results!
Map.addLayer(poly,{color:'gray'},'RoI');     
Map.addLayer(countImg,{min:0,max:3},'Point Counts');
Map.addLayer(points,{color:'yellow'},'Points');

Here is a working link. I hope this help!

0

Based on Kel's code, here is another solution. The key is to transform the MultiPoint Geometry to a list of Point Geometry.

var multiPts = ee.Geometry.MultiPoint(
    [[57.43610672115551, -20.298790475544028],
     [57.566569367639886, -20.221490947834383],
     [57.695658723108636, -20.319397176387103],
     [57.676432648889886, -20.171225637115814],
     [57.58991531490551, -20.216336278108052],
     [57.57892898678051, -20.225356838032646],
     [57.572062531702386, -20.227934044777072]]);
var poly =
  ee.Feature(
    ee.Geometry.Polygon(
    [[[57.36469558834301, -20.087414125113316],
      [57.36469558834301, -20.499588506612334],
      [57.85908035396801, -20.499588506612334],
      [57.85908035396801, -20.087414125113316]]], null, false), {});

var Points = ee.Feature(multiPts, {});

var coords = multiPts.coordinates();
var FeaCol = ee.FeatureCollection(coords.map(function(pt){
  return ee.Feature(ee.Geometry.Point(pt), {}).set('dummy2', 1);
}));
var FeaColImg = FeaCol.reduceToImage(['dummy2'], ee.Reducer.sum())
  .unmask(0)
  .reproject('epsg:4326', null, 1000);

// display
Map.addLayer(poly, {color : 'gray'}, 'RoI');     
Map.addLayer(FeaColImg.clip(poly), {min : 0, max : 3}, 'Point Counts');
Map.addLayer(Points, {color : 'yellow'}, 'Points');
  • Hi and welcome to GIS.SE! Thank you for posting your solution, but could you please provide a little more context so that novice GIS users/coders can understand your solution a little better? – root676 Sep 10 at 9:15
  • @root676 Thank you for your advice, and I am sorry for replying so late. Here is my explanation. When the points representing bird observations is imported to GEE by MultiPoint and Feature, there is only one feature in FeatureCollection that refers all points. So we can't use reduceToImage with scale 1000 to get the number of observations in pixel directly if some are nearer than 1km. My solution is to transform the MultiPoint Geometry to a list of Point Geometry. So they will be discrete geometries by map and Feature, and reduceToImage with scale 1000 can work directly. – wangyh Sep 16 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.