0

Starting with an example shown here: https://groups.google.com/g/google-earth-engine-developers/c/w20Unaq6zCw/m/a8HrcpqSCAAJ

How would I modify the code below to Paint using a Color value stored as a property in the FeatureCollection. So, for example, in the regions variable below, {name: 'Rice'} is instead stored as {Color: 'blue'}

Then, rather than having the palette variable hard-coded as below, the palette would come from this Color property stored in the feature. Note that I won't know ahead of time how many different colors are stored in the featurecollection.

This seems like it should be straightforward, but I cannot get it to work.

//specify regions corresponding to different vegetation types, here as representative rectangles with specified coordinates
var regions = ee.FeatureCollection([
 ee.Feature(ee.Geometry.Rectangle(-121.657, 38.109, -121.654, 38.108), {name: 'Rice'}),
 ee.Feature(ee.Geometry.Rectangle(-122.024, 38.199, -122.02, 38.197), {name: 'Annual grassland'}),
 ee.Feature(ee.Geometry.Rectangle(-121.875, 37.847, -121.873, 37.8455), {name: 'Forest'}),
 ee.Feature(ee.Geometry.Rectangle(-121.803, 37.8615, -121.8015, 37.8603), {name: 'Shrubland'}),
 ee.Feature(ee.Geometry.Rectangle(-121.825, 38.049, -121.823, 38.0473), {name: 'Wetland'}),
 ee.Feature(ee.Geometry.Rectangle(-121.825, 38.049, -121.823, 38.0473), {name: 'Wetland'}),
 ee.Feature(ee.Geometry.Rectangle(-121.825, 38.049, -121.823, 38.0473), {name: 'Wetland'}),
]);

function categorize(fc, prop) {
  var uniqueValues = ee.List(fc.distinct(ee.SelectorSet(prop)).sort(prop).aggregate_array(prop))
  
  return fc.map(function(f) {
    return f.set(prop + '_category', uniqueValues.indexOf(f.get(prop)))
  })
}

var count = regions.aggregate_count_distinct('name').getInfo();

var palette=['FF0000','00FF00','0000FF', '8b4500', '000000', '00FFFF'];
var regionsimage=ee.Image().toByte();
var paintimage=regionsimage.paint(categorize(regions, 'name'), 'name_category', 4);
Map.addLayer(paintimage, {palette:palette, min:0, max:count});

Map.centerObject(regions)
2

Image.paint() is unsuitable for this purpose; despite talking about colors, it actually produces "monochrome" results, in that you're specifying only one band value or "luminance". In order to use actual RGB colors per-feature, you need to use FeatureCollection.style() instead, which lets you store colors (in fact, an entire dictionary of custom styling of your choice) on the individual features.

var palette = ee.Dictionary({
  'Annual grassland': 'FF0000',
  'Forest': '00FF00',
  'Rice': '0000FF',
  'Shrubland': '8b4500',
  'Wetland': '000000',
});

var image = regions
  .map(function (feature) {
    // Add a style-dictionary property using our chosen palette
    return feature.set('myStyle', {
      'color': palette.get(feature.get('name')),
    });
  })
  .style({
    'styleProperty': 'myStyle',
  });
Map.addLayer(image, {});

https://code.earthengine.google.com/0891dabf7a16a40ed736c28f9319e94f

In this case, I am using FeatureCollection.map() to add styling based on your existing name property, but if you would rather write the colors into your data from the start, you can do that instead. Note that the value of the style property myStyle must be a dictionary; if you're starting with a property whose value is a color string, you'll need to create the style dictionary from that.

1
  • Great, this helped a lot! I updated in the link here to use a Color property stored in the FeatureCollection itself as the basis for the styling (since I won't know what the palette is ahead of time since I won't know what colors are in the FeatureCollection Color property): code.earthengine.google.com/70bcc2f79586af54c58ef69e0373b2f4 – l_r Jul 28 '20 at 20:14

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.