Google Earth Engine – How to Generate Random Points Within a Masked Area

google-earth-engine

I'm trying to generate 1000 random points in areas of low tree cover across Africa and then get NDVI data for those points. I can successfully load the Global Forest Change dataset and use a mask to only show areas with 5% or less tree cover. Following suggestions from other post on here I tried to use stratifiedsample to generate my points, however I get various error messages each time I try to run it. I think this may be because the geometry of the masked area is just too complex and large to sample but I'm really not sure.

I also tried using randomPoints to generate the 1000 points across Africa but I'm not clear how I can filter this to get only points in the masked region (end result would have less then 1000 but I could always up the number of initial points generated)

The end result I would like is a FeatureCollection of 1000 points in areas of low tree cover.

Here is my code:

///Import africa boundary layer
var boundary = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017");
var africa = boundary.filter(ee.Filter.eq('wld_rgn', 'Africa'));
///Import Hansen Globel Forest Change dataset 
var gfc = ee.Image('UMD/hansen/global_forest_change_2021_v1_9').clip(africa);
var treeCover = gfc.select(['treecover2000']);
var lessthan5 = treeCover.lte(5);  // get areas with less than 5% tree cover
var treeCover_lessthan5 = treeCover.updateMask(lessthan5);
Map.addLayer(treeCover_lessthan5);
///Generating points
var samples = treeCover_lessthan5.stratifiedSample({
    region:africa,
    scale:30,
    numPoints:1000,
   geometries:true});
print(samples);
Map.addLayer(samples);
var points = ee.FeatureCollection.randomPoints(
    {region: africa, points: 1000, seed: 0, maxError: 1});
print(points);
Map.addLayer(points);

https://code.earthengine.google.com/0896d784ed501dd8800ae858bab684a6

Best Answer

One solution can be use ee.Image.sample instead of stratifiedSample. But before, will be better convert your masked area in a geometry, see the code:

///Import africa boundary layer
var boundary = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017");
var africa = boundary.filter(ee.Filter.eq('wld_rgn', 'Africa'));
///Import Hansen Globel Forest Change dataset 
var gfc = ee.Image('UMD/hansen/global_forest_change_2021_v1_9').clip(africa);
var treeCover = gfc.select(['treecover2000']);
var lessthan5 = treeCover.lte(5);  // get areas with less than 5% tree cover
var treeCover_lessthan5 = treeCover.updateMask(lessthan5);

Map.addLayer(treeCover_lessthan5);

//masked area to geometry
var vectors = treeCover_lessthan5.reduceToVectors({
  geometry: africa,
  crs: treeCover_lessthan5.projection(),
  scale: 50000,//I used  big number to reduce the effort
  maxPixels: 1e13,
  bestEffort:true,
  eightConnected: false,
});

//Map.addLayer(vectors);

///Generating points
var samples = treeCover_lessthan5.sample({
    region:vectors,
    scale:30,
    numPixels:1000,
    geometries:true});

print(samples);

Map.addLayer(samples).setShown(1);


check the code