TransWikia.com

Paint a FeatureCollection using color values stored in a property of the FeatureCollection itself

Geographic Information Systems Asked on September 30, 2021

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)

One Answer

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.

Correct answer by Kevin Reid on September 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP