1

I'm trying to plot the ESA CCI land cover map using the palette that they define in their .csv download. I managed to import this palette into GEE by saving it as a shapefile with a dummy geometry (using R), which I'm hoping I've made publicly available here.

I'm testing it out by changing the palette in GEE's Image Visualization tutorial (for a different land cover dataset, but I'll stick with it for simplicity). So, first, I load the MODIS land cover:

// Load 2012 MODIS land cover and select the IGBP classification.
var cover = ee.Image('MODIS/051/MCD12Q1/2012_01_01')
  .select('Land_Cover_Type_1');

Then I define my alternative palette:

// Load alternative colour palette
var cciPalette = 
  ee.List(
  ee.FeatureCollection('users/rasenior/cci_landcover_legend')
 .aggregate_array('hex'));

// Remove '#' symbol and make lower case
var replace = function(name){
  return (ee.String(name).replace('#', '').toLowerCase());
}; 
var cciPalette2 = cciPalette.map(replace);
print(cciPalette2);

The console tells me that cciPalette2 is a list, and everything looks good. It looks just like the igbpPalette from the tutorial (a longer list because CCI have more land cover categories). But when I sub cciPalette2 in for igbpPalette:

Map.setCenter(-99.229, 40.413, 5);
Map.addLayer(cover,
             {min: 0, max: 17, palette: cciPalette2},
             'CCI classification');

I get the error:

CCI classification: Layer error: Image.visualize: Expected a string or list of strings for field 'palette'.

But cciPalette2 is a list of strings, no? What am I doing wrong? I'm a total GEE and javascript novice so I'm sure I'm missing something simple.

Full code here: https://code.earthengine.google.com/be1102eda2fb41584e9be3697f42b48e

1

To generate layer you need to have a palette on the client side that gets sent to GEE to generate the map. Since you are generating palette based on aggregating a property in a feature collection, the ccgiPalette2 is neither a string nor a list of strings but a computed object type instead. You can use the evaluate or getInfo function to address this.

var cciPalette2 = cciPalette.map(replace).getInfo();

Would be the simplest solution, and your script will work without further changes but since getInfo is deprecated i recommend using evaluate function instead which works by setting up a callback function.

cciPalette.map(replace).evaluate(function(cciPalette2){
  // Map again
  Map.setCenter(-99.229, 40.413, 5);
  Map.addLayer(cover,
               {min: 0, max: 17, palette: cciPalette2},
               'CCI classification');
});

The good thing about evaluate is that it does not freeze the UI while the data is being fetched.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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