0

I'm trying to get population density data from Google Earth Engine but i get an error.

Line 17: gpw_roi.reduceRegions is not a function

// Load GPW population count dataset
var gpw = ee.ImageCollection('CIESIN/GPWv4/population-count');

// Define the area of interest (AOI) using a polygon geometry
var aoi = ee.Geometry.Polygon([
  [-74.1, 40.6],
  [-74.1, 40.7],
  [-73.9, 40.7],
  [-73.9, 40.6],
]);

// Filter the GPW dataset to the AOI
var gpw_roi = gpw.filterBounds(aoi);

// Function to calculate population for each feature in the collection
var calculatePopulation = function(feature) {
  var population = gpw_roi.reduceRegions({
    reducer: ee.Reducer.sum(),
    collection: feature.geometry(),
    scale: 1000, // Scale in meters (adjust based on your area size and resolution)
  });
  return feature.set('population_count', population.first().get('population-count'));
};

// Map the function over the FeatureCollection and calculate population for each area
var populationCounts = gpw_roi.map(calculatePopulation);

// Print the population counts
print('Population Counts:', populationCounts);

What could be wrong with the script? How can i get the population count?

Shadow Walker
  • 979
  • 5
  • 27
  • 51

1 Answers1

0

gpw_roi is an ee.ImageCollection. reduceRegions is an operation on single ee.Images, not ee.ImageCollections.

Before you can apply reduceRegions you must select a single image or combine multiple images. It looks like you tried to map over each image of gpw_roi, but you didn't use the right variable name. Change this line:

  var population = gpw_roi.reduceRegions({

to

  var population = feature.reduceRegions({

Now the code works. However, since feature is the image, not your aoi, collection: feature.geometry() probably won't be the region you wanted. Also, since you have only one polygon, reduceRegions is not needed and reduceRegion is more applicable. Consider doing this instead:

var calculatePopulation = function(image) {
  var population = image.reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: aoi,
    scale: 1000,
  });
  return image.set('population_count', population.get('population-count'));
};

(In addition to the changes I already mentioned, I renamed the mapping variable to image since it is an image.)

This will sum the values over the bounds of aoi, not the bounds of the image, which is probably what you meant.

However, there's one more problem left: this will not give you a precise population count. Instead, it samples the input image on an 1 km grid (scale: 1000) which is not necessarily the pixel grid of the original image, so it doesn't give you the population count within aoi, but a sum of those samples. Instead, you should leave out the scale parameter, so that it counts all of the original image's pixels within the bounds. Since the image's documented resolution is "30 arc-second (approximately 1km) grid cells", this is almost the same value, but you might as well be precise and make your code simpler by leaving out the scale.

var calculatePopulation = function(image) {
  var population = image.reduceRegion({
    reducer: ee.Reducer.sum(),
    geometry: aoi,
  });
  return image.set('population_count', population.get('population-count'));
};
Kevin Reid
  • 37,492
  • 13
  • 80
  • 108