From 91b6543e1e3ecc36f9a89ae4afeac0cc1e437787 Mon Sep 17 00:00:00 2001 From: Justin Braaten Date: Tue, 12 Jun 2018 08:26:04 -0700 Subject: [PATCH] changes --- .../wide_and_narrow_table_examples.txt | 0 test/example-scripts.html | 237 -------------- test/faq.html | 218 ------------- test/index.html | 237 -------------- test/introduction.html | 218 ------------- test/landtrendr.html | 245 -------------- test/lt-gee-outputs.html | 273 ---------------- test/lt-gee-requirements.html | 305 ------------------ test/lt-gee.html | 184 ----------- test/references.html | 233 ------------- test/running-lt-gee.html | 273 ---------------- test/search_index.json | 15 - test/shortcut-functions.html | 278 ---------------- test/style.css | 4 - test/ui-applications.html | 289 ----------------- test/validation.html | 218 ------------- test/working-with-outputs.html | 294 ----------------- 17 files changed, 3521 deletions(-) rename {misc => bookdown}/wide_and_narrow_table_examples.txt (100%) delete mode 100644 test/example-scripts.html delete mode 100644 test/faq.html delete mode 100644 test/index.html delete mode 100644 test/introduction.html delete mode 100644 test/landtrendr.html delete mode 100644 test/lt-gee-outputs.html delete mode 100644 test/lt-gee-requirements.html delete mode 100644 test/lt-gee.html delete mode 100644 test/references.html delete mode 100644 test/running-lt-gee.html delete mode 100644 test/search_index.json delete mode 100644 test/shortcut-functions.html delete mode 100644 test/style.css delete mode 100644 test/ui-applications.html delete mode 100644 test/validation.html delete mode 100644 test/working-with-outputs.html diff --git a/misc/wide_and_narrow_table_examples.txt b/bookdown/wide_and_narrow_table_examples.txt similarity index 100% rename from misc/wide_and_narrow_table_examples.txt rename to bookdown/wide_and_narrow_table_examples.txt diff --git a/test/example-scripts.html b/test/example-scripts.html deleted file mode 100644 index 640872c..0000000 --- a/test/example-scripts.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

7 Example Scripts

-

Three use case examples are provided, each of them begins with the same process of parameter definition and collection building and then varies on what is done with the results from the LT-GEE call. Keep in mind that these are simple building blocks to learn from. The parameter settings, methods for building collections, and the way we handle outputs in these examples are not intended to be standard protocol. We hope that the GEE community will help us develop better scripts and push what we can learn about our dynamic Earth using the LT-GEE tool.

-
-

7.1 Exploration and parameterization

-

LandTrendr can be run in point mode to visualize the segmentation for a pixel. This is really useful for quickly testing the performance of various parameter settings and spectral indices, as well as simply viewing and interpreting change in the x-y space of time and spectral value for both the source and LandTrendr trajectory-fitted data. We recommend starting here to understand how best to set parameters for your mapping project.

-

-

Example script

-

GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Pixel Time Series Plotter

-
-
-

7.2 Data generation

-

LandTrendr can be run in a data generation mode where every pixel time series within the bounds of a given region is segmented and a data cube containing the segmented line structure and trajectory-fitted time series stack is returned. The results are the basic building blocks for historical landscape state and change mapping. Before generating data cubes, it is best to explore and parameterize LT-GEE using the 1st example script.

-

-

Example script

-

GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Vertex and Fitted Data Generation

-
-
-

7.3 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. In this example we take the data cube generated in the previous example and extract the greatest disturbance per pixel in a region.

-

-

Example script

-

GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Greatest Disturbance Mapping

- -
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/faq.html b/test/faq.html deleted file mode 100644 index 25bb471..0000000 --- a/test/faq.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

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.

-
- -
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/index.html b/test/index.html deleted file mode 100644 index 7de2a63..0000000 --- a/test/index.html +++ /dev/null @@ -1,237 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
- -
-

Welcome

-

Documentation by Justin Braaten of Oregon State University’s eMapR Lab

-

2018/06/11

-
-

This site is a guide to the Google Earth Engine implementation of the LandTrendr spectral-temporal segmentation algorithm.

-

-
-
-

Jump right in - plot a segmented time series or map disturbance with a GUI!

-

*Some sections are still under construction (6/11/18) - check back frequenty in the coming month for additional UI applications and shortcut functions. You might try doing a hard refresh on the site to make sure you see recent changes (what you’re looking at might be a previously cached version of the site)

- -
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/introduction.html b/test/introduction.html deleted file mode 100644 index 6208466..0000000 --- a/test/introduction.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

1 Introduction

-

LandTrendr (LT) is set of spectral-temporal segmentation algorithms that are useful for change detection in a time series of moderate resolution satellite imagery (primarily Landsat) and for generating trajectory-based spectral time series data largely absent of inter-annual signal noise. LandTrendr was originally implemented in IDL (Interactive Data Language), but with the help of engineers at Google, it has been ported to the Google Earth Engine (GEE) platform (porting paper; GEE overview; GEE paper). The GEE framework nearly eliminates the onerous data management and image-preprocessing aspects of the IDL implementation. It is also light-years faster than the IDL implementation, where computing time is measured in minutes instead of days.

-

This guide is intended to introduce the basics of running LandTrendr in GEE. It describes the LandTrendr conceptual framework, what is required to run LT-GEE, how to run it, what the outputs are, and how they are formatted. It also provides three example scripts, a series of user interfaces to the LT operations, and a shortcut JavaScript library.

-

It is assumed that you have a GEE account, that you are somewhat familiar with the GEE JavaScript API, and have a basic understanding of LandTrendr (method, application).

- -
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/landtrendr.html b/test/landtrendr.html deleted file mode 100644 index 456f837..0000000 --- a/test/landtrendr.html +++ /dev/null @@ -1,245 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

2 LandTrendr

-

Each pixel in an image time series has a story to tell, LandTrendr aims to tell them succinctly. Let’s look at an example; here we have a pixel intersecting Lon: -123.845, Lat: 45.889 (Fig 2.1) from a conifer-dominated, industrial forest region of the Pacific Northwest, USA. At the beginning of its record, it was a mature, second-growth conifer stand, and for 17 years, little changed. Then, between the summers of 2000 and 2001 a service road was built through it, removing some of its vegetation. Over the next year it experienced a clearcut harvest, removing all of its remaining vegetation. For the last 14 years it has been regenerating. Most recently it was a closed canopy, maturing, conifer stand.

-

-

Fig 2.1. Every pixel tells a story. Landsat provides a historical record of the character of landscapes. By extracting a single pixel from a time series of Landsat imagery, it is possible to recount the state and change of the features composing the 1-hectare area of a pixel through time. In this example, we analyze the history of a conifer forest pixel from an industrial forest region of the Pacific Northwest (USA) that experiences a period of relative stability, a dramatic, rapid loss of vegetation, and subsequent regeneration.

-

The description of this example pixel’s history is of course abridged, and only conveys a moderate resolution perspective of state and change in forest character. The unabridged version of this pixel’s story includes many other small changes in the forest stand it represents, but given the precision of the satellite sensor and methods in processing, the provided description is the type of pixel history interpretation we are confident are represented well in the image time series. LandTrendr is a brevity algorithm that listens to the annual, verbose, noisy detail of a pixel’s story and writes an abridged version.

-

In practice, LandTrendr takes a single point-of-view from a pixel’s spectral history, like a band or an index, and goes through a process to identify breakpoints separating periods of durable change or stability in spectral trajectory, and records the year that changes occurred. These breakpoints, defined by year and spectral index value, allow us to represent the spectral history of a pixel as a series of vertices bounding line segments (Fig 2.2).

-

-

Fig 2.2. LandTrendr pixel time series segmentation. Image data is reduced to a single band or spectral index and then divided into a series of straight line segments by breakpoint (vertex) identification.

-

There are two neat features that result from this segmented view of spectral history.

-
    -
  1. The ability to interpolate new values for years between vertices.
  2. -
  3. Simple geometry calculations on line segments provide information about distinct spectral epochs
  4. -
-
-

2.1 Fit-to-Vertex Image Data

-

The ability to interpolate new values for years between vertices is very useful. It ensures that each observation is aligned to a trajectory consistent with where the pixel has been and where it is going. We can think of this as hindsight-enhanced image time series data. It has two practical utilities. It can fill in data from missing observations in the time series (masked because of cloud or shadow) and it maintains consistency in predictive mapping through time; e.g. an annual forest classification is not likely to bounce between mature and old-growth conifer because of minor differences in spectral reflectance from atmosphere or shadow difference (Fig 2.3).

-

-

Fig 2.3. Hindsight-enhanced image time series data. Identification of time series breakpoints or vertices, allows the observations between vertices to be interpolated, removing extraneous information and placing each observation in the context of the trajectory it is part of. This is useful in filling missing observations because of cloud and shadow, and makes for more consistent annual map prediction.

-

Since breakpoints or vertices are defined by a year we also have the ability to impose breakpoints identified in one spectral band or index on any other. For instance, we can segment a pixel time series cast as Normalized Burn Ratio (NBR: [NIR-SWIR]/[NIR+SWIR]) to identify vertices, and then segment a short-wave infrared (SWIR) band based on the NBR-identified vertices (Fig 2.4).

-

-

Fig 2.4. Impose the segmentation structure of one spectral representation on another. Here we have identified four breakpoints or vertices for a pixel time series using NBR, and then used the year of those vertices to segment and interpolate the values of a SWIR band time series for the same pixel.

-

This is useful because we can make the whole data space for a pixel’s time series consistent relative to a single perspective (Fig 2.5) and summarize starting, ending, and delta values for all spectral representations for the same temporal segments, which can be powerful predictors of land cover, agent of change, and state transitions.

-

-

Fig 2.5. A stack of spectral representations can be standardized to the segmentation structure of a single spectral band or index. Here we are demonstrating the standardization of tasseled cap brightness, greenness, and wetness to the segmentation structure of NBR. This allows us to take advantage of multi-dimensional spectral space to describe the properties of spectral epochs and breakpoints to predict land cover, change process, and transitions from a consistent perspective (NBR).

-
-
-

2.2 Epoch Information

-

The second neat feature of a segmented world view of spectral history is that simple geometry calculations can summarize attributes of spectral epochs (Fig 2.6). Temporal duration and spectral magnitude can be calculated for each segment based on the vertex time and spectral dimensions. These attributes allow us to easily query the data about when changes occur, how frequently they occur, on average how long do they last, what is the average magnitude of disturbance (or recovery) segments, etc. We can also query information about adjacent segments to focal segments. For instance, we can ask, what it the average rate of recovery following a disturbance segment, or what was the trajectory of a pixel time series prior to disturbance segments that we’ve attributed to fire.

-

-

Fig 2.6. Diagram of segment attributes. From these attributes we can summarize and query change per pixel over the landscape.

- -
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/lt-gee-outputs.html b/test/lt-gee-outputs.html deleted file mode 100644 index f894cfb..0000000 --- a/test/lt-gee-outputs.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

5 LT-GEE Outputs

-

The results of LT-GEE include (Fig 5.1):

-
    -
  • The year of observations per pixel time series; x-axis values in 2-D spectral-temporal space; (default)
  • -
  • The source value of observations per pixel time series; y-axis values in 2-D spectral-temporal space; (default)
  • -
  • The source value of observations fitted to segment lines between vertices (FTV) per pixel time series; y-axis values in 2-D spectral-temporal space; (default)
  • -
  • The root mean square error (RMSE) of the FTV values, relative to the source values; (default)
  • -
  • Complete time series FTV values for additional bands in the collection greater than band 1; y-axis values in 2-D spectral-temporal space; (optional)
  • -
-

-

Fig 5.1. A visual diagram of what data are returned from LT-GEE. Every legend item is returned as an output.


-

The results of LT-GEE are not immediately ready for analysis, display, or export as maps of change or fitted time series data. Think of each pixel as a bundle of data that needs to be unpacked. The packaging of the data per pixel is similar to a nested list in Python or R. The primary list looks something like this:

-
[[Annual Segmentation Info], Fitting RMSE, [Fitted Time Series n]]
-

In the GEE construct, this primary list is an image with at least 2 bands, one that contains annual segmentation information and one that contains the RMSE of the segmentation fit. Additionally, if the input image collection to LT-GEE contained more than one band, then each band following the first will be represented as a spectrally fitted annual series (Fig 5.2 and Fig 5.3).

-


Fig 5.2. The results of LT-GEE are essentially a list of lists per pixel that describe segmentation and optionally provide fitted annual spectral data (FTV). The output is delivered as a GEE image with at least 2 bands, one that contains annual segmentation information and one that contains the RMSE of the segmentation fit. Additionally, if the input image collection to LT-GEE contained more than one band, then each band following the first will be represented as a spectrally fitted annual series (FTV).

-


Fig 5.3. The results of LT-GEE printed to the GEE console. The ‘LandTrendr’ and ‘rmse’ are included by default, ‘B4_fit’ is included because Landsat TM/+ETM band 4 (B4) was included as the second band in the input collection.


-
-

5.1 LandTrendr Band

-

The ‘LandTrendr’ band is a 4 x nYears dimension array. You can subset it like this:

-
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
-var segmentationInfo = LTresult.select(['LandTrendr']); // subset the LandTrendr segmentation info
-

It contains 4 rows and as many columns as there are annual observations for a given pixel through the time series. The 2-D ‘LandTrendr’ annual segmentation array looks like this:

-
[
-  [1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, ...] // Year list 
-  [ 811,  809,  821,  813,  836,  834,  833,  818,  826,  820,  765,  827,  775, ...] // Source list
-  [ 827,  825,  823,  821,  819,  817,  814,  812,  810,  808,  806,  804,  802, ...] // Fitted list
-  [   1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1, ...] // Is Vertex list
-]
-
    -
  • Row 1 is the observation year.
  • -
  • Row 2 is the observation value corresponding to the year in row 1, it is equal to the first band in the input collection.
  • -
  • Row 3 is the observation value corresponding to the year in row 1, fitted to line segments defined by breakpoint vertices identified in segmentation.
  • -
  • Row 4 is a Boolean value indicating whether an observation was identified as a vertex.
  • -
-

You can extract a row using the GEE arraySlice function. Here is an example of the extracting the year and fitted value rows as separate lists:

-
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
-var LTarray = LTresult.select(['LandTrendr']); // subset the LandTrendr segmentation info
-var year = LTarray.arraySlice(0, 0, 1); // slice out the year row
-var fitted = LTarray.arraySlice(0, 2, 3); // slice out the fitted values row
-

The GEE arraySlice function takes the dimension you want to subset and the start and end points along the dimension to extract as inputs.

-
-
-

5.2 RMSE

-

The ‘rmse’ band is a scalar value that is the root mean square error between the original values and the segmentation-fitted values.

-

It can be subset like this:

-
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
-var segmentationInfo = LTresult.select(['rmse']); // subset the rmse band
-
-
-

5.3 FTV

-

If the the input image collection included more than one band, the proceeding bands will be included in the output image as FTV or fit-to-vertice data bands. The segmentation, defined by year of observation, of the first band in the image collection is imparted on these bands. If there were missing years in the input image collection, they will be interpolated in the FTV bands. If years at the beginning or end of the series are present, the value will be set as the first/last known value.

-

It can be subset from the primary output image by selection of the band name, which will be the the concatenation of the band name from the input image collection and ’_fit’, as in ‘B4_fit’. Here is an example of subsetting an FTV ‘fit’ band:

-
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
-var B4ftv = LTresult.select(['B4_fit']); // subset the B4_fit band
-

If you’re unsure of the band names, you can view the band names by printing the results to the GEE console.

-
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE
-print(LTresult)
-

Then expand in the ‘Image’ and ‘Band’ objects in the console.

- -
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/lt-gee-requirements.html b/test/lt-gee-requirements.html deleted file mode 100644 index 20a0eda..0000000 --- a/test/lt-gee-requirements.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

3 LT-GEE Requirements

-

LT-GEE requires two things:

-
    -
  1. An annual image collection
  2. -
  3. A set of parameters to control segmentation
  4. -
-
-

3.1 Image Collection

-

The image data composing a collection needs to represent an observation that is consistent through time. It should not include noise from atmosphere, clouds and shadows, sensor differences, or other anomalies. The annual changes in a time series should be the result of changes in the physical features of a landscape. We recommend using the USGS Landsat Surface Reflectance Tier 1 data sets. These data have been atmospherically corrected, and include a cloud, shadow, water and snow mask produced using CFMASK.

-

GEE ImageCollection IDs for USGS Landsat Surface Reflectance

-
    -
  • Landsat 5: LANDSAT/LT05/C01/T1_SR
  • -
  • Landsat 7: LANDSAT/LE07/C01/T1_SR
  • -
  • Landsat 8: LANDSAT/LC08/C01/T1_SR
  • -
-

The collection must include only one observation per year. However, because clouds are often present in any given image, it is best to retrieve multiple images for a season, mask out clouds and cloud shadows from each, and then create a composite of those images so that you have reasonable annual spatial coverage of clear-view pixels. The best-pixel-compositing method you apply is up to you. We have used nearness to a target day-of-year and also medoid compositing, we prefer the later and include it in the provided examples. LandTrendr will segment the first band in the image collection and generate annual fitted-to-vertex (FTV) data for each subsequent band. Consequently, you need to manipulate your collection so that the band or spectral index you want segmented is the first band, and any additional bands you want fitted to vertices should follow. The band or index you select for segmentation should be based on an informed decision weighted by the sensitivity of it to change in the conditions of the landscape you are working with. The best spectral representation of change can be different for shrubs vs trees vs conifers vs deciduous etc. We have found SWIR bands, and indices leveraging them, to be generally quite sensitive to change, but we also know that it is highly variable. You should try segmenting on several bands or indices to see what works best. We also recommend trying a few different date windows and widths for generating annual composites.

-

In the example scripts provided, we composite image dates for the northern hemisphere growing season (mid-June through mid-September), which seems to work pretty well for 25-50 degrees latitude. Folks working in the southern hemisphere will need to modify the example scripts if you are to include images from your growing season, since it crosses the new year: December 2016 through February 2017, for example. You’ll also have to deal with how to label the year of the annual image composite - should it be the former or later year of the growing season composite?

-

Two really important steps in image collection building include 1) masking cloud and cloud shadow pixels during annual image compositing and to 2) ensure that the spectral band or index that is to be segmented is oriented so that vegetation loss is represented by a positive delta. For instance, NBR in its native orientation results in a negative delta when vegetation is lost from one observation to the next. In this case, NBR must be multiplied by -1 before being segmented. Conversely, if Landsat TM band 5 (SWIR) is selected for segmentation, inversion of the spectral values is not required, since natively, vegetation loss is represented by a positive delta.

-

Note that we provide a couple of shortcut functions to build annual surface reflectance collections and convert it to a collection formatted for use by LandTrendr. See the buildSRcollection and buildLTcollection functions in the Shortcut Functions section.

-
-
-

3.2 LT parameters

-

The LT-GEE function takes 9 arguments: 8 control parameters that adjust how spectral-temporal segmentation is done, and the annual image collection. The original LandTrendr paper describes the effect and sensitivity of changing some of these argument values. We recommend trying variations in settings to see what works best for the environment you are working in. One of the great things about having LT in GEE is that parameter settings are easy and fast to iterate through to find a best set.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 3.1: LandTrendr parameters
ParameterTypeDefaultDefinition
maxSegmentsIntegerMaximum number of segments to be fitted on the time series
spikeThresholdFloat0.9Threshold for dampening the spikes (1.0 means no dampening)
vertexCountOvershootInteger3The inital model can overshoot the maxSegments + 1 vertices by this amount. Later, it will be prunned down to maxSegments + 1
preventOneYearRecoveryBooleanfalsePrevent segments that represent one year recoveries
recoveryThresholdFloat0.25If a segment has a recovery rate faster than 1/recoveryThreshold (in years), then the segment is disallowed
pvalThresholdFloat0.1If the p-value of the fitted model exceeds this threshold, then the current model is discarded and another one is fitted using the Levenberg-Marquardt optimizer
bestModelProportionFloat1.25Takes the model with most vertices that has a p-value that is at most this proportion away from the model with lowest p-value
minObservationsNeededInteger6Min observations needed to perform output fitting
timeSeriesImageCollectionCollection from which to extract trends (it’s assumed that each image in the collection represents one year). The first band is used to find breakpoints, and all subsequent bands are fitted using those breakpoints
- -
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/lt-gee.html b/test/lt-gee.html deleted file mode 100644 index 34582aa..0000000 --- a/test/lt-gee.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

LT-GEE

- -
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/references.html b/test/references.html deleted file mode 100644 index 1367d28..0000000 --- a/test/references.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - diff --git a/test/running-lt-gee.html b/test/running-lt-gee.html deleted file mode 100644 index 3751d9f..0000000 --- a/test/running-lt-gee.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

4 Running LT-GEE

-

LT-GEE is run using the function: ee.Algorithms.TemporalSegmentation.LandTrendr which takes a dictionary of parameter arguments as input.

-

In its most most basic form, running LandTrendr in Google Earth Engine requires 6 steps. The following code snippets help illustrate the steps.

-

The following snippets are only a demonstration aid. In application, use the provided code examples to learn and build from, and take advantage of the shortcut functions we’ve put together to build collections and run LandTrendr

-
    -
  1. Define starting and ending years of the times series
  2. -
-
var startYear = 1985;
-var endYear   = 2010;
-
    -
  1. Define an area to run LandTrendr on as an ee.Geometry
  2. -
-
var coords = [[-123.925, 42.996],
-              [-122.327, 42.996],
-              [-122.327, 43.548],
-              [-123.925, 43.548],
-              [-123.925, 42.996]];
-
-var aoi = ee.Geometry.Polygon(coords);
-
    -
  1. Define the LandTrendr run parameters as a dictionary. See the parameters section for definitions. Note that the image collection will be appended to this dictionary in a later step.
  2. -
-
var run_params = { 
-  maxSegments:            6,
-  spikeThreshold:         0.9,
-  vertexCountOvershoot:   3,
-  preventOneYearRecovery: true,
-  recoveryThreshold:      0.25,
-  pvalThreshold:          0.05,
-  bestModelProportion:    0.75,
-  minObservationsNeeded:  6
-};
-
    -
  1. Build an image collection that includes only one image per year, subset to a single band or index (you can include other bands - the first will be segmented, the others will be fit to the vertices). Note that we are using a mock function to reduce annual image collections to a single image - this can be accomplished many ways using various best-pixel-compositing methods.
  2. -
-
for(var year = startYear; year <= endYear; year++) {
-  var img = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
-              .filterBounds(aoi)
-              .filterDate(year+'-06-15', year+'-09-15');
-  
-  img = reduceToSingeImageMockFunction(img);
-
-  var tempCollection = ee.ImageCollection(img.select(['B5']));         
-
-  if(year == startYear) {
-    var srCollection = tempCollection;
-  } else {
-    srCollection = srCollection.merge(tempCollection);
-  }
-};
-
    -
  1. Append the image collection to the LandTrendr run parameter dictionary
  2. -
-
run_params.timeSeries = srCollection;
-
    -
  1. Run the LandTrendr algorithm
  2. -
-
var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params);
-

Please note that for the sake of a basic example LT-GEE run, we are not addressing the two really important steps in collection building: 1) to mask cloud and cloud shadow pixels during annual image compositing (step 4) and 2) to ensure that the spectral band or index that is to be segmented is oriented so that vegetation loss is represented by a positive delta (we used a SWIR band, which is the correct orientation for use in LT-GEE).

- -
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/search_index.json b/test/search_index.json deleted file mode 100644 index 9df0d8a..0000000 --- a/test/search_index.json +++ /dev/null @@ -1,15 +0,0 @@ -[ -["index.html", "LT-GEE Guide Welcome", " LT-GEE Guide Welcome Documentation by Justin Braaten of Oregon State University’s eMapR Lab 2018/06/11 This site is a guide to the Google Earth Engine implementation of the LandTrendr spectral-temporal segmentation algorithm. Jump right in - plot a segmented time series or map disturbance with a GUI! *Some sections are still under construction (6/11/18) - check back frequenty in the coming month for additional UI applications and shortcut functions. You might try doing a hard refresh on the site to make sure you see recent changes (what you’re looking at might be a previously cached version of the site) "], -["introduction.html", "1 Introduction", " 1 Introduction LandTrendr (LT) is set of spectral-temporal segmentation algorithms that are useful for change detection in a time series of moderate resolution satellite imagery (primarily Landsat) and for generating trajectory-based spectral time series data largely absent of inter-annual signal noise. LandTrendr was originally implemented in IDL (Interactive Data Language), but with the help of engineers at Google, it has been ported to the Google Earth Engine (GEE) platform (porting paper; GEE overview; GEE paper). The GEE framework nearly eliminates the onerous data management and image-preprocessing aspects of the IDL implementation. It is also light-years faster than the IDL implementation, where computing time is measured in minutes instead of days. This guide is intended to introduce the basics of running LandTrendr in GEE. It describes the LandTrendr conceptual framework, what is required to run LT-GEE, how to run it, what the outputs are, and how they are formatted. It also provides three example scripts, a series of user interfaces to the LT operations, and a shortcut JavaScript library. It is assumed that you have a GEE account, that you are somewhat familiar with the GEE JavaScript API, and have a basic understanding of LandTrendr (method, application). "], -["landtrendr.html", "2 LandTrendr 2.1 Fit-to-Vertex Image Data 2.2 Epoch Information", " 2 LandTrendr Each pixel in an image time series has a story to tell, LandTrendr aims to tell them succinctly. Let’s look at an example; here we have a pixel intersecting Lon: -123.845, Lat: 45.889 (Fig 2.1) from a conifer-dominated, industrial forest region of the Pacific Northwest, USA. At the beginning of its record, it was a mature, second-growth conifer stand, and for 17 years, little changed. Then, between the summers of 2000 and 2001 a service road was built through it, removing some of its vegetation. Over the next year it experienced a clearcut harvest, removing all of its remaining vegetation. For the last 14 years it has been regenerating. Most recently it was a closed canopy, maturing, conifer stand. Fig 2.1. Every pixel tells a story. Landsat provides a historical record of the character of landscapes. By extracting a single pixel from a time series of Landsat imagery, it is possible to recount the state and change of the features composing the 1-hectare area of a pixel through time. In this example, we analyze the history of a conifer forest pixel from an industrial forest region of the Pacific Northwest (USA) that experiences a period of relative stability, a dramatic, rapid loss of vegetation, and subsequent regeneration. The description of this example pixel’s history is of course abridged, and only conveys a moderate resolution perspective of state and change in forest character. The unabridged version of this pixel’s story includes many other small changes in the forest stand it represents, but given the precision of the satellite sensor and methods in processing, the provided description is the type of pixel history interpretation we are confident are represented well in the image time series. LandTrendr is a brevity algorithm that listens to the annual, verbose, noisy detail of a pixel’s story and writes an abridged version. In practice, LandTrendr takes a single point-of-view from a pixel’s spectral history, like a band or an index, and goes through a process to identify breakpoints separating periods of durable change or stability in spectral trajectory, and records the year that changes occurred. These breakpoints, defined by year and spectral index value, allow us to represent the spectral history of a pixel as a series of vertices bounding line segments (Fig 2.2). Fig 2.2. LandTrendr pixel time series segmentation. Image data is reduced to a single band or spectral index and then divided into a series of straight line segments by breakpoint (vertex) identification. There are two neat features that result from this segmented view of spectral history. The ability to interpolate new values for years between vertices. Simple geometry calculations on line segments provide information about distinct spectral epochs 2.1 Fit-to-Vertex Image Data The ability to interpolate new values for years between vertices is very useful. It ensures that each observation is aligned to a trajectory consistent with where the pixel has been and where it is going. We can think of this as hindsight-enhanced image time series data. It has two practical utilities. It can fill in data from missing observations in the time series (masked because of cloud or shadow) and it maintains consistency in predictive mapping through time; e.g. an annual forest classification is not likely to bounce between mature and old-growth conifer because of minor differences in spectral reflectance from atmosphere or shadow difference (Fig 2.3). Fig 2.3. Hindsight-enhanced image time series data. Identification of time series breakpoints or vertices, allows the observations between vertices to be interpolated, removing extraneous information and placing each observation in the context of the trajectory it is part of. This is useful in filling missing observations because of cloud and shadow, and makes for more consistent annual map prediction. Since breakpoints or vertices are defined by a year we also have the ability to impose breakpoints identified in one spectral band or index on any other. For instance, we can segment a pixel time series cast as Normalized Burn Ratio (NBR: [NIR-SWIR]/[NIR+SWIR]) to identify vertices, and then segment a short-wave infrared (SWIR) band based on the NBR-identified vertices (Fig 2.4). Fig 2.4. Impose the segmentation structure of one spectral representation on another. Here we have identified four breakpoints or vertices for a pixel time series using NBR, and then used the year of those vertices to segment and interpolate the values of a SWIR band time series for the same pixel. This is useful because we can make the whole data space for a pixel’s time series consistent relative to a single perspective (Fig 2.5) and summarize starting, ending, and delta values for all spectral representations for the same temporal segments, which can be powerful predictors of land cover, agent of change, and state transitions. Fig 2.5. A stack of spectral representations can be standardized to the segmentation structure of a single spectral band or index. Here we are demonstrating the standardization of tasseled cap brightness, greenness, and wetness to the segmentation structure of NBR. This allows us to take advantage of multi-dimensional spectral space to describe the properties of spectral epochs and breakpoints to predict land cover, change process, and transitions from a consistent perspective (NBR). 2.2 Epoch Information The second neat feature of a segmented world view of spectral history is that simple geometry calculations can summarize attributes of spectral epochs (Fig 2.6). Temporal duration and spectral magnitude can be calculated for each segment based on the vertex time and spectral dimensions. These attributes allow us to easily query the data about when changes occur, how frequently they occur, on average how long do they last, what is the average magnitude of disturbance (or recovery) segments, etc. We can also query information about adjacent segments to focal segments. For instance, we can ask, what it the average rate of recovery following a disturbance segment, or what was the trajectory of a pixel time series prior to disturbance segments that we’ve attributed to fire. Fig 2.6. Diagram of segment attributes. From these attributes we can summarize and query change per pixel over the landscape. "], -["lt-gee-requirements.html", "3 LT-GEE Requirements 3.1 Image Collection 3.2 LT parameters", " 3 LT-GEE Requirements LT-GEE requires two things: An annual image collection A set of parameters to control segmentation 3.1 Image Collection The image data composing a collection needs to represent an observation that is consistent through time. It should not include noise from atmosphere, clouds and shadows, sensor differences, or other anomalies. The annual changes in a time series should be the result of changes in the physical features of a landscape. We recommend using the USGS Landsat Surface Reflectance Tier 1 data sets. These data have been atmospherically corrected, and include a cloud, shadow, water and snow mask produced using CFMASK. GEE ImageCollection IDs for USGS Landsat Surface Reflectance Landsat 5: LANDSAT/LT05/C01/T1_SR Landsat 7: LANDSAT/LE07/C01/T1_SR Landsat 8: LANDSAT/LC08/C01/T1_SR The collection must include only one observation per year. However, because clouds are often present in any given image, it is best to retrieve multiple images for a season, mask out clouds and cloud shadows from each, and then create a composite of those images so that you have reasonable annual spatial coverage of clear-view pixels. The best-pixel-compositing method you apply is up to you. We have used nearness to a target day-of-year and also medoid compositing, we prefer the later and include it in the provided examples. LandTrendr will segment the first band in the image collection and generate annual fitted-to-vertex (FTV) data for each subsequent band. Consequently, you need to manipulate your collection so that the band or spectral index you want segmented is the first band, and any additional bands you want fitted to vertices should follow. The band or index you select for segmentation should be based on an informed decision weighted by the sensitivity of it to change in the conditions of the landscape you are working with. The best spectral representation of change can be different for shrubs vs trees vs conifers vs deciduous etc. We have found SWIR bands, and indices leveraging them, to be generally quite sensitive to change, but we also know that it is highly variable. You should try segmenting on several bands or indices to see what works best. We also recommend trying a few different date windows and widths for generating annual composites. In the example scripts provided, we composite image dates for the northern hemisphere growing season (mid-June through mid-September), which seems to work pretty well for 25-50 degrees latitude. Folks working in the southern hemisphere will need to modify the example scripts if you are to include images from your growing season, since it crosses the new year: December 2016 through February 2017, for example. You’ll also have to deal with how to label the year of the annual image composite - should it be the former or later year of the growing season composite? Two really important steps in image collection building include 1) masking cloud and cloud shadow pixels during annual image compositing and to 2) ensure that the spectral band or index that is to be segmented is oriented so that vegetation loss is represented by a positive delta. For instance, NBR in its native orientation results in a negative delta when vegetation is lost from one observation to the next. In this case, NBR must be multiplied by -1 before being segmented. Conversely, if Landsat TM band 5 (SWIR) is selected for segmentation, inversion of the spectral values is not required, since natively, vegetation loss is represented by a positive delta. Note that we provide a couple of shortcut functions to build annual surface reflectance collections and convert it to a collection formatted for use by LandTrendr. See the buildSRcollection and buildLTcollection functions in the Shortcut Functions section. 3.2 LT parameters The LT-GEE function takes 9 arguments: 8 control parameters that adjust how spectral-temporal segmentation is done, and the annual image collection. The original LandTrendr paper describes the effect and sensitivity of changing some of these argument values. We recommend trying variations in settings to see what works best for the environment you are working in. One of the great things about having LT in GEE is that parameter settings are easy and fast to iterate through to find a best set. Table 3.1: LandTrendr parameters Parameter Type Default Definition maxSegments Integer Maximum number of segments to be fitted on the time series spikeThreshold Float 0.9 Threshold for dampening the spikes (1.0 means no dampening) vertexCountOvershoot Integer 3 The inital model can overshoot the maxSegments + 1 vertices by this amount. Later, it will be prunned down to maxSegments + 1 preventOneYearRecovery Boolean false Prevent segments that represent one year recoveries recoveryThreshold Float 0.25 If a segment has a recovery rate faster than 1/recoveryThreshold (in years), then the segment is disallowed pvalThreshold Float 0.1 If the p-value of the fitted model exceeds this threshold, then the current model is discarded and another one is fitted using the Levenberg-Marquardt optimizer bestModelProportion Float 1.25 Takes the model with most vertices that has a p-value that is at most this proportion away from the model with lowest p-value minObservationsNeeded Integer 6 Min observations needed to perform output fitting timeSeries ImageCollection Collection from which to extract trends (it’s assumed that each image in the collection represents one year). The first band is used to find breakpoints, and all subsequent bands are fitted using those breakpoints "], -["running-lt-gee.html", "4 Running LT-GEE", " 4 Running LT-GEE LT-GEE is run using the function: ee.Algorithms.TemporalSegmentation.LandTrendr which takes a dictionary of parameter arguments as input. In its most most basic form, running LandTrendr in Google Earth Engine requires 6 steps. The following code snippets help illustrate the steps. The following snippets are only a demonstration aid. In application, use the provided code examples to learn and build from, and take advantage of the shortcut functions we’ve put together to build collections and run LandTrendr Define starting and ending years of the times series var startYear = 1985; var endYear = 2010; Define an area to run LandTrendr on as an ee.Geometry var coords = [[-123.925, 42.996], [-122.327, 42.996], [-122.327, 43.548], [-123.925, 43.548], [-123.925, 42.996]]; var aoi = ee.Geometry.Polygon(coords); Define the LandTrendr run parameters as a dictionary. See the parameters section for definitions. Note that the image collection will be appended to this dictionary in a later step. var run_params = { maxSegments: 6, spikeThreshold: 0.9, vertexCountOvershoot: 3, preventOneYearRecovery: true, recoveryThreshold: 0.25, pvalThreshold: 0.05, bestModelProportion: 0.75, minObservationsNeeded: 6 }; Build an image collection that includes only one image per year, subset to a single band or index (you can include other bands - the first will be segmented, the others will be fit to the vertices). Note that we are using a mock function to reduce annual image collections to a single image - this can be accomplished many ways using various best-pixel-compositing methods. for(var year = startYear; year <= endYear; year++) { var img = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR') .filterBounds(aoi) .filterDate(year+'-06-15', year+'-09-15'); img = reduceToSingeImageMockFunction(img); var tempCollection = ee.ImageCollection(img.select(['B5'])); if(year == startYear) { var srCollection = tempCollection; } else { srCollection = srCollection.merge(tempCollection); } }; Append the image collection to the LandTrendr run parameter dictionary run_params.timeSeries = srCollection; Run the LandTrendr algorithm var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); Please note that for the sake of a basic example LT-GEE run, we are not addressing the two really important steps in collection building: 1) to mask cloud and cloud shadow pixels during annual image compositing (step 4) and 2) to ensure that the spectral band or index that is to be segmented is oriented so that vegetation loss is represented by a positive delta (we used a SWIR band, which is the correct orientation for use in LT-GEE). "], -["lt-gee-outputs.html", "5 LT-GEE Outputs 5.1 LandTrendr Band 5.2 RMSE 5.3 FTV", " 5 LT-GEE Outputs The results of LT-GEE include (Fig 5.1): The year of observations per pixel time series; x-axis values in 2-D spectral-temporal space; (default) The source value of observations per pixel time series; y-axis values in 2-D spectral-temporal space; (default) The source value of observations fitted to segment lines between vertices (FTV) per pixel time series; y-axis values in 2-D spectral-temporal space; (default) The root mean square error (RMSE) of the FTV values, relative to the source values; (default) Complete time series FTV values for additional bands in the collection greater than band 1; y-axis values in 2-D spectral-temporal space; (optional) Fig 5.1. A visual diagram of what data are returned from LT-GEE. Every legend item is returned as an output. The results of LT-GEE are not immediately ready for analysis, display, or export as maps of change or fitted time series data. Think of each pixel as a bundle of data that needs to be unpacked. The packaging of the data per pixel is similar to a nested list in Python or R. The primary list looks something like this: [[Annual Segmentation Info], Fitting RMSE, [Fitted Time Series n]] In the GEE construct, this primary list is an image with at least 2 bands, one that contains annual segmentation information and one that contains the RMSE of the segmentation fit. Additionally, if the input image collection to LT-GEE contained more than one band, then each band following the first will be represented as a spectrally fitted annual series (Fig 5.2 and Fig 5.3). Fig 5.2. The results of LT-GEE are essentially a list of lists per pixel that describe segmentation and optionally provide fitted annual spectral data (FTV). The output is delivered as a GEE image with at least 2 bands, one that contains annual segmentation information and one that contains the RMSE of the segmentation fit. Additionally, if the input image collection to LT-GEE contained more than one band, then each band following the first will be represented as a spectrally fitted annual series (FTV). Fig 5.3. The results of LT-GEE printed to the GEE console. The ‘LandTrendr’ and ‘rmse’ are included by default, ‘B4_fit’ is included because Landsat TM/+ETM band 4 (B4) was included as the second band in the input collection. 5.1 LandTrendr Band The ‘LandTrendr’ band is a 4 x nYears dimension array. You can subset it like this: var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE var segmentationInfo = LTresult.select(['LandTrendr']); // subset the LandTrendr segmentation info It contains 4 rows and as many columns as there are annual observations for a given pixel through the time series. The 2-D ‘LandTrendr’ annual segmentation array looks like this: [ [1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, ...] // Year list [ 811, 809, 821, 813, 836, 834, 833, 818, 826, 820, 765, 827, 775, ...] // Source list [ 827, 825, 823, 821, 819, 817, 814, 812, 810, 808, 806, 804, 802, ...] // Fitted list [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ...] // Is Vertex list ] Row 1 is the observation year. Row 2 is the observation value corresponding to the year in row 1, it is equal to the first band in the input collection. Row 3 is the observation value corresponding to the year in row 1, fitted to line segments defined by breakpoint vertices identified in segmentation. Row 4 is a Boolean value indicating whether an observation was identified as a vertex. You can extract a row using the GEE arraySlice function. Here is an example of the extracting the year and fitted value rows as separate lists: var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE var LTarray = LTresult.select(['LandTrendr']); // subset the LandTrendr segmentation info var year = LTarray.arraySlice(0, 0, 1); // slice out the year row var fitted = LTarray.arraySlice(0, 2, 3); // slice out the fitted values row The GEE arraySlice function takes the dimension you want to subset and the start and end points along the dimension to extract as inputs. 5.2 RMSE The ‘rmse’ band is a scalar value that is the root mean square error between the original values and the segmentation-fitted values. It can be subset like this: var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE var segmentationInfo = LTresult.select(['rmse']); // subset the rmse band 5.3 FTV If the the input image collection included more than one band, the proceeding bands will be included in the output image as FTV or fit-to-vertice data bands. The segmentation, defined by year of observation, of the first band in the image collection is imparted on these bands. If there were missing years in the input image collection, they will be interpolated in the FTV bands. If years at the beginning or end of the series are present, the value will be set as the first/last known value. It can be subset from the primary output image by selection of the band name, which will be the the concatenation of the band name from the input image collection and ’_fit’, as in ‘B4_fit’. Here is an example of subsetting an FTV ‘fit’ band: var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE var B4ftv = LTresult.select(['B4_fit']); // subset the B4_fit band If you’re unsure of the band names, you can view the band names by printing the results to the GEE console. var LTresult = ee.Algorithms.TemporalSegmentation.LandTrendr(run_params); // run LT-GEE print(LTresult) Then expand in the ‘Image’ and ‘Band’ objects in the console. "], -["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 Shortcut 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. 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 Exploration and parameterization 7.2 Data generation 7.3 Change mapping", " 7 Example Scripts Three use case examples are provided, each of them begins with the same process of parameter definition and collection building and then varies on what is done with the results from the LT-GEE call. Keep in mind that these are simple building blocks to learn from. The parameter settings, methods for building collections, and the way we handle outputs in these examples are not intended to be standard protocol. We hope that the GEE community will help us develop better scripts and push what we can learn about our dynamic Earth using the LT-GEE tool. 7.1 Exploration and parameterization LandTrendr can be run in point mode to visualize the segmentation for a pixel. This is really useful for quickly testing the performance of various parameter settings and spectral indices, as well as simply viewing and interpreting change in the x-y space of time and spectral value for both the source and LandTrendr trajectory-fitted data. We recommend starting here to understand how best to set parameters for your mapping project. Example script GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Pixel Time Series Plotter 7.2 Data generation LandTrendr can be run in a data generation mode where every pixel time series within the bounds of a given region is segmented and a data cube containing the segmented line structure and trajectory-fitted time series stack is returned. The results are the basic building blocks for historical landscape state and change mapping. Before generating data cubes, it is best to explore and parameterize LT-GEE using the 1st example script. Example script GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Vertex and Fitted Data Generation 7.3 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. In this example we take the data cube generated in the previous example and extract the greatest disturbance per pixel in a region. Example script GEE path: users/emaprlab/public:Scripts/LandTrendr Examples/LandTrendr Greatest Disturbance Mapping "], -["ui-applications.html", "8 UI Applications 8.1 UI LandTrendr Pixel Time Series Plotter 8.2 UI LandTrendr Disturbance 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, it can be found within the Reader permission group of your GEE scripts library. 8.1 UI LandTrendr Pixel Time Series Plotter 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. If you’ve added the eMapR public repository, run this script to access the GUI. 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 formated 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 Collection building is same as that described in the example scripts above 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 Disturbance Mapper The UI LandTrendr Disturbance Mapper will display map layers of disturbance attributes including: year of disturbance detection, magnitude of disturbance, duration of disturbance, and pre-disturbance spectral value. If you’ve added the eMapR public repository, just run this script to access the GUI. 8.2.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 disturbance detection. 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 formated 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 disturbance type you are interested in - this applies only if there are multiple disturbances in a pixel time series. It is a relative qualifier among a series of disturbances for a pixel time series. Optionally filter disturbances 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 disturbances by magnitude. Magnitude filtering is achieved by interpolation of a magnitude threshold from 1 year to 20 years. Define the magntiude threshold considered a disturbance for disturbances that are one year in duration and also 20 years in duration. If you want to apply the same threshold value across all durations, enter the same value in each box. The values should be the minimum spectral delta value that is considered a disturbance. They should be the absolute value and multiplied by 1000 for decimal-based surface reflectance bands and 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). The filter is only applied if the Filter by Magnitude box is checked. Optionally filter by pre-disturbance spectral value. This filter will limit the resulting disturbances by those that have a spectral value prior to the disturbance either greater/less then (depending on index) or equal to the defined value. The units are a of the spectral index selected for segmentation and should be scaled by 1000 (if you are you only want disturbances that had an NBR value of 0.4 prior to disturbance, you would set this parameter to 400). 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 disturbance year of 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. Inspector mode selector. In the center top of the map there is a check box for whether to interact with the map in Inspector mode or not. When inspector mode is activated, map clicks engage the GEE Inspector functionality so that you can explore map layer values for a point (see the Inspector tab). When deactivated, a map click will start mapping disturbances for the region surrounding the clicked point. 8.2.2 Under the hood Collection building is same as that described in the example scripts above 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 xxport 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 magntiude filter parameters "], -["shortcut-functions.html", "9 Shortcut Functions 9.1 Functions", " 9 Shortcut Functions We have created a LandTrendr JavaScript module that contains several shortcut functions to run LandTrendr and deal with the outputs. To access these functions, you must visits this URL to add the eMapR public GEE repository We have developed a LandTrendr JavaScript module that contains several shortcut functions to build LandTrendr input collections, run LandTrendr, and deal with the outputs. The module be accessed from our public GEE repository. To include them in your applications, 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. Once added, it can be found within the Reader permission group of your GEE scripts library. You’ll find the LandTrendr module at Modules/LandTrendr.js. To use the shortcut functions, 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'); 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 buildLTcollection: Builds a collection as input to LandTrendr. It will prepare a collection where the first band is the band to base spectral-temporal segmentation and the subsequent bands will be fitted to segmentation structure of the segmentation band runLT: Run LandTrendr given a set of parameters. A wrapper around buildSRcollection and buildLTcollection functions. getSegmentInfo: Generates an array of information about segments from the breakpoint vertices identified by LandTrendr. getFittedData: Generates an annual band stack for given index provided as ftvList indices to either buildLTcollection or runLT. Flattens the FTV array format to bands per given index. 9.1.1 buildSRcollection buildSRcollection(startYear, endYear, startDay, endDay, aoi) 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 Example: var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); var startYear = 1985; var endYear = 2017; var startDay = '06-20'; var endDay = '09-20'; var aoi = ee.Geometry.Point(-122.8848, 43.7929); Map.centerObject(aoi,10); Map.addLayer(aoi); var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); print(annualSRcollection); 9.1.2 buildLTcollection buildLTcollection(collection, index, ftvList) collection (Image Collection): An annual surface reflectance collection generated by the buildSRcollection function. index (String): The index from the list in the ________ section to be segmented by LandTrendr. ftvList (List of strings): A list of one or more indices from the list in the ________ section to be fitted to the segmentation of the index parameter. Example: var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js'); 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']; Map.centerObject(aoi,10); Map.addLayer(aoi); var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi); var annualLTcollection = ltgee.buildLTcollection(annualSRcollection, index, ftvList); "], -["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. "] -] diff --git a/test/shortcut-functions.html b/test/shortcut-functions.html deleted file mode 100644 index 734790d..0000000 --- a/test/shortcut-functions.html +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

9 Shortcut Functions

-

We have created a LandTrendr JavaScript module that contains several shortcut functions to run LandTrendr and deal with the outputs. To access these functions, you must visits this URL to add the eMapR public GEE repository

-

We have developed a LandTrendr JavaScript module that contains several shortcut functions to build LandTrendr input collections, run LandTrendr, and deal with the outputs. The module be accessed from our public GEE repository. To include them in your applications, 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. Once added, it can be found within the Reader permission group of your GEE scripts library. You’ll find the LandTrendr module at Modules/LandTrendr.js.

-

To use the shortcut functions, 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');
-
-

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
  • -
  • buildLTcollection: Builds a collection as input to LandTrendr. It will prepare a collection where the first band is the band to base spectral-temporal segmentation and the subsequent bands will be fitted to segmentation structure of the segmentation band
  • -
  • runLT: Run LandTrendr given a set of parameters. A wrapper around buildSRcollection and buildLTcollection functions.
  • -
  • getSegmentInfo: Generates an array of information about segments from the breakpoint vertices identified by LandTrendr.
  • -
  • getFittedData: Generates an annual band stack for given index provided as ftvList indices to either buildLTcollection or runLT. Flattens the FTV array format to bands per given index.
  • -
-
-

9.1.1 buildSRcollection

-

buildSRcollection(startYear, endYear, startDay, endDay, aoi)

-
    -
  • 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
  • -
-

Example:

-
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
-
-var startYear = 1985;
-var endYear = 2017;
-var startDay = '06-20';
-var endDay = '09-20';
-var aoi = ee.Geometry.Point(-122.8848, 43.7929);
-
-Map.centerObject(aoi,10);
-Map.addLayer(aoi);
-
-var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi);
-print(annualSRcollection);
-
-
-

9.1.2 buildLTcollection

-

buildLTcollection(collection, index, ftvList)

-
    -
  • collection (Image Collection): An annual surface reflectance collection generated by the buildSRcollection function.
  • -
  • index (String): The index from the list in the ________ section to be segmented by LandTrendr.
  • -
  • ftvList (List of strings): A list of one or more indices from the list in the ________ section to be fitted to the segmentation of the index parameter.
  • -
-

Example:

-
var ltgee = require('users/emaprlab/public:Modules/LandTrendr.js');
-
-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'];
-
-Map.centerObject(aoi,10);
-Map.addLayer(aoi);
-var annualSRcollection = ltgee.buildSRcollection(startYear, endYear, startDay, endDay, aoi);
-var annualLTcollection = ltgee.buildLTcollection(annualSRcollection, index, ftvList);
- -
-
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/style.css b/test/style.css deleted file mode 100644 index d9118ef..0000000 --- a/test/style.css +++ /dev/null @@ -1,4 +0,0 @@ -.book .book-header h1 { - opacity: 1; - text-align: left; -} \ No newline at end of file diff --git a/test/ui-applications.html b/test/ui-applications.html deleted file mode 100644 index 441863e..0000000 --- a/test/ui-applications.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

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, it can be found within the Reader permission group of your GEE scripts library.

-
-

8.1 UI LandTrendr Pixel Time Series Plotter

-

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.

-

-

If you’ve added the eMapR public repository, run this script to access the GUI.

-
-

8.1.1 Steps

-
    -
  1. Click on the script to load it and then click the Run button to initialize the application.
  2. -
  3. Drag the map panel to the top of the page for better viewing.
  4. -
  5. Define a year range over which to generate annual surface reflectance composites.
  6. -
  7. 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!
  8. -
  9. Select spectral indices and bands to view. You can select or or many.
  10. -
  11. 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 formated 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.
  12. -
  13. Define the LandTrendr segmentation parameters. See the LT Parameters section for definitions.
  14. -
  15. 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.
  16. -
-

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

-
    -
  • Collection building is same as that described in the example scripts above
  • -
  • 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 Disturbance Mapper

-

The UI LandTrendr Disturbance Mapper will display map layers of disturbance attributes including: year of disturbance detection, magnitude of disturbance, duration of disturbance, and pre-disturbance spectral value.

-

-

If you’ve added the eMapR public repository, just run this script to access the GUI.

-
-

8.2.1 Steps

-
    -
  1. Click on the script to load it and then click the Run button to initialize the application.
  2. -
  3. Drag the map panel to the top of the page for better viewing.
  4. -
  5. 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.
  6. -
  7. 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!
  8. -
  9. Select spectral index or band to use for disturbance detection.
  10. -
  11. 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 formated 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.
  12. -
  13. 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.
  14. -
  15. Define the disturbance type you are interested in - this applies only if there are multiple disturbances in a pixel time series. It is a relative qualifier among a series of disturbances for a pixel time series.
  16. -
  17. Optionally filter disturbances 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.
  18. -
  19. Optionally filter disturbances by magnitude. Magnitude filtering is achieved by interpolation of a magnitude threshold from 1 year to 20 years. Define the magntiude threshold considered a disturbance for disturbances that are one year in duration and also 20 years in duration. If you want to apply the same threshold value across all durations, enter the same value in each box. The values should be the minimum spectral delta value that is considered a disturbance. They should be the absolute value and multiplied by 1000 for decimal-based surface reflectance bands and 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). The filter is only applied if the Filter by Magnitude box is checked.
  20. -
  21. Optionally filter by pre-disturbance spectral value. This filter will limit the resulting disturbances by those that have a spectral value prior to the disturbance either greater/less then (depending on index) or equal to the defined value. The units are a of the spectral index selected for segmentation and should be scaled by 1000 (if you are you only want disturbances that had an NBR value of 0.4 prior to disturbance, you would set this parameter to 400). The filter is only applied if the Filter by Pre-Dist Value box is checked.
  22. -
  23. Optionally filter by a minimum disturbance patch size, as defined by 8-neighbor connectivity of pixels having the same disturbance year of 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.
  24. -
  25. Define the LandTrendr segmentation parameters. See the LT Parameters section for definitions.
  26. -
-

Inspector mode selector. In the center top of the map there is a check box for whether to interact with the map in Inspector mode or not. When inspector mode is activated, map clicks engage the GEE Inspector functionality so that you can explore map layer values for a point (see the Inspector tab). When deactivated, a map click will start mapping disturbances for the region surrounding the clicked point.

-
-
-

8.2.2 Under the hood

-
    -
  • Collection building is same as that described in the example scripts above
  • -
  • 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 xxport 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 magntiude filter parameters
  • -
- -
-
-
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/validation.html b/test/validation.html deleted file mode 100644 index 207ebca..0000000 --- a/test/validation.html +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

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.

-

- -
-
- -
-
-
- - -
-
- - - - - - - - - - - - diff --git a/test/working-with-outputs.html b/test/working-with-outputs.html deleted file mode 100644 index 00c6ae9..0000000 --- a/test/working-with-outputs.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - LT-GEE Guide - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
- - -
-
- -
-
-

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:

-
    -
  1. Some operations that can be performed on the ‘LandTrendr’ band image array to extract segment information
  2. -
  3. Isolate the greatest delta segment of a time series
  4. -
  5. Filter the greatest delta segment by vegetation loss magnitude and loss duration
  6. -
  7. Apply a minimum mapping unit filter to identified disturbance pixels to reduce spatial noise
  8. -
  9. Convert a fitted (FTV) band from an image array to an image with a band per year in the time series
  10. -
-

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 Shortcut 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.

-
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.

- -
-
-
- -
-
-
- - -
-
- - - - - - - - - - - -