12

New user of Earth Engine and Javascript here. I have a FeatureCollection of points. These points are field observations where researchers have marked water sources, and noted whether or not they were dry at the time of observation. Basically, I would like to display these points in GEE with a different color for "dry" and "wet" observations. The water status is the "water_stat" property of each feature. I figure I should be able to assign a color for each status, but I haven't been able to work it out.

So far, I have tried FeatureCollection.draw(), but there doesn't seem to be an easy way to draw unique colors based on a feature property.

I have also tried Image.paint(), but I can't control the radius of the points that are displayed on the map: it only colors one pixel for each point. If I can get it to color more than one pixel, I think I can figure out how to get it to color those points uniquely - but I'm not going down that road if I can't figure out the one-pixel problem first.

So, I see two options: 1) figure out how to FeatureCollection.draw() with different colors, or 2) figure out how to control the radius of points, using Image.paint() - possibly by buffering the points somehow. Any ideas on how to work out either of these approaches? Code is linked and displayed below.

https://code.earthengine.google.com/8c9787c9a118b7661f62355f0715c9ef

    //This script adds field observations of water presence to the map.

   // Import features
   var fieldObs = ee.FeatureCollection("users/ansoncall/FieldObservations");

  // Adds the field observations to the map. 
  Map.addLayer(fieldObs.draw({color: 'ff0000', pointRadius: 5}), {}, 'Field 
  Observations'); //Can't add unique colors with .draw()??

  // Create an empty image into which to paint the features, cast to byte.
  var emptyObs = ee.Image().byte();

  // Paint all the polygon edges with the same number and width, display.
  var outlineObs = emptyObs.paint({
    featureCollection: fieldObs,
    color: 1, // Can enter a feature property if different colors are needed 
  for different features. Not done yet but I think I can figure out that 
  part
  });

  // Add custom color layer to map
  Map.addLayer(outlineObs, {palette: '#00ff00'}, 'Color-Coded 
  Observations'); //Only ONE pixel is colored!

  // Prints the field observations to the console
  print(fieldObs, 'Field Observations'); //
1
  • 1
    What would be the method to do the same but we have a continuous instead of 2 categories? For example if I want to draw darker colors for places with higher levels of a property (like humidity)
    – Raimundo
    Commented Feb 19, 2019 at 22:47

2 Answers 2

15

The Google Earth Engine Developers group just provided two solutions - one quick fix and one more elegant.

The quick fix - filter out the "wet" features, then add those as a unique layer. Then filter out the "dry" features, and add those as a second layer. Here's the code used to filter out wet features:

    var Wet = ee.FeatureCollection(fieldObs.filter(ee.Filter.eq('water_stat', 'Wet')));
    print(Wet)

The more elegant solution was provided by Noel Gorelick:

Map over the features, give each feature a "style" dictionary containing a >"color" property based on its status.
Then call collection.style(), passing the name of the style dictionary >property. See this example: https://code.earthengine.google.com/a9ba80f9d412c918f3499261f5d435e7

In Noel's method, the entire FeatureCollection can be added as a single layer, with unique colors based on feature properties. Just what I was looking for.

3

This is essentially the same as Noel's method mentioned by Anson, but less verbose. Instead of creating a new feature, I just set the properties of the old feature.

// make a feature collection and add to map
var fc = ee.FeatureCollection([
  ee.Feature(ee.Geometry.Point([0,0]), {class: 0}),
  ee.Feature(ee.Geometry.Point([0,1]), {class: 1})
])
Map.addLayer(fc, {}, 'no color')
Map.centerObject(fc)

// function to conditionally set properties of feature collection
var setPointProperties = function(f){ 
  var klass = f.get("class") // 0 or 1
  var mapDisplayColors = ee.List(['0000ff', 'ff0000']); // class 0 should be blue, class 1 should be red
  
  // use the class as index to lookup the corresponding display color
  return f.set({style: {color: mapDisplayColors.get(klass)}})
}

// apply the function and view the results on map
var styled = fc.map(setPointProperties)
Map.addLayer(styled.style({styleProperty: "style"}), {}, 'conditionally styled')

https://code.earthengine.google.com/?scriptPath=users%2Fcaseyengstrom%2Freprex%3AconditionallyStyleFeatures

Your Answer

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

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