0

I wrote a code to extract the landover change using the LandTrendr algorithm. As the documentation said I put a code at last to extarct the array which includes the fitted or the original values.

However, in my console I only see Image (1 Band) as the output of 'print(fitted)'!

How can I save the output of that array as a table?

The code is wrote based on "https://emapr.github.io/LT-GEE/lt-gee-outputs.html" documentation section 5.1 LandTrendr Band.

Here is the code, you can try it yourself if you want:

var points = ee.Geometry.Point([-121.946741626287, 39.7895992866194]);

// Define annual composite date range.
var startDay = 175; // start at 175th day of year
var nDays = 90;    // end 120 days later

// Define year range
var startYear = 1990;
var endYear   = 2020;

// Define band to use for segmentation
var bandName = 'B7';

// Define LandTrendr parameters
var ltParams = { 
  maxSegments:            6,
  spikeThreshold:         0.9,
  vertexCountOvershoot:   3,
  preventOneYearRecovery: true,
  recoveryThreshold:      0.25,
  pvalThreshold:          0.05,
  bestModelProportion:    0.75,
  minObservationsNeeded:  6
};


// Display the point.
Map.centerObject (points, 13);
Map.addLayer(points, {color: 'red'});
Map.setOptions('SAtellite');

// Define function to mask clouds and cloud shadows.
function cfmask(img) {
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
  var Mask = qa.bitweiseAnd (cloudShadowBitMask)
     .eq(0)
     .and(qa.bitwiseAnd(cloudsBitMask).eq(0))
  return img.updateMask(mask);
}

// Import Landsat 5 surface reflectance collection
var lsCol = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR');

// Define a list of years to make composits for.
var yearsList = ee.List.sequence(startYear, endYear, 1);

// Map over the year list to build an annual composite collection.
var annualCol = ee.ImageCollection.fromImages(
  yearsList.map(function(yr) {
    var startDate =  ee.Date.fromYMD(yr, 1, 1).advance(startDay, 'day');
    var middleDate = startDate.advance(nDays/2, 'day');
    var endDate = startDate.advance(nDays+1, 'day');
    var yearCol = lsCol
       .filterDate(startDate, endDate)
       .filterBounds(points)
       .select(bandName)
       .median();
    var nBands = yearCol.bandNames().size();
    return yearCol.set({
      'system:time_start': middleDate.millis(),
      'nBands': nBands
    });
    
  })
  );

// Deal with missing years (no images or all pixels masked).
var yearPresentCol = annualCol.filter(ee.Filter.neq('nBands', 0));
var yearAbsentCol = annualCol.filter(ee.Filter.eq('nBands', 0));

// Make a filter image for missing years - all pixels masked.
var dummyImg = ee.Image(0).selfMask().rename(bandName);

// Add dummy image band to image with bands (missing years).
yearAbsentCol = yearAbsentCol.map(function(img) {
  return img.addBands(dummyImg);
});

// merge the missing years collection to valid years collection.
var ltCol = yearPresentCol.merge(yearAbsentCol);

// Set the annual composite collection as the LandTrendr timeSeries parameter.
ltParams.timeSeries = ltCol;

var ltArrImg = ee.Algorithms.TemporalSegmentation.LandTrendr(ltParams);
print(ltArrImg);

// Map.addLayer(ltArrImg);

var segmentationInfo = ltArrImg.select(['LandTrendr'])

var LTarray = ltArrImg.select(['LandTrendr']); // subset the LandTrendr segmentation info
var year = LTarray.arraySlice(0, 0, 1); // slice out the year row
var fitted = LTarray.arraySlice(0, 2, 3); // slice out the fitted values row
print(fitted);
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197

1 Answers1

1

LandTrendr works with images, so your output it an image. But since you seem to be interested in a single point, you can extract the image value at that point using reduceRegion(). Then, to "save" this as a CSV, you create an ee.FeatureCollection and export it. Here's one option on how to approach that:

var features = ee.FeatureCollection(ee.Array(LTarray
  .reduceRegion({
    reducer: ee.Reducer.first(), 
    geometry: points, 
    scale: 30, 
  })
  .get('LandTrendr')).transpose().toList().map(function (row) {
    row = ee.List(row)
    return ee.Feature(points, {
      year: row.get(0),
      original: row.get(1),
      fitted: row.get(2),
      vertex: row.get(3),
    })
  })
)

print(features)
Export.table.toDrive({
  collection: features, 
  description: 'table', 
  selectors: ['year', 'original', 'fitted', 'vertex']
})

https://code.earthengine.google.com/3c09433dff27753a4a924bc5a06eca1f

Daniel Wiell
  • 253
  • 2
  • 5
  • Thanks a lot that works prefect. However, I have one question: Based on the LandTrendr API website the output is Magnitude ranging between -1000 and +1000 while my code is showing completely different range! any idea how should I obtain a value like the API? – babak asadolah Aug 19 '23 at 03:24