Google Earth Engine – Converting Points to Raster (Image)

google-earth-enginejavascriptrasterization

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.

Best Answer

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!

Related Question