1

I'm trying to find the lowest 20th percentile figure and corresponding area across different geographies defined by an image.

The image is obtained from the multiplication of 2 images, which has produced many disparate polygons in brown (soil taxonomy and slope). See below.

var img1a = soiltaxa.eq(389).and(slope0206Mask);
Map.addLayer(img1a.updateMask(img1a),{palette:'brown'},'1a');

Brown polygons produced by the multiplication of a soil taxonomy image and a slope image

Separately, I created a single band for soil carbon below in black.

var SOC = socc.multiply(bd)
  .multiply(5*0.1*10000/(250*250)) 
  .clip(region);
var imgSOC30 = ee.Image(SOC.select('b0','b10','b30'));
var SOC30 = imgSOC30.reduce('sum');
Map.addLayer(SOC30,{min:12,max:242},'SOC30',0);

Map of soil carbon

I want to find the lowest 20th percentile and corresponding area of the single band represented in the bottom picture in monochrome (soil carbon) for just the brown geographies in the top picture.

The issue seems to be that the brown polygons in the top picture are an Image. How do I use Google Earth Engine to calculate the the lowest 20th percentile soil carbon and corresponding area for just the brown polygons?

The code below works if I substitute "img1a" for a geometry, but when I use "img1a", I get an error message saying: Dictionary (Error) Image.reduceRegion, argument 'geometry': Invalid type. Expected type: Geometry. Actual type: Image<[grtgroup]>.

var SOC30percgeo = SOC30.reduceRegion({
  reducer: ee.Reducer.percentile([20,50,80]),
  geometry: img1a,
  scale: 250, // Resolution in meters.
  maxPixels: 1e9});
print('SOC30 percentiles for geo',SOC30percgeo);

// Get lowest 20th percentile SOC30 for geo. 
var DegradedSOC30geo = SOC30.clip(img1a).lte(ee.Number(SOC30percgeo.get('sum_p20')));
Map.addLayer(DegradedSOC30geo.updateMask(DegradedSOC30geo),{palette:'red'},'Degraded SOC30 geo');

// Get pixel area for geo degraded and convert to ha. 
var DegradedSOC30geoArea = DegradedSOC30geo.multiply(ee.Image.pixelArea()).divide(10000); 

// Sum pixels for geo degraded.
var DegradedSOC30geoSize = DegradedSOC30geoArea.reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: img1a,
  scale: 250, // Resolution in meters
  maxPixels: 1e9
});
print('degraded area in geo: ',DegradedSOC30geoSize,'ha');

2 Answers 2

1

When reducing SOC30, to only include "brown pixels" in img1a, you could mask SOC30 with the mask of img1a: SOC30.updateMask(img1a.mask()).

The geometry property in reduceRegion() must be an ee.Geometry. If SOC30 is a bounded image, you can omit it all together, and the footprint of SOC30 will be used. If you want to use the footprint of img1a, you set it to img1a.geometry(). Looking at your code, it seems like you have some explicit region you're interested in - your region variable. If that's the case, this would probably be the geometry you should used.

This should hopefully work for you:

var SOC30percgeo = SOC30
  .updateMask(img1a.mask())
  .reduceRegion({
    reducer: ee.Reducer.percentile([20, 50, 80]),
    scale: 250, // Resolution in meters.
    maxPixels: 1e9
  })

// Get lowest 20th percentile SOC30 for geo. 
var DegradedSOC30geo = SOC30
  .updateMask(img1a.mask())
  .lte(SOC30percgeo.getNumber('sum_p20'))

Map.addLayer(DegradedSOC30geo, {palette: 'red'}, 'Degraded SOC30 geo')

// Get pixel area for geo degraded and convert to ha. 
var DegradedSOC30geoArea = DegradedSOC30geo
  .multiply(ee.Image.pixelArea())
  .divide(10000)

// Sum pixels for geo degraded.
var DegradedSOC30geoSize = DegradedSOC30geoArea
  .reduceRegion({
    reducer: ee.Reducer.sum(),
    scale: 250, // Resolution in meters
    maxPixels: 1e9
  })
print('degraded area in geo: ', DegradedSOC30geoSize, 'ha')

https://code.earthengine.google.com/2063800b7cc1d4e45d3af842925f6b77

0

Thanks! It turned out I had to convert img1a from a raster into a vector for it to work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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