0

I am trying to train a classifier to distinguish between snow and not snow pixels on Landsat imagery. I got the layer prepared with manually vectorized snow extent for couple of images and now want to iterate over that layer, grab the image corresponding to it from a collection, sample my points and merge the result together so I can pass it to train the classifier.

I have the code below and I am almost there - it's just not working for a collection. It works perfectly for a single image.

Why does .map behave like this and what would be the workaround?

//Prepare data
var manualSnowCover = ee.FeatureCollection(trainingPolygons);
var trainingSceneList = manualSnowCover.aggregate_array('layer'); //layer field contains product ids
var trainingScenes = lall_orig.filter(ee.Filter.inList("LANDSAT_PRODUCT_ID", trainingSceneList));
var bands = ['blue', 'green', 'red', 'nir', 'swir1', 'swir2'];

//Sample training points
var sampleTrainingData = function (img) {
  var landsatProductID = img.get("LANDSAT_PRODUCT_ID");
  //Create snow points
  var query = ee.String('layer == "productID"').replace('productID', landsatProductID);
  var manualSnowMask = manualSnowCover.filter(query);
  var snowPoints = ee.FeatureCollection.randomPoints(manualSnowMask, 1000)
  .map(function (feature) {return feature.set("class", 1);});
  //Create other land cover points - basically take image geometry and subtract snow from it
  var nonSnowMask = ee.Feature(clip_geom).difference(manualSnowMask.first());
  var nonSnowPoints = ee.FeatureCollection.randomPoints(nonSnowMask.geometry(), 1000)
  .map(function (feature) {return feature.set("class", 0);});
  //Merge together and sample the raster
  var trainingPoints = snowPoints.merge(nonSnowPoints);
  var trainingData = img.select(bands).sampleRegions({
  collection: trainingPoints,
  properties: ['class'],
  scale: 30});
  
  return trainingData;
  };

// This works fine and returns a feature collection that is usable with ee.Classifier.smileCart().train
var trainingData = sampleTrainingData(trainingScenes.first());
// This returns an empty feature collection with 12 elements and 0 columns 
var trainingData = trainingScenes.map(sampleTrainingData);
print(trainingData);

Result from mapping over image collection

1 Answer 1

0

The answer is as simple as - flatten your resulting feature collection.

When you apply .map() to an image collection, it returns a feature collection, where each element is result of method applied to a specific image. Each element is also a feature collection. So, at the end you get feature collection of feature collections. Applying simple .flatten() will do a job:

var ic = ee.ImageCollection("LANDSAT/LC08/C01/T2_SR"),
    trainingPolygons = /* color: #98ff00 */ee.FeatureCollection(
        [ee.Feature(
            ee.Geometry.Polygon(
                [[[-87.07011718750002, 32.17998116455555],
                  [-87.48759765625002, 31.24539831823601],
                  [-86.14726562500002, 31.170226036751586]]]),
            {
              "system:index": "0"
            })]);
            
//Prepare data
var trainingScenes = ic.filterBounds(trainingPolygons).limit(10)

//Sample training points
var sampleTrainingData = function (img) {
  var trainingData = img.sample({
  numPixels:100,
  scale: 30});
  return trainingData;
  };

// This works fine and returns a feature collection 
var trainingData = sampleTrainingData(trainingScenes.first());
// This returns an empty feature collection with 12 elements and 0 columns 
var trainingData = trainingScenes.map(sampleTrainingData);
print(trainingData);

print('Flattened Feature Collection')
print(trainingData.flatten());

Also, please, when you submit your question, share the link to the code that reproduces the error or presents the issue that you encounter (so, it can be run without modification). Otherwise, instead of directly helping you, one needs first to reproduce your problem and do a lot of guessing about your input data and the datasets that you are using.

For your convenience, example of your simplified question with an implemented fix: https://code.earthengine.google.com/2134add8bd4a98d9c0e20d73a560beb3

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.