diff --git a/bookdown/09-api.Rmd b/bookdown/09-api.Rmd
index f700a4c..2979090 100644
--- a/bookdown/09-api.Rmd
+++ b/bookdown/09-api.Rmd
@@ -703,6 +703,8 @@ var endDay = '09-20';
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = ['TCB', 'TCG', 'TCW'];
+
+// define LandTrendr parameters
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
diff --git a/docs/api.html b/docs/api.html
index 36701be..16da66b 100644
--- a/docs/api.html
+++ b/docs/api.html
@@ -800,6 +800,8 @@
getFittedRGBcol
var aoi = ee.Geometry.Point(-122.8848, 43.7929);
var index = 'NBR';
var ftvList = ['TCB', 'TCG', 'TCW'];
+
+// define LandTrendr parameters
var runParams = {
maxSegments: 6,
spikeThreshold: 0.9,
diff --git a/docs/search_index.json b/docs/search_index.json
index 5402006..ba5926e 100644
--- a/docs/search_index.json
+++ b/docs/search_index.json
@@ -8,7 +8,7 @@
["working-with-outputs.html", "6 Working with Outputs 6.1 Getting segment information 6.2 Isolate a single segment of interest 6.3 Filter an isolated segment by an attribute 6.4 Filter by patch size 6.5 Transform an FTV array to an image stack", " 6 Working with Outputs The results coming from the LT-GEE algorithm are packaged as array images. If you are unfamiliar with the array image format, please see the GEE documentation. As array images, it is best to think of each pixel as a separate container of information. Each container is independent of others and can have varying observation lengths determined by the difference between the number of years in the time series and the number of masked observations in that time series. Image arrays are highly flexible, and in the case of the ‘LandTrendr’ band output, it allows slicing on 2 dimensions (observation [axis 1], and attribute [axis 0]), which is particularly handy for extracting all attributes for a given observation or set of observations (like observations identified as vertices). Though useful for slicing and manipulating segmentation information, the image array construct is not very good for visualization and exporting, so we will also demonstrate transforming the arrays to traditional images with bands representing observation values per year in the time series, by projecting (arrayProject) and/or flattening (arrayFlatten) the the arrays. specifically, this section will walk through: Some operations that can be performed on the ‘LandTrendr’ band image array to extract segment information Isolate the greatest delta segment of a time series Filter the greatest delta segment by vegetation loss magnitude and loss duration Apply a minimum mapping unit filter to identified disturbance pixels to reduce spatial noise Convert a fitted (FTV) band from an image array to an image with a band per year in the time series Note that the following code snippets are intended to be a template for learning and building on. We also provide shortcut functions to perform these operations in the API Functions section, which greatly simplify these steps. 6.1 Getting segment information The ‘LandTrendr’ Band output exists as an image array containing information for every observation not masked in the input collection. We hope that you’ll discover ways to utilize all the information, but we have focused on information regarding only the observations identified as vertices in the spectral-temporal segmentation. To extract only these observations we can use the 4th row of the ‘LandTrendr’ band, which is a Boolean indicating whether an observation is a vertex or not, to mask all the other rows (year, source value, fitted value): var lt = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params) // run LandTrendr spectral temporal segmentation algorithm .select('LandTrendr'); // select the LandTrendr band var vertexMask = lt.arraySlice(0, 3, 4); // slice out the 'Is Vertex' row - yes(1)/no(0) var vertices = lt.arrayMask(vertexMask); // use the 'Is Vertex' row as a mask for all rows Now we only have vertex observations in the vertices array. With this we can query information about vertices, count the number of vertices, and we can also generate information about segments defined by vertices, like magnitude of change and segment duration. In the following snippet we will create a series of variables that describe the 1) start year, 2) end year, 3) start value, and 4) end value for each segment in a given pixel’s time series. To do this, we first shift a copy of the vertices array along axis 1 (columns/annual observations) by 1 column so that we can subtract one from the other to obtain start and end year as well as start and end value for each segment. var left = vertices.arraySlice(1, 0, -1); // slice out the vertices as the start of segments var right = vertices.arraySlice(1, 1, null); // slice out the vertices as the end of segments var startYear = left.arraySlice(0, 0, 1); // get year dimension of LT data from the segment start vertices var startVal = left.arraySlice(0, 2, 3); // get spectral index dimension of LT data from the segment start vertices var endYear = right.arraySlice(0, 0, 1); // get year dimension of LT data from the segment end vertices var endVal = right.arraySlice(0, 2, 3); // get spectral index dimension of LT data from the segment end vertices Now, for each segment in a given pixel’s time series we know the start and end year and value. With this information we can calculate the duration of each segment and also the delta, or magnitude of change by subtracting starting year and value from ending year and value for each segment. var dur = endYear.subtract(startYear); // subtract the segment start year from the segment end year to calculate the duration of segments var mag = endVal.subtract(startVal); // substract the segment start index value from the segment end index value to calculate the delta of segments var rate = mag.divide(dur); // calculate the rate of spectral change Next, we’ll make an array that contains all segment attributes. var segInfo = ee.Image.cat([startYear.add(1), endYear, startVal, endVal, mag, dur, rate]) .toArray(0) .mask(vertexMask.mask()); Keep in mind that the segment delta and rate may be inverted from it’s native orientation, based on whether you inverted the spectral values in the input collection. This is good, though, because then we always know that a positive delta/rate indicates increasing vegetation and a negative delta/rate indicates decreasing vegetation. This segmentation information array is the base for exploring, querying, and mapping change. 6.2 Isolate a single segment of interest Segments represent a durable spectral trajectory. A pixel’s state can remain stable or transition to a different state. Transitions can occur over short or long periods of time, they can be major or minor, and starting and ending states can vary. In this section we’ll take the segment information and extract out from all segments in a given pixel’s time series only the greatest magnitude vegetation loss segment. To achieve this, we can sort the segment information array by the magnitude of change, and then slice out the first (greatest magnitude) segment’s information. var sortByThis = segInfo.arraySlice(0,4,5).toArray(0).multiply(-1); // need to flip the delta here, since arraySort is working by ascending order var segInfoSorted = segInfo.arraySort(sortByThis); // sort the array by magnitude var bigDelta = segInfoSorted.arraySlice(1, 0, 1); // get the first segment in the sorted array (greatest magnitude vegetation loss segment) 6.3 Filter an isolated segment by an attribute Once we have a single segment of interest isolated (greatest vegetation loss, in this case) we can transform the array into an image and perform filtering by other attributes of the segment of interest. Since the first band in the input collection to LandTrendr was oriented so that vegetation loss is represented by a positive delta (see LT-GEE Requirments section), you may need to multiply any attribute derived from the spectral input by -1 to re-orient it to its native state. This is evident in the following snippet as .multiply(distDir), where distDir is the scalar to possibly invert the values. Also follow the links in the example scripts section to see where are how distDir is used. var bigDeltaImg = ee.Image.cat(bigDelta.arraySlice(0,0,1).arrayProject([1]).arrayFlatten([['yod']]), bigDelta.arraySlice(0,1,2).arrayProject([1]).arrayFlatten([['endYr']]), bigDelta.arraySlice(0,2,3).arrayProject([1]).arrayFlatten([['startVal']]).multiply(distDir), bigDelta.arraySlice(0,3,4).arrayProject([1]).arrayFlatten([['endVal']]).multiply(distDir), bigDelta.arraySlice(0,4,5).arrayProject([1]).arrayFlatten([['mag']]).multiply(distDir), bigDelta.arraySlice(0,5,6).arrayProject([1]).arrayFlatten([['dur']]), bigDelta.arraySlice(0,6,7).arrayProject([1]).arrayFlatten([['rate']]).multiply(distDir)); Now we have a traditional image with bands for each segment attribute. From here we can create and apply a mask to identify only vegetation loss magnitudes greater/less than (depends on spectral index orientation) a minimum value and less than 4 years in duration. var distMask = bigDeltaImg.select(['mag']).lt(100) .and(bigDeltaImg.select(['dur']).lt(4)); var bigFastDist = bigDeltaImg.mask(distMask).int16(); // need to set as int16 bit to use connectedPixelCount for minimum mapping unit filter 6.4 Filter by patch size Finally we can eliminate spatial noise by applying a minimum mapping unit, based on the year of disturbance detection (you could patchify pixels by other attributes too) var mmuPatches = bigFastDist.select(['yod']) // patchify based on disturbances having the same year of detection .connectedPixelCount(mmu, true) // count the number of pixel in a candidate patch .gte(11); // are the the number of pixels per candidate patch greater than user-defined minimum mapping unit? var bigFastDist = bigFastDist.updateMask(mmuPatches); // mask the pixels/patches that are less than minimum mapping unit 6.5 Transform an FTV array to an image stack The previous sections described how to manipulate the ‘LandTrendr’ band array. In this section we’ll turn our attention to an example of an FTV band. If LT-GEE was run on a collection that included more than a single band, then the subsequent bands will be included in the LT-GEE output as FTV bands, where all observations between the user-defined starting and ending years will be fit the segmentation structure of the first band. Run LT-GEE on a collection that includes NBR as band 1 and Band 4 (NIR) as a second band. The output will include a Band 4 fitted to NBR segmentation, which we’ll select by calling its band name, the concatenation of the band name from the LT-GEE input collection and ’_fit’. var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE var B4ftv = LTresult.select(['B4_fit']); // subset the B4_fit band The ‘B4ftv’ variable is a 1 dimensional array. To convert it to an image with bands representing years, we use the arrayFlatten function. The arrayFlatten function takes a list of band labels with dimensions that match the dimensions of the image array to be flattened. We have 1 dimension and each observation along the single axis represents a year, so we just need to make a list of years and supply it as input to arrayFlatten. var years = []; // make an empty array to hold year band names for (var i = startYear; i <= endYear; ++i) years.push('yr'+i.toString()); // fill the array with years from the startYear to the endYear and convert them to string var B4ftvStack = B4ftv.arrayFlatten([years]); // flatten this out into bands, assigning the year as the band name Now the FTV image array is a standard image band stack that can be easily displayed or exported. "],
["example-scripts.html", "7 Example Scripts 7.1 Change mapping", " 7 Example Scripts These example scripts rely on the LT-GEE API, which needs to be added to your Google Earth Engine script library before running the scripts. To add the API, click this link. See the API reference to find more functionality for building image collections and dealing with LandTrendr outputs. 7.1 Change mapping Change events can be extracted and mapped from LandTrendr’s segmented line vertices. Information regarding the year of change event detection, magnitude of change, duration of change, and pre-change event spectral data can all be mapped. These change mapping script examples use the same LT-GEE API functions as the GEE APP UI LandTrendr Change Mapper. Use it to help parameterize the script and explore outputs before committing to downloading data to Google Drive. 7.1.1 Map vegetation loss In this example we’ll map the greatest vegetation loss segment and display the year of change detection and the magnitude of the change. Additionally, we’ll write the change attributes as GeoTiff files to your Google Drive account. Example script GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Greatest Disturbance Mapping 7.1.2 Map vegetation gain In this example we’ll map the greatest vegetation gain segment and display the year of change detection and the magnitude of the change. Additionally, we’ll write the change attributes as GeoTiff files to your Google Drive account. Example script GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Greatest Growth Mapping "],
["ui-applications.html", "8 UI Applications 8.1 UI LandTrendr Pixel Time Series Plotter 8.2 UI LandTrendr Change Mapper 8.3 UI LandTrendr Fitted Index Delta RGB Mapper", " 8 UI Applications We have developed a few UI applications for exploring LT-GEE time series data. They can be found in our public GEE repository. To access the applications, visit this URL: https://code.earthengine.google.com/?accept_repo=users/emaprlab/public). It will add the users/emaprlab/public repository to your GEE account. Once added, the repository can be found within the Reader permission group of your GEE scripts library. There you’ll find the following user interface applications. UI LandTrendr Pixel Time Series Plotter | link | source and LandTrendr-fitted data for a pixel UI LandTrendr Change Mapper | link | map disturbances and view attributes UI LandTrendr Fitted Index Delta RGB Mapper | link | visualize change and relative band/index information 8.1 UI LandTrendr Pixel Time Series Plotter GEE App link The UI LandTrendr Pixel Time Series Plotter will plot the Landsat surface reflectance source and LandTrendr-fitted index for a selected location. The script is useful for simply exploring and visualizing the spectral-temporal space of a pixel, for comparing the effectiveness of a series of indices for identifying landscape change, and for parameterizing LandTrendr to work best for your study region. 8.1.1 Steps Click on the script to load it and then click the Run button to initialize the application. Drag the map panel to the top of the page for better viewing. Define a year range over which to generate annual surface reflectance composites. Define the date range over which to generate annual composites. The format is (month-day) with two digits for both month and day. Note that if your study area is in the southern hemisphere and you want to include dates that cross the year boundary to capture the summer season, this is not possible yet - it is on our list! Select spectral indices and bands to view. You can select or or many. Optionally define a pixel coordinate set to view the time series of, alternatively you’ll simply click on the map. Note that the coordinates are in units of latitude and longitude formatted as decimal degrees (WGS 84 EPSG:4326). Also note that when you click a point on the map, the coordinates of the point will populate these entry boxes. Define the LandTrendr segmentation parameters. See the LT Parameters section for definitions. Either click a location on the map or hit the Submit button. If you want to change anything about the run, but keep the coordinate that you clicked on, just make the changes and then hit the Submit button - the coordinates for the clicked location are saved to the pixel coordinates input boxes. Wait a minute or two and plots of source and LandTrendr-fitted time series data will appear for all the indices you selected. The next time you click a point or submit the inputs, any current plots will be cleared and the new set will be displayed. 8.1.2 Under the hood Landsat 8 is transformed to the properties of Landsat 7 using slopes and intercepts from reduced major axis regressions reported in Roy et al 2016 Table 2 Masking out clouds, cloud shadows, and snow using CFMASK product from USGS Medoid annual compositing 8.2 UI LandTrendr Change Mapper GEE App link The UI LandTrendr Change Mapper will display map layers of change (vegetation loss or gain) attributes including: year of change detection, magnitude of change, duration of change event, and pre-change spectral value. 8.2.1 Steps Define a year range over which to build a Landsat time series to identify change - best to set this close to the maximum range, you can filter changes by year in a different setting below. Define the date range over which to generate annual Landsat image composites. The format is (month-day) with two digits for both month and day. Note that you can cross the year boundary, which is desirable if your study area is in the southern hemisphere, for example, Start Date: 11-15 and End Date: 03-15. If the start day month is greater than the end day month, then the function will composite across the new year, and assign the year of the composite as the new year. Select spectral index or band to use for change detection. Select the features you would like to mask from the imagery - these features are identified from the CFMASK quality band included with each image. Optionally provide a pixel coordinate set to define the center of the change map, alternatively you will simply click on the map location desired. Note that the coordinates are in units of longitude and latitude formatted as decimal degrees (WGS 84 EPSG:4326). Also note that when you click a point on the map, the coordinates of the point will populate these entry boxes. If you choose to enter coordinates, then you must click the submit button at the bottom of the control panel once all options are selected to generate the map. Define a buffer around the center point defined by a map click or provided in the longitude and latitude coordinate boxes from step 5. The units are in kilometers. It will draw and clip the map to the bounds of the square region created by the buffer around the point of interest. Define the vegetation change type you are interested in - either vegetation gain or loss. Define the vegetation change sort - should the change be the greatest, least, longest, etc. This applies only if there are multiple vegetation changes of a given type in a pixel time series. It is a relative qualifier for a pixel time series. Optionally filter changes by the year of detection. Adjust the sliders to constrain the results to a given range of years. The filter is only applied if the Filter by Year box is checked. Optionally filter changes by magnitude. Enter a threshold value and select a conditional operator. For example, if you selected the change type as vegetation loss defined by NBR and wanted only high magnitude losses shown, you would maybe want to keep only those pixels that had greater than 0.4 NBR units loss - you would set value as 400 (NBR scaled by 1000 - keep reading for more on this) and select the > operator. The value should always be positive which is on a scale of either vegetation loss or gain with 0 being no loss or gain and high values being high loss or gain, where gain and loss are defined by the vegetation change type selected above. Values should be multiplied by 1000 for ratio and normalized difference spectral indices (we multiply all the decimal-based data by 1000 so that we can convert the data type to signed 16-bit and retain some precision), and keep in mind that surface reflectance bands are multiplied by 10000 according to LEDAPS and LaSRC processing The filter is only applied if the Filter by Magnitude box is checked. Optionally filter by change event duration. Enter a threshold value and select a conditional operator. For example, if you only want to display change events that occurred rapidly, you would maybe set the value as 2 (years) and the operator as < to retain only those changes that completed within a single year. The filter is only applied if the Filter by Duration box is checked. Optionally filter by pre-change spectral value. This filter will limit the resulting changes by those that have a spectral value prior to the change either greater or less than the value provided. Values should be multiplied by 1000 for ratio and normalized difference spectral indices (we multiply all the decimal-based data by 1000 so that we can convert the data type to signed 16-bit and retain some precision), and keep in mind that surface reflectance bands are multiplied by 10000 according to LEDAPS and LaSRC processing. The filter is only applied if the Filter by Pre-Dist Value box is checked. Optionally filter by a minimum disturbance patch size, as defined by 8-neighbor connectivity of pixels having the same year of change detection. The value is the minimum number of pixel in a patch. The filter is only applied if the Filter by MMU box is checked. Define the LandTrendr segmentation parameters. See the LT Parameters section for definitions. Optionally submit the options for processing. If you have provided longitude and latitude coordinates to define the map center in step 5, you must submit the task. If you have generated a map and want to change a parameter, do so and then redraw the map by pressing this submit button. Inspector mode selector. In the right hand panel the app there is a check box for whether to interact with the map in Inspector mode or not. When inspector mode is activated, map clicks will retrieve change event attributes for the clicked pixel and display them in the right hand panel. When deactivated, a map click will start mapping changes for the region surrounding the clicked point. 8.2.2 Under the hood Landsat 8 is transformed to the properties of Landsat 7 using slopes and intercepts from reduced major axis regressions reported in Roy et al 2016 Table 2 Masking out clouds, cloud shadows, and snow using CFMASK product from USGS Medoid annual compositing 8.2.3 ToDo Option to export the map layers Allow input of a user drawn area or import of a feature asset or fusion table auto stretch to different indices - right now it is defaulting stretch for NBR Force absolute value for magnitude filter inputs Handle input of unscaled decimal values for the pre-dist and magnitude filter parameters 8.3 UI LandTrendr Fitted Index Delta RGB Mapper GEE App link The UI LandTrendr Fitted Index Delta RGB Mapper will display an RGB color map representing spectral band or index values at three time slices. Formally, it is referred to as write function memory insertion change detection. Each color red, green, and blue are assigned a year of spectral data, then those data are composited to an RGB image where each of red, green, and blue are mixed by weighting of the spectral intensity for the year represented by each color. It is useful as a quick way to visualize change or non-change over time along with providing a relative sense for spectral intensity. If I’m just exploring change in an area, I’ll often use this before strictly mapping disturbance, because I get a sense for spectral distribution and spatial pattern. Once you get a handle on interpreting the colors it is really quite an interesting and useful visualization. The following figure is a guide to help interpret the colors. 8.3.1 Steps Click on the script to load it and then click the Run button to initialize the application. Drag the map panel to the top of the page for better viewing. Define a year range over which to identify disturbances - best to set this close to the maximum range, you can filter disturbances by year in a different setting below. Define the date range over which to generate annual composites. The format is (month-day) with two digits for both month and day Note that if your study area is in the southern hemisphere and you want to include dates that cross the year boundary to capture the summer season, this is not possible yet - it is on our list! Select spectral index or band to use for segmentation and change detection. Define years to represent red, green, and blue color in the final RGB composite. Optionally define a pixel coordinate set to define the center of the disturbance map, alternatively you’ll simply click on the map. Note that the coordinates are in units of latitude and longitude formatted as decimal degrees (WGS 84 EPSG:4326). Also note that when you click a point on the map, the coordinates of the point will populate these entry boxes. Define a buffer around the center point defined by a map click or provided in the latitude and longitude coordinate boxes from step 6. The units are in kilometers. It will draw and clip the map to the bounds of the square region created by the buffer around the point of interest. Define the LandTrendr segmentation parameters. See the LT Parameters section for definitions. Either click on the map or hit the Submit button to draw the map - wait a few minutes for the process to complete. 8.3.2 Under the hood Landsat 8 is transformed to the properties of Landsat 7 using slopes and intercepts from reduced major axis regressions reported in Roy et al 2016 Table 2 Masking out clouds, cloud shadows, and snow using CFMASK product from USGS Medoid annual compositing 2 standard deviation stretch on the selected band or spectral index 8.3.3 ToDo "],
-["api.html", "9 API 9.1 Functions 9.2 Spectral index codes", " 9 API We have developed a LandTrendr JavaScript module that serves as an API to build LandTrendr input collections, run LandTrendr, and deal with the outputs. The API can be accessed from our public GEE repository. To use the API, you must first visit this URL: https://code.earthengine.google.com/?accept_repo=users/emaprlab/public. It will add the users/emaprlab/public repository to your GEE account. To use the API, you must import the LandTrendr.js module into your script using the following line - place it at the top of the script. var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); LandTrendr API functions use USGS Landsat Surface Reflectance Tier 1 data sets. They optionally mask clouds, cloud shadows, and snow from images using CFMASK. Annual image composites are generated using a medoid approach: for a given image pixel, the medoid is the value for a given band that is numerically closest to the median of all corresponding pixels among images considered (all images between a provided annual data range). TM and ETM+ data are included in annual medoid compositing without alteration, but OLI image bands 2, 3, 4, 5, 6 and 7 are subset and transformed to the spectral properties of ETM+ bands 1, 2, 3, 4, 5 and 7, respectively, using slopes and intercepts from reduced major axis regressions reported in Roy et al 2016 Table 2. 9.1 Functions buildSRcollection - Builds an annual cloud and cloud shadow masked medoid composite of Landsat surface reflectance TM-equivalent bands 1,2,3,4,5,7. This collection can be useful outside of use by LandTrendr, but is also the base for creating the input collection for LandTrendr. buildClearPixelCountCollection - buildSRcollection builds an annual surface reflectance collection potentially many images in a given year. It can be helpful to know how many pixels were available to generate the annual composite images. This function returns the count of unmasked pixels per year that are available for compositing for the provided years and date ranges. transformSRcollection - Transforms the images within an annual surface reflectance collection built by buildSRcollection to a list of provided indices or bands. buildLTcollection - Builds a collection as input to LandTrendr. It will prepare a collection where the first band is the spectral index to base temporal segmentation on, and the subsequent bands will be fitted to segmentation structure of the segmentation index. collectionToBandStack - Transforms an image collection into an image stack where each band of each image in the collection is concatenated as a band into a single image. Useful for mapping a function over a collection, like transforming surface reflectance to NDVI, and then transforming the resulting collection into a band sequential time series image stack. runLT - Run LandTrendr given a set of parameters. This is a wrapper around buildSRcollection and buildLTcollection functions. getSegmentData - Generates an array of information about spectral-temporal segments from the breakpoint vertices identified by LandTrendr. Returns either all spectral-temporal segments, or just vegetation loss segments, or just vegetation growth segments. getFittedData - Generates an annual band stack for a given index provided as ftvList indices to either buildLTcollection or runLT. It flattens the FTV array format to a band per year for a given FTV index. getChangeMap - Generates a set of map layers describing either vegetation loss or gain events with attributes including: year of change detection, spectral delta, duration of change event, pre-change event spectral value, and the rate of spectral change. Each attribute is a band of an ee.Image. getSegmentCount - Given a segment data array produced by the getSegmentData function, this function returns the number of segments identified by LandTrendr as an ee.Image. getFittedRGBcol - Creates a collection of RGB visualization images from three FTV bands resulting from a call to LandTrendr segmentation. This is useful for creating thumbnails, filmstrips, and GIFs. disturbanceMap - Deprecated, use getChangeMap 9.1.1 buildSRcollection Description: Builds an annual cloud and cloud shadow masked medoid composite of Landsat surface reflectance TM-equivalent bands 1,2,3,4,5,7. This collection can be useful outside of use by LandTrendr, but is also the base for creating the input collection for LandTrendr. Usage: buildSRcollection(startYear, endYear, startDay, endDay, aoi, maskThese) Parameters: startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection startDay (String | month day formatted as ‘mm-dd’): The minimum date in the desired seasonal range over which to generate annual composite. endDay (String | month day formatted as ‘mm-dd’): The maximum date in the desired seasonal range over which to generate annual composite. aoi (Geometry): The area-of-interest over which to mosaic images maskThese (List of strings | deafault: [‘cloud’, ‘shadow’, ‘snow’]): A list of CFMASK mask classes to include as masked pixels. Classes include: ‘cloud’, ‘shadow’, ‘snow’ and ‘water’. Result: An ee.ImageCollection where each image represents the medoid of observations per TM-equivalent surface reflectance bands 1-5 and 7, for a given year. There will be as many images as there are years in the range inclusive of startYear and endYear. If a given year does not exist for the range, then a masked band will act as a filler. Similarly, if all observations of a given pixel within a year are masked because of inclusion in the maskThese list, the pixel will be masked. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var maskThese = ['cloud', 'shadow', 'snow'] // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi, maskThese); print(annualSRcollection); 9.1.2 buildClearPixelCountCollection Description: Returns the count of unmasked pixels per year that are available for compositing for the provided years and date ranges. Usage: buildClearPixelCountCollection(startYear, endYear, startDay, endDay, aoi, maskThese) Parameters: startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection startDay (String | month day formatted as ‘mm-dd’): The minimum date in the desired seasonal range over which to generate annual composite. endDay (String | month day formatted as ‘mm-dd’): The maximum date in the desired seasonal range over which to generate annual composite. aoi (Geometry): The area-of-interest over which to mosaic images maskThese (List of strings | deafault: [‘cloud’, ‘shadow’, ‘snow’]): A list of CFMASK mask classes to include as masked image features Result: An ee.ImageCollection that includes one single band image per year in the provided year range that represents the number of unmasked pixels available for compositing given the date range and mask classes to include as masked pixels. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var maskThese = ['cloud', 'shadow', 'snow'] // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var nClearCollection = ltgee.buildClearPixelCountCollection(startYear, endYear, startDay, endDay, aoi, maskThese); print(nClearCollection); 9.1.3 transformSRcollection Description: Transforms the images within an annual surface reflectance collection built by buildSRcollection to a list of provided indices or bands. Usage: transformSRcollection(srCollection, bandList) Parameters: srCollection (Image Collection): An annual surface reflectance collection generated by the buildSRcollection function. bandList (List of strings): A list of one or more indices or bands from the list in the Spectral index codes section to be included in images composing the annual collection. Bands in the resulting images will be ordered and labeled as they are in this list. Result: An ee.ImageCollection that includes one image per year based on an image collection built by buildSRcollection function transformed to the indices provided in the bandList parameter. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var bandList = ['NBR', 'NDVI', 'TCW']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // build annual surface reflectance collection (cloud and shadow masked medoid composite) var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); // transform the annual surface reflectance bands to whatever is in the bandList variable var indexCollection = ltgee.transformSRcollection(annualSRcollection, bandList); // example of extracting year 2000 as an image from the collection var year2000 = ee.Image(indexCollection.filterDate('2000-01-01','2000-12-31').first()); print(year2000); 9.1.4 buildLTcollection Description: Builds a collection as input to LandTrendr. It will prepare a collection where the first band is the spectral index to base temporal segmentation on, and the subsequent bands will be fitted to segmentation structure of the segmentation index. Usage: buildLTcollection(collection, index, ftvList) Parameters: collection (Image Collection): An annual surface reflectance collection generated by the buildSRcollection function. index (String): The index from the list in the Spectral index codes section to be segmented by LandTrendr. ftvList (List of strings): A list of one or more indices from the list in the Spectral index codes section to be fitted to the segmentation of the index parameter. This parameter can also be set by and empty list [] which is valid and results in no FTV bands included in the LandTrendr output image. Result: An ee.ImageCollection where each image represents an assemblage of bands or indices to be segmented and fitted by LandTrendr. There will be as many images as there are years in the range inclusive of startYear and endYear. If a given year does not exist for the range, then a masked band will act as a filler. Similarly, if all observations of a given pixel within a year are masked because of cloud, cloud shadow, or snow, the pixel will be masked. The first band per image will be whatever spectral representation is defined by the index parameter - it will be oriented so that vegetation loss results in a positive spectral delta. Any following bands will be defined by the indices provided in the ftvList parameter, in the same order, and unmodified with regard to spectral delta orientation. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = ['NDVI', 'B4', 'B3']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); var annualLTcollection = ltgee.buildLTcollection(annualSRcollection, index, ftvList); print(annualLTcollection) 9.1.5 collectionToBandStack Description: Transforms an image collection into an image stack where each band of each image in the collection is concatenated as a band into a single image. Useful for mapping a function over a collection, like transforming surface reflectance to NDVI, and then transforming the resulting collection into a band sequential time series image stack. Usage: collectionToBandStack(collection, startYear, endYear) Parameters: collection (Image Collection): An annual surface reflectance image collection with one band per image, like that resulting from the use of transformSRcollection(srCollection, ['NDVI']), or buildClearPixelCountCollection, for instance. startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection maskFill (Integer, default: 0)**: The value to fill masked pixels in the image collection with. Result: An ee.Image representing a band sequential time series of image bands from each image in the given collection between startYear and endYear. Note that masked values in the image collection will be filled with 0 Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var bandList = ['NDVI']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // build annual surface reflectance collection (cloud and shadow masked medoid composite) var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); // transform the annual surface reflectance bands to whatever is in the bandList variable var indexCollection = ltgee.transformSRcollection(annualSRcollection, bandList); // transform image collection of NDVI (from bandList) to a image band stack var collectionBandStack = ltgee.collectionToBandStack(indexCollection, startYear, endYear); print(collectionBandStack); Map.addLayer(collectionBandStack, {"bands":["2000"],"min":-100,"max":1000,"palette":["ff2f0d","fff825","0ab308"]}); 9.1.6 runLT Description: Run LandTrendr given a set of parameters. This is a wrapper around buildSRcollection and buildLTcollection functions. Usage: runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese) Parameters: startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection startDay (String | month day formatted as ‘mm-dd’): The minimum date in the desired seasonal range over which to generate annual composite. endDay (String | month day formatted as ‘mm-dd’): The maximum date in the desired seasonal range over which to generate annual composite. aoi (Geometry): The area-of-interest over which to mosaic images index (String): The index from the list in the Spectral index codes section to be segmented by LandTrendr. ftvList (List of strings): A list of one or more indices from the list in the Spectral index codes section to be fitted to the segmentation of the index parameter. runParams (Dictionary): A dictionary of parameters to control LandTrendr segmentation. You can find definitions for the dictionary keys and values in LT parameters section maskThese (List of strings | default: [‘cloud’, ‘shadow’, ‘snow’]): A list of CFMASK mask classes to include as masked pixels. Classes include: ‘cloud’, ‘shadow’, ‘snow’ and ‘water’. Result: An array image described in the LT-GEE Outputs section Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = []; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; var maskThese = ['cloud', 'shadow', 'snow'] // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese); print(lt) 9.1.7 getSegmentData Description: Generates an array of information about spectral-temporal segments from the breakpoint vertices identified by LandTrendr. Returns either all spectral-temporal segments, or just vegetation loss segments, or just vegetation growth segments. Usage: getSegmentData(lt, index, delta, right) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr(). index (String): The index from the list in the Spectral index codes section used to generate LandTrendr outputs for the previous lt argument. delta (String): A parameter to define what segments to return information about. Either 'all' segments, only vegetation 'loss' segments, or only vegetation 'gain' segments. right (Boolean): Optional: true or false for whether to right the spectral values to their natural orientation around 0. LandTrendr requires that the spectral index being segmented be oriented so that vegetation loss is represented as a positive spectral delta (see LandTrendr collection building). This simplifies interpretation of the resulting segmentation - every positive delta indicates vegetation loss (the algorithm was designed around Landsat TM Band 5 SWIR). As a result, you may want to re-orient or right the spectral values in the segment data so that it is in its natural form and easier to intuitively interpret. This parameter only affects the results when providing the 'all' argument to the delta parameter. The default is false. Result: An image array with dimensions: 8 (rows) x nSegments (cols). Each row describes an attribute of the segments identified by LandTrendr per pixel time series. Each column represents a segment in the time series per pixel ordered from earliest to latest in the series. Row 1: segment start year Row 2: segment end year Row 3: segment start value Row 4: segment end value Row 5: segment spectral delta Row 6: segment duration Row 7: segment rate of spectral change Row 8: segment DSNR* *Segment spectral delta standardized by the RMSE of the LandTrendr fit. More details on DSNR can be found here: Cohen, W. B., Yang, Z., Healey, S. P., Kennedy, R. E., & Gorelick, N. (2018). A LandTrendr multispectral ensemble for forest disturbance detection. Remote Sensing of Environment, 205, 131-140. To extract a row, use the arraySlice function. For example, if you wanted to work only with the segment start years, you would do this: var segStartYr = segInfo.arraySlice(0, 0, 1). See the Working with Outputs section for more information on handling these data. The spectral segment start and end value will be in the natural index orientation around 0 when selecting either loss or growth for the delta parameter argument, and if all is selected while the right parameter argument is equal to true. In other cases, depending on the segmented index, these values could be inverted. Additionally, when selecting either loss or growth for the delta parameter argument, segment delta and rate will be the absolute value. In the case where all is selected as the delta parameter argument, the sign of spectral delta and change rate will depend on the index’s orientation around zero and whether the right parameter argument is equal to true or false. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = []; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams); var segInfo = ltgee.getSegmentData(lt, index, 'all'); print(segInfo); Map.addLayer(segInfo); // use 'Inspector' to explore values 9.1.8 getFittedData Description: Generates an annual band stack for a given index provided as ftvList indices to either buildLTcollection or runLT. It flattens the FTV array format to a band per year for a given FTV index. Usage: getFittedData(lt, startYear, endYear, index) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr(). startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection index (String): The index from the list in the Spectral index codes section to be segmented by LandTrendr. Result: An ee.Image representing fitted-to-vertex annual spectral data for whatever index was provided as the index parameter. There will be as many bands as there are years in the range inclusive of startYear and endYear. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = ['NBR', 'NDVI']; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams); var nbrFTV = ltgee.getFittedData(lt, startYear, endYear, ftvList[0]); var ndviFTV = ltgee.getFittedData(lt, startYear, endYear, ftvList[1]); print(nbrFTV); print(ndviFTV); 9.1.9 getChangeMap Description: Generates a set of map layers describing either vegetation loss or gain events with attributes including: year of change detection, spectral delta, duration of change event, pre-change event spectral value, and the rate of spectral change. Each attribute is a band of an ee.Image. Usage: getChangeMap(lt, changeParams) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr(). changeParams (Dictionary): A dictionary of parameters to control change mapping. delta (string): Either 'loss' or 'gain' to define whether to map vegetation loss or gain. sort (string): The type of change to identify if there are more than one change event in a pixel time series. It can be: 'greatest', 'least', 'newest', 'oldest', 'fastest', 'slowest'. year (Dictionary): Options for filtering change events by year of detection checked (Boolean): true or false for whether to filter by year. If true, then you must define both start and end described as follows. start (Integer): The minimum year of change events to include in the map. end (Integer): The maximum year of change events to include in the map. mag (Dictionary): Options for filtering change events by magnitude checked (Boolean): true or false for whether to filter by magnitude. If true, then you must define value and operator described as follows. value (Integer): The absolute value representing the spectral delta of change events to be compared against the following operator parameter. It is in the units of the spectral index defined by the index parameter in the runLT function described above. If the index is a normalized index like NBR or NDVI, the value should be multiplied by 1000. For instance, if you want to map NDVI delta segments greater than 0.4, the value here would be 400. If the index is a Landsat spectral band, like ‘B5’, the units are that of the USGS Collection 1 Surface Reflectance product. operator (String): A comparative operator, either '<' or '>', used to compare change event magnitude against the threshold value described previously. Only change segments resulting in a true condition will be included in the map dsnr (Boolean): true or false for whether the magnitude should be standardized by the RMSE of the LandTrendr fit. If true then the value needs to be interpreted as a factor of RMSE. If you want to only include change that is greater than the RMSE of the fit, then value should be 1, if you only want change that is greater than 2 times the RMSE, then value should be 2. More details on DSNR can be found here: Cohen, W. B., Yang, Z., Healey, S. P., Kennedy, R. E., & Gorelick, N. (2018). A LandTrendr multispectral ensemble for forest disturbance detection. Remote Sensing of Environment, 205, 131-140. dur (Dictionary): Options for filtering change events by duration. checked (Boolean): true or false for whether to filter by duration. If true, then you must define value and operator described as follows. value (Integer): The number of years a change event took to complete to be compared against the following operator parameter. It is in units of years. operator (String): A comparative operator, either '<' or '>', used to compare change event duration against the threshold value described previously. Only change segments resulting in a true condition will be included in the map. preval (Dictionary): Options for filtering change events by pre-change spectral value. checked (Boolean): true or false for whether to filter by pre-change spectral value. If true, then you must define value and operator described as follows. value (Integer): The spectral index value prior to a change event to be compared against the following operator parameter. It is in the units of the spectral index defined by the index parameter in the runLT function described above. If the index is a normalized index like NBR or NDVI, the value should be multiplied by 1000. For instance, if you want to filter change events by NDVI pre-change values greater than 0.3, the value here would be 300. If the index is a Landsat spectral band, like ‘B5’, the units are that of the USGS Collection 1 Surface reflectance product. It should be signed according to the natural orientation of the index or band. mmu (Dictionary): Options for filtering change events by minimum patch size. Patches are defined by change event pixels matching the above filtering criteria, having the same year of detection and adjacent to other pixels by the 8 neighbor rule. checked (Boolean): true or false for whether to filter change events by a minimum patch size. If true, then you must define value described as follows. value (Integer): The minimum number of pixels defining a change event patch. Number of pixels is the unit. Single pixels or patches with less than the provided value will not be included in the map. See the example below for formatting the dictionary Result: An ee.Image with bands for attributes of change events meeting filtering criteria including: Year of change event detection: 'yod' (year) Magnitude of change event: 'mag' (absolute value of change event spectral delta) Duration of change event: 'dur' (years) Pre-change event spectral value: 'preval' (spectral value) Rate of spectral change for event 'rate' (mag/dur) DSNR 'dsnr' (mag/fit rmse) multipled by 100 to retain two decimal precision with Int16 data. See the following for more information on the metric: Cohen, W. B., Yang, Z., Healey, S. P., Kennedy, R. E., & Gorelick, N. (2018). A LandTrendr multispectral ensemble for forest disturbance detection. Remote Sensing of Environment, 205, 131-140. Note: Use the LT-GEE Change Mapper App as a test to determine parameter values. Example: //########################################################################################## // START INPUTS //########################################################################################## // define collection parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var maskThese = ['cloud', 'shadow', 'snow', 'water']; // define landtrendr parameters var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // define change parameters var changeParams = { delta: 'loss', sort: 'greatest', year: {checked:false, start:2000, end:2010}, mag: {checked:true, value:200, operator: '>', dsnr:false}, dur: {checked:true, value:4, operator: '<'}, preval: {checked:true, value:300, operator: '>'}, mmu: {checked:true, value:11}, }; //########################################################################################## // END INPUTS //########################################################################################## // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // add index to changeParams object changeParams.index = index; // run landtrendr var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, [], runParams, maskThese); // get the change map layers var changeImg = ltgee.getChangeMap(lt, changeParams); // set visualization dictionaries var palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000']; var yodVizParms = { min: startYear, max: endYear, palette: palette }; var magVizParms = { min: 200, max: 800, palette: palette }; // display the change attribute map - note that there are other layers - print changeImg to console to see Map.centerObject(aoi, 11); Map.addLayer(changeImg.select(['mag']), magVizParms, 'Magnitude of Change'); Map.addLayer(changeImg.select(['yod']), yodVizParms, 'Year of Detection'); 9.1.10 getSegmentCount Description: Given a segment data array produced by the getSegmentData function, this function returns the number of segments identified by LandTrendr as an ee.Image. Usage: getSegmentCount(segData) Parameters: segData: an image array returned from the getSegmentData function. Result: A single-band ee.Image describing the number of segments per pixel time series identified by LandTrendr. Note: This function counts the number of segments returned from the getSegmentData function, which can optionally return vegetation loss, gain, or all segments. The count of segments will reflect the delta argument provided to the getSegmentData function. For instance, if you ran the getSegmentData function and set the delta argument as 'loss' and then ran this function, you’d get a map of the number of vegetation loss segments. Alternatively, if thedelta argument was set to 'all', you’d get a map of the segment count including all segment types. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = []; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; var maskThese = ['cloud', 'shadow', 'snow']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); // run LandTrendr using the LT-GEE API var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese); // get the segment data array var segData = ltgee.getSegmentData(lt, index, 'all', true); // get the segment count var segCount = ltgee.getSegmentCount(segData); Map.addLayer(segCount, {"min":0, "max":runParams.maxSegments}); 9.1.11 getFittedRGBcol Description: Creates a collection of RGB visualization images from three FTV bands resulting from a call to LandTrendr segmentation. This is useful for creating thumbnails, filmstrips, and GIFs. Usage: getFittedRGBcol(lt, startYear, endYear, bands, visParams) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr() startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection bands (List of strings): Three bands in order of Red, Green, Blue visParams (dictionary): min (List of numbers): The minimum values for the three RGB bands that define low end of stretch range max (List of numbers): The maximum values for the three RGB bands that define high end of stretch range gamma (List of numbers): The gamma values for the three RGB bands Result: An image collection with an RGB image for each year between and including startYear and endYear. Note: This function is useful for generating high-quality time series frames for use in GIF movies. The following example applies the output to the Earth Engine getVideoThumbURL function to generate a GIF. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1984; var endYear = 2018; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = ['TCB', 'TCG', 'TCW']; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // define the RGB visualization parameters var visParams = { min: [604, -49, -2245], max: [5592, 3147, 843], gamma: [1, 1, 1] }; // define the GIF video parameters var vidParams = { crs: 'EPSG:3857', dimensions: 300, region: aoi.buffer(10000).bounds(), framesPerSecond: 8 }; // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams); // get RGB collection var rgbCol = ltgee.getFittedRGBcol(lt, startYear, endYear, ftvList, visParams); // print the RGB GIF link print(rgbCol.getVideoThumbURL(vidParams)); // show RGB image for year 2000 on map var rgb2000 = rgbCol.filterDate('2000-01-01', '2000-12-31').first().clip(vidParams.region); Map.centerObject(rgb2000, 10); Map.addLayer(rgb2000, {}, 'TC/RGB'); 9.2 Spectral index codes The LandTrendr.js functions library has a defined list of indices and bands that it will work with. Below in Table 9.1 is the list of ‘index’ codes to use and their common name. You should specify them as an all caps string. Table 9.1: Spectral Index Codes Code Name NBR Normalized Burn Ratio NDVI Normalized Difference Vegetation Index NDSI Normalized Different Snow Index NDMI Normalized Difference Moisture Index TCB Tasseled-Cap Brightness TCG Tasseled-Cap Greenness TCW Tasseled-Cap Wetness TCA Tasseled-Cap Angle B1 Thematic Mapper-equivalent Band 1 B2 Thematic Mapper-equivalent Band 2 B3 Thematic Mapper-equivalent Band 3 B4 Thematic Mapper-equivalent Band 4 B5 Thematic Mapper-equivalent Band 5 B7 Thematic Mapper-equivalent Band 7 "],
+["api.html", "9 API 9.1 Functions 9.2 Spectral index codes", " 9 API We have developed a LandTrendr JavaScript module that serves as an API to build LandTrendr input collections, run LandTrendr, and deal with the outputs. The API can be accessed from our public GEE repository. To use the API, you must first visit this URL: https://code.earthengine.google.com/?accept_repo=users/emaprlab/public. It will add the users/emaprlab/public repository to your GEE account. To use the API, you must import the LandTrendr.js module into your script using the following line - place it at the top of the script. var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); LandTrendr API functions use USGS Landsat Surface Reflectance Tier 1 data sets. They optionally mask clouds, cloud shadows, and snow from images using CFMASK. Annual image composites are generated using a medoid approach: for a given image pixel, the medoid is the value for a given band that is numerically closest to the median of all corresponding pixels among images considered (all images between a provided annual data range). TM and ETM+ data are included in annual medoid compositing without alteration, but OLI image bands 2, 3, 4, 5, 6 and 7 are subset and transformed to the spectral properties of ETM+ bands 1, 2, 3, 4, 5 and 7, respectively, using slopes and intercepts from reduced major axis regressions reported in Roy et al 2016 Table 2. 9.1 Functions buildSRcollection - Builds an annual cloud and cloud shadow masked medoid composite of Landsat surface reflectance TM-equivalent bands 1,2,3,4,5,7. This collection can be useful outside of use by LandTrendr, but is also the base for creating the input collection for LandTrendr. buildClearPixelCountCollection - buildSRcollection builds an annual surface reflectance collection potentially many images in a given year. It can be helpful to know how many pixels were available to generate the annual composite images. This function returns the count of unmasked pixels per year that are available for compositing for the provided years and date ranges. transformSRcollection - Transforms the images within an annual surface reflectance collection built by buildSRcollection to a list of provided indices or bands. buildLTcollection - Builds a collection as input to LandTrendr. It will prepare a collection where the first band is the spectral index to base temporal segmentation on, and the subsequent bands will be fitted to segmentation structure of the segmentation index. collectionToBandStack - Transforms an image collection into an image stack where each band of each image in the collection is concatenated as a band into a single image. Useful for mapping a function over a collection, like transforming surface reflectance to NDVI, and then transforming the resulting collection into a band sequential time series image stack. runLT - Run LandTrendr given a set of parameters. This is a wrapper around buildSRcollection and buildLTcollection functions. getSegmentData - Generates an array of information about spectral-temporal segments from the breakpoint vertices identified by LandTrendr. Returns either all spectral-temporal segments, or just vegetation loss segments, or just vegetation growth segments. getFittedData - Generates an annual band stack for a given index provided as ftvList indices to either buildLTcollection or runLT. It flattens the FTV array format to a band per year for a given FTV index. getChangeMap - Generates a set of map layers describing either vegetation loss or gain events with attributes including: year of change detection, spectral delta, duration of change event, pre-change event spectral value, and the rate of spectral change. Each attribute is a band of an ee.Image. getSegmentCount - Given a segment data array produced by the getSegmentData function, this function returns the number of segments identified by LandTrendr as an ee.Image. getFittedRGBcol - Creates a collection of RGB visualization images from three FTV bands resulting from a call to LandTrendr segmentation. This is useful for creating thumbnails, filmstrips, and GIFs. disturbanceMap - Deprecated, use getChangeMap 9.1.1 buildSRcollection Description: Builds an annual cloud and cloud shadow masked medoid composite of Landsat surface reflectance TM-equivalent bands 1,2,3,4,5,7. This collection can be useful outside of use by LandTrendr, but is also the base for creating the input collection for LandTrendr. Usage: buildSRcollection(startYear, endYear, startDay, endDay, aoi, maskThese) Parameters: startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection startDay (String | month day formatted as ‘mm-dd’): The minimum date in the desired seasonal range over which to generate annual composite. endDay (String | month day formatted as ‘mm-dd’): The maximum date in the desired seasonal range over which to generate annual composite. aoi (Geometry): The area-of-interest over which to mosaic images maskThese (List of strings | deafault: [‘cloud’, ‘shadow’, ‘snow’]): A list of CFMASK mask classes to include as masked pixels. Classes include: ‘cloud’, ‘shadow’, ‘snow’ and ‘water’. Result: An ee.ImageCollection where each image represents the medoid of observations per TM-equivalent surface reflectance bands 1-5 and 7, for a given year. There will be as many images as there are years in the range inclusive of startYear and endYear. If a given year does not exist for the range, then a masked band will act as a filler. Similarly, if all observations of a given pixel within a year are masked because of inclusion in the maskThese list, the pixel will be masked. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var maskThese = ['cloud', 'shadow', 'snow'] // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi, maskThese); print(annualSRcollection); 9.1.2 buildClearPixelCountCollection Description: Returns the count of unmasked pixels per year that are available for compositing for the provided years and date ranges. Usage: buildClearPixelCountCollection(startYear, endYear, startDay, endDay, aoi, maskThese) Parameters: startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection startDay (String | month day formatted as ‘mm-dd’): The minimum date in the desired seasonal range over which to generate annual composite. endDay (String | month day formatted as ‘mm-dd’): The maximum date in the desired seasonal range over which to generate annual composite. aoi (Geometry): The area-of-interest over which to mosaic images maskThese (List of strings | deafault: [‘cloud’, ‘shadow’, ‘snow’]): A list of CFMASK mask classes to include as masked image features Result: An ee.ImageCollection that includes one single band image per year in the provided year range that represents the number of unmasked pixels available for compositing given the date range and mask classes to include as masked pixels. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var maskThese = ['cloud', 'shadow', 'snow'] // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var nClearCollection = ltgee.buildClearPixelCountCollection(startYear, endYear, startDay, endDay, aoi, maskThese); print(nClearCollection); 9.1.3 transformSRcollection Description: Transforms the images within an annual surface reflectance collection built by buildSRcollection to a list of provided indices or bands. Usage: transformSRcollection(srCollection, bandList) Parameters: srCollection (Image Collection): An annual surface reflectance collection generated by the buildSRcollection function. bandList (List of strings): A list of one or more indices or bands from the list in the Spectral index codes section to be included in images composing the annual collection. Bands in the resulting images will be ordered and labeled as they are in this list. Result: An ee.ImageCollection that includes one image per year based on an image collection built by buildSRcollection function transformed to the indices provided in the bandList parameter. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var bandList = ['NBR', 'NDVI', 'TCW']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // build annual surface reflectance collection (cloud and shadow masked medoid composite) var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); // transform the annual surface reflectance bands to whatever is in the bandList variable var indexCollection = ltgee.transformSRcollection(annualSRcollection, bandList); // example of extracting year 2000 as an image from the collection var year2000 = ee.Image(indexCollection.filterDate('2000-01-01','2000-12-31').first()); print(year2000); 9.1.4 buildLTcollection Description: Builds a collection as input to LandTrendr. It will prepare a collection where the first band is the spectral index to base temporal segmentation on, and the subsequent bands will be fitted to segmentation structure of the segmentation index. Usage: buildLTcollection(collection, index, ftvList) Parameters: collection (Image Collection): An annual surface reflectance collection generated by the buildSRcollection function. index (String): The index from the list in the Spectral index codes section to be segmented by LandTrendr. ftvList (List of strings): A list of one or more indices from the list in the Spectral index codes section to be fitted to the segmentation of the index parameter. This parameter can also be set by and empty list [] which is valid and results in no FTV bands included in the LandTrendr output image. Result: An ee.ImageCollection where each image represents an assemblage of bands or indices to be segmented and fitted by LandTrendr. There will be as many images as there are years in the range inclusive of startYear and endYear. If a given year does not exist for the range, then a masked band will act as a filler. Similarly, if all observations of a given pixel within a year are masked because of cloud, cloud shadow, or snow, the pixel will be masked. The first band per image will be whatever spectral representation is defined by the index parameter - it will be oriented so that vegetation loss results in a positive spectral delta. Any following bands will be defined by the indices provided in the ftvList parameter, in the same order, and unmodified with regard to spectral delta orientation. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = ['NDVI', 'B4', 'B3']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); var annualLTcollection = ltgee.buildLTcollection(annualSRcollection, index, ftvList); print(annualLTcollection) 9.1.5 collectionToBandStack Description: Transforms an image collection into an image stack where each band of each image in the collection is concatenated as a band into a single image. Useful for mapping a function over a collection, like transforming surface reflectance to NDVI, and then transforming the resulting collection into a band sequential time series image stack. Usage: collectionToBandStack(collection, startYear, endYear) Parameters: collection (Image Collection): An annual surface reflectance image collection with one band per image, like that resulting from the use of transformSRcollection(srCollection, ['NDVI']), or buildClearPixelCountCollection, for instance. startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection maskFill (Integer, default: 0)**: The value to fill masked pixels in the image collection with. Result: An ee.Image representing a band sequential time series of image bands from each image in the given collection between startYear and endYear. Note that masked values in the image collection will be filled with 0 Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var bandList = ['NDVI']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // build annual surface reflectance collection (cloud and shadow masked medoid composite) var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); // transform the annual surface reflectance bands to whatever is in the bandList variable var indexCollection = ltgee.transformSRcollection(annualSRcollection, bandList); // transform image collection of NDVI (from bandList) to a image band stack var collectionBandStack = ltgee.collectionToBandStack(indexCollection, startYear, endYear); print(collectionBandStack); Map.addLayer(collectionBandStack, {"bands":["2000"],"min":-100,"max":1000,"palette":["ff2f0d","fff825","0ab308"]}); 9.1.6 runLT Description: Run LandTrendr given a set of parameters. This is a wrapper around buildSRcollection and buildLTcollection functions. Usage: runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese) Parameters: startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection startDay (String | month day formatted as ‘mm-dd’): The minimum date in the desired seasonal range over which to generate annual composite. endDay (String | month day formatted as ‘mm-dd’): The maximum date in the desired seasonal range over which to generate annual composite. aoi (Geometry): The area-of-interest over which to mosaic images index (String): The index from the list in the Spectral index codes section to be segmented by LandTrendr. ftvList (List of strings): A list of one or more indices from the list in the Spectral index codes section to be fitted to the segmentation of the index parameter. runParams (Dictionary): A dictionary of parameters to control LandTrendr segmentation. You can find definitions for the dictionary keys and values in LT parameters section maskThese (List of strings | default: [‘cloud’, ‘shadow’, ‘snow’]): A list of CFMASK mask classes to include as masked pixels. Classes include: ‘cloud’, ‘shadow’, ‘snow’ and ‘water’. Result: An array image described in the LT-GEE Outputs section Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = []; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; var maskThese = ['cloud', 'shadow', 'snow'] // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese); print(lt) 9.1.7 getSegmentData Description: Generates an array of information about spectral-temporal segments from the breakpoint vertices identified by LandTrendr. Returns either all spectral-temporal segments, or just vegetation loss segments, or just vegetation growth segments. Usage: getSegmentData(lt, index, delta, right) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr(). index (String): The index from the list in the Spectral index codes section used to generate LandTrendr outputs for the previous lt argument. delta (String): A parameter to define what segments to return information about. Either 'all' segments, only vegetation 'loss' segments, or only vegetation 'gain' segments. right (Boolean): Optional: true or false for whether to right the spectral values to their natural orientation around 0. LandTrendr requires that the spectral index being segmented be oriented so that vegetation loss is represented as a positive spectral delta (see LandTrendr collection building). This simplifies interpretation of the resulting segmentation - every positive delta indicates vegetation loss (the algorithm was designed around Landsat TM Band 5 SWIR). As a result, you may want to re-orient or right the spectral values in the segment data so that it is in its natural form and easier to intuitively interpret. This parameter only affects the results when providing the 'all' argument to the delta parameter. The default is false. Result: An image array with dimensions: 8 (rows) x nSegments (cols). Each row describes an attribute of the segments identified by LandTrendr per pixel time series. Each column represents a segment in the time series per pixel ordered from earliest to latest in the series. Row 1: segment start year Row 2: segment end year Row 3: segment start value Row 4: segment end value Row 5: segment spectral delta Row 6: segment duration Row 7: segment rate of spectral change Row 8: segment DSNR* *Segment spectral delta standardized by the RMSE of the LandTrendr fit. More details on DSNR can be found here: Cohen, W. B., Yang, Z., Healey, S. P., Kennedy, R. E., & Gorelick, N. (2018). A LandTrendr multispectral ensemble for forest disturbance detection. Remote Sensing of Environment, 205, 131-140. To extract a row, use the arraySlice function. For example, if you wanted to work only with the segment start years, you would do this: var segStartYr = segInfo.arraySlice(0, 0, 1). See the Working with Outputs section for more information on handling these data. The spectral segment start and end value will be in the natural index orientation around 0 when selecting either loss or growth for the delta parameter argument, and if all is selected while the right parameter argument is equal to true. In other cases, depending on the segmented index, these values could be inverted. Additionally, when selecting either loss or growth for the delta parameter argument, segment delta and rate will be the absolute value. In the case where all is selected as the delta parameter argument, the sign of spectral delta and change rate will depend on the index’s orientation around zero and whether the right parameter argument is equal to true or false. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = []; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams); var segInfo = ltgee.getSegmentData(lt, index, 'all'); print(segInfo); Map.addLayer(segInfo); // use 'Inspector' to explore values 9.1.8 getFittedData Description: Generates an annual band stack for a given index provided as ftvList indices to either buildLTcollection or runLT. It flattens the FTV array format to a band per year for a given FTV index. Usage: getFittedData(lt, startYear, endYear, index) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr(). startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection index (String): The index from the list in the Spectral index codes section to be segmented by LandTrendr. Result: An ee.Image representing fitted-to-vertex annual spectral data for whatever index was provided as the index parameter. There will be as many bands as there are years in the range inclusive of startYear and endYear. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = ['NBR', 'NDVI']; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); Map.addLayer(aoi); // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams); var nbrFTV = ltgee.getFittedData(lt, startYear, endYear, ftvList[0]); var ndviFTV = ltgee.getFittedData(lt, startYear, endYear, ftvList[1]); print(nbrFTV); print(ndviFTV); 9.1.9 getChangeMap Description: Generates a set of map layers describing either vegetation loss or gain events with attributes including: year of change detection, spectral delta, duration of change event, pre-change event spectral value, and the rate of spectral change. Each attribute is a band of an ee.Image. Usage: getChangeMap(lt, changeParams) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr(). changeParams (Dictionary): A dictionary of parameters to control change mapping. delta (string): Either 'loss' or 'gain' to define whether to map vegetation loss or gain. sort (string): The type of change to identify if there are more than one change event in a pixel time series. It can be: 'greatest', 'least', 'newest', 'oldest', 'fastest', 'slowest'. year (Dictionary): Options for filtering change events by year of detection checked (Boolean): true or false for whether to filter by year. If true, then you must define both start and end described as follows. start (Integer): The minimum year of change events to include in the map. end (Integer): The maximum year of change events to include in the map. mag (Dictionary): Options for filtering change events by magnitude checked (Boolean): true or false for whether to filter by magnitude. If true, then you must define value and operator described as follows. value (Integer): The absolute value representing the spectral delta of change events to be compared against the following operator parameter. It is in the units of the spectral index defined by the index parameter in the runLT function described above. If the index is a normalized index like NBR or NDVI, the value should be multiplied by 1000. For instance, if you want to map NDVI delta segments greater than 0.4, the value here would be 400. If the index is a Landsat spectral band, like ‘B5’, the units are that of the USGS Collection 1 Surface Reflectance product. operator (String): A comparative operator, either '<' or '>', used to compare change event magnitude against the threshold value described previously. Only change segments resulting in a true condition will be included in the map dsnr (Boolean): true or false for whether the magnitude should be standardized by the RMSE of the LandTrendr fit. If true then the value needs to be interpreted as a factor of RMSE. If you want to only include change that is greater than the RMSE of the fit, then value should be 1, if you only want change that is greater than 2 times the RMSE, then value should be 2. More details on DSNR can be found here: Cohen, W. B., Yang, Z., Healey, S. P., Kennedy, R. E., & Gorelick, N. (2018). A LandTrendr multispectral ensemble for forest disturbance detection. Remote Sensing of Environment, 205, 131-140. dur (Dictionary): Options for filtering change events by duration. checked (Boolean): true or false for whether to filter by duration. If true, then you must define value and operator described as follows. value (Integer): The number of years a change event took to complete to be compared against the following operator parameter. It is in units of years. operator (String): A comparative operator, either '<' or '>', used to compare change event duration against the threshold value described previously. Only change segments resulting in a true condition will be included in the map. preval (Dictionary): Options for filtering change events by pre-change spectral value. checked (Boolean): true or false for whether to filter by pre-change spectral value. If true, then you must define value and operator described as follows. value (Integer): The spectral index value prior to a change event to be compared against the following operator parameter. It is in the units of the spectral index defined by the index parameter in the runLT function described above. If the index is a normalized index like NBR or NDVI, the value should be multiplied by 1000. For instance, if you want to filter change events by NDVI pre-change values greater than 0.3, the value here would be 300. If the index is a Landsat spectral band, like ‘B5’, the units are that of the USGS Collection 1 Surface reflectance product. It should be signed according to the natural orientation of the index or band. mmu (Dictionary): Options for filtering change events by minimum patch size. Patches are defined by change event pixels matching the above filtering criteria, having the same year of detection and adjacent to other pixels by the 8 neighbor rule. checked (Boolean): true or false for whether to filter change events by a minimum patch size. If true, then you must define value described as follows. value (Integer): The minimum number of pixels defining a change event patch. Number of pixels is the unit. Single pixels or patches with less than the provided value will not be included in the map. See the example below for formatting the dictionary Result: An ee.Image with bands for attributes of change events meeting filtering criteria including: Year of change event detection: 'yod' (year) Magnitude of change event: 'mag' (absolute value of change event spectral delta) Duration of change event: 'dur' (years) Pre-change event spectral value: 'preval' (spectral value) Rate of spectral change for event 'rate' (mag/dur) DSNR 'dsnr' (mag/fit rmse) multipled by 100 to retain two decimal precision with Int16 data. See the following for more information on the metric: Cohen, W. B., Yang, Z., Healey, S. P., Kennedy, R. E., & Gorelick, N. (2018). A LandTrendr multispectral ensemble for forest disturbance detection. Remote Sensing of Environment, 205, 131-140. Note: Use the LT-GEE Change Mapper App as a test to determine parameter values. Example: //########################################################################################## // START INPUTS //########################################################################################## // define collection parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var maskThese = ['cloud', 'shadow', 'snow', 'water']; // define landtrendr parameters var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // define change parameters var changeParams = { delta: 'loss', sort: 'greatest', year: {checked:false, start:2000, end:2010}, mag: {checked:true, value:200, operator: '>', dsnr:false}, dur: {checked:true, value:4, operator: '<'}, preval: {checked:true, value:300, operator: '>'}, mmu: {checked:true, value:11}, }; //########################################################################################## // END INPUTS //########################################################################################## // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // add index to changeParams object changeParams.index = index; // run landtrendr var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, [], runParams, maskThese); // get the change map layers var changeImg = ltgee.getChangeMap(lt, changeParams); // set visualization dictionaries var palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000']; var yodVizParms = { min: startYear, max: endYear, palette: palette }; var magVizParms = { min: 200, max: 800, palette: palette }; // display the change attribute map - note that there are other layers - print changeImg to console to see Map.centerObject(aoi, 11); Map.addLayer(changeImg.select(['mag']), magVizParms, 'Magnitude of Change'); Map.addLayer(changeImg.select(['yod']), yodVizParms, 'Year of Detection'); 9.1.10 getSegmentCount Description: Given a segment data array produced by the getSegmentData function, this function returns the number of segments identified by LandTrendr as an ee.Image. Usage: getSegmentCount(segData) Parameters: segData: an image array returned from the getSegmentData function. Result: A single-band ee.Image describing the number of segments per pixel time series identified by LandTrendr. Note: This function counts the number of segments returned from the getSegmentData function, which can optionally return vegetation loss, gain, or all segments. The count of segments will reflect the delta argument provided to the getSegmentData function. For instance, if you ran the getSegmentData function and set the delta argument as 'loss' and then ran this function, you’d get a map of the number of vegetation loss segments. Alternatively, if thedelta argument was set to 'all', you’d get a map of the segment count including all segment types. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = []; var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; var maskThese = ['cloud', 'shadow', 'snow']; // center and zoom the display in case outputs are to be mapped Map.centerObject(aoi,10); // run LandTrendr using the LT-GEE API var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams, maskThese); // get the segment data array var segData = ltgee.getSegmentData(lt, index, 'all', true); // get the segment count var segCount = ltgee.getSegmentCount(segData); Map.addLayer(segCount, {"min":0, "max":runParams.maxSegments}); 9.1.11 getFittedRGBcol Description: Creates a collection of RGB visualization images from three FTV bands resulting from a call to LandTrendr segmentation. This is useful for creating thumbnails, filmstrips, and GIFs. Usage: getFittedRGBcol(lt, startYear, endYear, bands, visParams) Parameters: lt (Image Array): The image array that is the result of running LandTrendr with either runLT() or ee.Algorithms.TemporalSegmentation.LandTrendr() startYear (Integer): The minimum year in the desired range of annual collection endYear (Integer): The maximum year in the desired range of annual collection bands (List of strings): Three bands in order of Red, Green, Blue visParams (dictionary): min (List of numbers): The minimum values for the three RGB bands that define low end of stretch range max (List of numbers): The maximum values for the three RGB bands that define high end of stretch range gamma (List of numbers): The gamma values for the three RGB bands Result: An image collection with an RGB image for each year between and including startYear and endYear. Note: This function is useful for generating high-quality time series frames for use in GIF movies. The following example applies the output to the Earth Engine getVideoThumbURL function to generate a GIF. Example: // load the LandTrendr.js module var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); // define parameters var startYear = 1984; var endYear = 2018; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); var index = 'NBR'; var ftvList = ['TCB', 'TCG', 'TCW']; // define LandTrendr parameters var runParams = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; // define the RGB visualization parameters var visParams = { min: [604, -49, -2245], max: [5592, 3147, 843], gamma: [1, 1, 1] }; // define the GIF video parameters var vidParams = { crs: 'EPSG:3857', dimensions: 300, region: aoi.buffer(10000).bounds(), framesPerSecond: 8 }; // apply LandTrendr.js functions var lt = ltgee.runLT(startYear, endYear, startDay, endDay, aoi, index, ftvList, runParams); // get RGB collection var rgbCol = ltgee.getFittedRGBcol(lt, startYear, endYear, ftvList, visParams); // print the RGB GIF link print(rgbCol.getVideoThumbURL(vidParams)); // show RGB image for year 2000 on map var rgb2000 = rgbCol.filterDate('2000-01-01', '2000-12-31').first().clip(vidParams.region); Map.centerObject(rgb2000, 10); Map.addLayer(rgb2000, {}, 'TC/RGB'); 9.2 Spectral index codes The LandTrendr.js functions library has a defined list of indices and bands that it will work with. Below in Table 9.1 is the list of ‘index’ codes to use and their common name. You should specify them as an all caps string. Table 9.1: Spectral Index Codes Code Name NBR Normalized Burn Ratio NDVI Normalized Difference Vegetation Index NDSI Normalized Different Snow Index NDMI Normalized Difference Moisture Index TCB Tasseled-Cap Brightness TCG Tasseled-Cap Greenness TCW Tasseled-Cap Wetness TCA Tasseled-Cap Angle B1 Thematic Mapper-equivalent Band 1 B2 Thematic Mapper-equivalent Band 2 B3 Thematic Mapper-equivalent Band 3 B4 Thematic Mapper-equivalent Band 4 B5 Thematic Mapper-equivalent Band 5 B7 Thematic Mapper-equivalent Band 7 "],
["validation.html", "10 Validation", " 10 Validation The traditional method for validation of LandTrendr segmentation and derived disturbance maps is the TimeSync application (paper). It was developed as a companion to LandTrendr and follows the same spectral-temporal vertex and segmentation framework. Please see this GitHub repository for all the files and instructions you need to get source data from Google Earth Engine and run the desktop Legacy version of the application. "],
["faq.html", "11 FAQ", " 11 FAQ Q: I have read or heard that for loops and client-side conditionals like if statements are GEE no-nos, yet you include them in your example scripts. What’s the deal?A: We don’t mix server-side and client-side objects and operations, which, as we understand it, are the main issues. We are also not GEE wizards, so please, we are calling on everyone to help make better, more GEE-friendly template scripts to share. "],
["references.html", "12 References", " 12 References Cohen, W. B., Yang, Z., & Kennedy, R. (2010). Detecting trends in forest disturbance and recovery using yearly Landsat time series: 2. TimeSync-Tools for calibration and validation. Remote Sensing of Environment, 114(12), 2911-2924. Gorelick, N., Hancher, M., Dixon, M., Ilyushchenko, S., Thau, D., & Moore, R. (2017). Google Earth Engine: Planetary-scale geospatial analysis for everyone. Remote Sensing of Environment, 202, 18-27. Kennedy, R. E., Yang, Z., & Cohen, W. B. (2010). Detecting trends in forest disturbance and recovery using yearly Landsat time series: 1. LandTrendr—Temporal segmentation algorithms. Remote Sensing of Environment, 114(12), 2897-2910. Kennedy, R. E., Yang, Z., Cohen, W. B., Pfaff, E., Braaten, J., & Nelson, P. (2012). Spatial and temporal patterns of forest disturbance and regrowth within the area of the Northwest Forest Plan. Remote Sensing of Environment, 122, 117-133. Kennedy, R.E., Yang, Z., Gorelick, N., Braaten, J., Cavalcante, L., Cohen, W.B., Healey, S. (2018). Implementation of the LandTrendr Algorithm on Google Earth Engine. Remote Sensing. 10, 691. Roy, D. P., Kovalskyy, V., Zhang, H. K., Vermote, E. F., Yan, L., Kumar, S. S., & Egorov, A. (2016). Characterization of Landsat-7 to Landsat-8 reflective wavelength and normalized difference vegetation index continuity. Remote Sensing of Environment, 185, 57-70. Zhu, Z., Wang, S., & Woodcock, C. E. (2015). Improvement and expansion of the Fmask algorithm: Cloud, cloud shadow, and snow detection for Landsats 4-7, 8, and Sentinel 2 images. Remote Sensing of Environment, 159, 269-277. "],