1

This is a follow up question on (Extract and plot from an Array in GEE) but can also be treated as a standalone question.

I want to run a LandTrendr analysis for a given number of points (coordinates) and write the results into a table such as

feature.id | year | original | fitted
00_00      | 2001 | 1001.00  | 1002.10
00_01      | 2002 | 1021.00  | 1050.20
...
01_00      | 2001 | 2001.00  | 2002.10
01_01      | 2002 | 3001.00  | 3002.10
...

My function over the FeatureCollection is not working and I can't get it right.

// Points
var p1 = ee.Geometry.Point([-122.64550158728298,38.44643840127136]);
var p2 = ee.Geometry.Point([-123.06960473413164,38.54089331487732]);
var p3 = ee.Geometry.Point([-122.85149523962673,38.33988067525676]);
var fg_points = ee.FeatureCollection(ee.List([ee.Feature(p1),ee.Feature(p2),ee.Feature(p3)]));

Map.setCenter(-122.64550158728298,38.44643840127136, 11);
Map.addLayer(feat);

// load LandTrendr module
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');

// define parameters
var startYear = 1985;
var endYear = 2018;
var startDay = '06-20';
var endDay = '09-20';
var index = 'NBR';
var ftvList = ["NBR"];
var maskThese = ['cloud', 'shadow', 'snow'];

//// function to map over the FeatureCollection
var mapfunc = function(feat) {

  var geom = feat.geometry()

  var collection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, geom, maskThese)
  var timeSeries = ltgee.buildLTcollection(collection, index, ftvList)

  var lt = ee.Algorithms.TemporalSegmentation.LandTrendr({ 
    timeSeries:             timeSeries,
    maxSegments:            6,
    spikeThreshold:         0.9,
    vertexCountOvershoot:   3,
    preventOneYearRecovery: true,
    recoveryThreshold:      0.25,
    pvalThreshold:          0.05,
    bestModelProportion:    0.75,
    minObservationsNeeded:  6
  });

  var fittedImage = ltgee.getFittedData(lt, startYear, endYear, index);

  var fittedCollection = ee.ImageCollection(fittedImage.bandNames()
  .map(function (yearString) {
    yearString = ee.String(yearString);
    return fittedImage.select(yearString)
      .set('system:time_start', ee.Date.parse('yyyy', yearString).millis())
      .rename('Fitted');
  })
  ); 

  // get feature id
  var id = ee.String(feat.id());

  // make an empty list to store the features
  var newfc = ee.List([])
  //// function to iterate over fittedCollection
  var addVals = function(img, fc) {
    // the initial value is the empty list
    fc = ee.List(fc)
    // get the date as string
    var date = img.date().format()
    //// extract the value of 'Fitted'
    var value = img.reduceRegion(ee.Reducer.first(), geom, 30).get('Fitted')
    // If the value is null then store it as 'No data'
    var val = ee.String(ee.Algorithms.If(value, ee.String(value), ee.String('No data')))
    // make the name of the feature (feat_id-date)
    var featname = ee.String("feat_").cat(id).cat(ee.String("-")).cat(date)

    // make the Feature
    var newfeat = ee.Feature(geom, {name:featname,
                                    value:val})
    // add the value to the list
     return fc.add(newfeat)
  }
  var newfeat = ee.FeatureCollection(ee.List(yearly.iterate(addVals, newfc)))
  return newfeat;
};

var newft = fg_points.map(mapfunc).flatten();

Export.table.toDrive(newft,
"export_Points");

https://code.earthengine.google.com/1acf553943e0bba49bca66878e8644c8

0
1

There came up several errors when I tried run the code. This should work as you wanted I guess.

  1. In line 8 you try to add feat to the map, which is not yet defined.

  2. Your if statement was malformatted. If a dictionary does not have a key, an error will be dropped if you try to get that value. Use:

      var val = ee.String(ee.Algorithms.If(value.contains('Fitted'),                                          
        ee.String(value.get('Fitted')),ee.String('No data')))
  1. something in your function addvals() was not working. I didn't find what exactly. You should better use mapping instead of an iterate function. See this example:
    // get feature id
    var id = ee.String(feat.id());
    var newfeat = fittedCollection.map(function(image){
    var value = image.reduceRegion(ee.Reducer.first(), geom, 30);
    // If the value is null then store it as 'No data'
    var val = ee.String(ee.Algorithms.If(value.contains('Fitted'), ee.String(value.get('Fitted')), ee.String('No data')))
    var featname = ee.String("feat_").cat(id).cat(ee.String("")).cat(image.date().format()
1
  • Thanks for the detailed description and the link! Works perfectly.
    – SimeonL
    Apr 13 '20 at 8:06

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.