GEE Reclassify Pixel Values – How to Reclassify Multiple Ranges of Pixel Values on Image Collection in GEE

google-earth-enginereclassify

Code editor script here

I have an image collection of PDSI from Terraclimate over a 20-year period, filtered by a bbox. I want to remap ranges of PDSI values into five different classes of drought intensity, and map that over the entire collection of images.

I know how to remap a single range of values to an entire image collection using the ee.Image.remap method (see Test 3 in script):

// create image collection:
var pdsi = ee.ImageCollection('IDAHO_EPSCOR/TERRACLIMATE')
.filter(ee.Filter.date(startDate, endDate))
.filterBounds(bbox)
.select('pdsi');

var mild_o = ee.List.sequence(-199, -100)
var mild_n = ee.List.sequence(1, 1, 1, 100) // 100 = range

var remapped = pdsi.map(function(image){
  return image.remap(mild_o, mild_n, 0);  // else value = 0
});
print(remapped.first())
Map.addLayer(remapped.first(), {}, "TEST 3: grouped remap statements")

And using the ee.Image.gte/lte (see Test 1 in script) method:

var remapped_func = function(img, lowerLimit, upperLimit, newValue) {
  var mask = img.gte(lowerLimit).and(img.lte(upperLimit))
  return img.where(mask, newValue)
};

// values from -100 to -199 will be 1 (moderate), the rest will not change
var mild = withDate.map(function(img){
  return img.map(remapped_func(withDate, -100, -199, 1))
});

However, my goal is to remap a series of ranges that cover all the pixel values of a given image in the collection. So I have tried two methods:

  1. ee.Image.remap:
var moderate_o = ee.List.sequence(-299, -200)
var moderate_n = ee.List.sequence(2, 2, 1, 100) 
var extreme_o = ee.List.sequence(-399, -300)
var extreme_n = ee.List.sequence(3, 3, 1, 100) 
var severe_o = ee.List.sequence(-4000, -400) // max value (aka highest value of severe drought)
var severe_n = ee.List.sequence(4, 4, 1, 3601) 
//var nodrought_o = ee.List.sequence(-99)  // min value (aka lowest value of no drought)
//var nodrought_n = ee.List.sequence(0, 0, 1) 

// try a grouped version where you map over all value ranges
var remap_all = pdsi.map(function(image){
  return image.remap(mild_o, mild_n, 
  image.remap(moderate_o, moderate_n, 
  image.remap(extreme_o, extreme_n, 
  image.remap(severe_o, severe_n, 0)
)))});
print(remap_all.first())
Map.addLayer(remap_all.first(), {}, "TEST 3: grouped remap statements")

This produces an error because, understandably, the remap syntax is incorrect (instead of a false value, I've inserted another remap statement).

  1. ee.Image.where:
var test2 = pdsi.map(function(img) {
  return img.where(img.lte(-100).and(img.gte(-199)), 1)
  .where(img.lte(-200).and(img.gte(-299)), 2)
  .where(img.lte(-300).and(img.gte(-399)), 3)
  .where(img.lte(-400), 4)
  .where(img.gte(-99), 0)
})
print(test2)
Map.addLayer(test2.first(), {}, "TEST 2: grouped where statements")

The images produced by this operation misclassifies everything to zero.

Best Answer

You are mistaken about test2; it is working, you are only looking at 1 image, in a small region where that image has roughly the same value. If you zoom out, or inspect the entire collection, you'll see variation.

However, your math is equivalent to dividing by -100 and taking the ceiling; that would be much faster & easier.

 return img.multiply(-1).divide(100).int().clamp(0, 4)
Related Question