Introduction

Welcome to the tutorial for working with the Tropical Moist Forest (TMF) dataset. This dataset is described in the Science advances paper Long-term (1990-2019) monitoring of forest cover changes in the humid tropics. This tutorial provides examples of how to use Earth Engine to visualize data layers available in the TMF dataset and presents some typical visualizations and analyses.
The scripts with the entire code are available at the end of the tutorial.

Audience

This tutorial assumes you are familiar with concepts presented in the Earth Engine Code Editor documentation pages and have worked through the Earth Engine API tutorial.

License and Attribution

The TMF data are provided free of charge and, without restriction of use.

They were produced under the Roadless-For pilot project (Making efficient use of EU climate finance: Using roads as an early performance indicator for REDD+ projects) and the Lot 2 (‘TroFoMo’ - Tropical moist Forest Monitoring) of the ForMonPol Administrative Arrangement (Forest Monitoring for Policies) funded by the Directorate-General for Climate Action of the European Commission (DG-CLIMA).

If you are using the data as a layer in a published map, please include the following attribution text: "Source: EC JRC"

Citations

C. Vancutsem, F. Achard, J.-F. Pekel, G. Vieilledent, S. Carboni, D. Simonetti, J. Gallego, L.E.O.C. Aragão, R. Nasi. Long-term (1990-2019) monitoring of forest cover changes in the humid tropics. Science Advances

Get access to Earth Engine

Access to Earth Engine is free but requires signup. To get access, please fill out our Earth Engine signup form to apply for an Evaluator account. Those granted access will receive an email within a few business days with further instructions.

Once you are familiar with the Code Editor, get started on the tutorial!

Tutorial

The TMF dataset contains 7 data layers that present the tropical moist forest cover and changes in different ways (see further information in the data users guide):

  1. The Transition map that captures transition stages from the initial observation period to the end of 2020 and the status of forest/changes at the end of the observation period by depicting five main land cover types with a few sub types.
  2. The Annual change collection that depicts the TMF extent and the related disturbances (deforestation and degradation), and forest regrowth (post-deforestation) for each year between 1990 and 2020. The timeline allows seeing how the TMF is changing over the past three decades.
  3. The year of deforestation corresponds to the year when the TMF has been deforested for the first time (followed or not by a regrowth).
  4. The year of degradation that corresponds to the year when the TMF has been degraded for the first time (and remained degraded up to 2020).
  5. The duration that corresponds to the number of days between the first and last disruptions detected for all the areas classified as TMF change in the transition map.
  6. The annual number of disruption observations that depicts the total number of disruption observations for each year between 1982 and 2020.
  7. The intensity that documents the total number of disruption observations detected over the disturbed period for all the areas classified as TMF change in the transition map.

And two metadata layers:

  1. The annual number of valid observations that depicts to total number of valid Landsat observations for each year between 1982 and 2020.
  2. The first year of the monitoring period that corresponds to the first year after the initial period (that starts at least four year after the first valid observation).

Four tutorials are presented in the next sections with the following objectives:

In the GEE scripts Section, we provide one script with the entire code for each tutorial, as well as the full code for visualizing and inspecting all the TMF layers (maps, metrics and metadata).

Tutorial 1 - Visualizing and inspecting the Transition map

The following steps show how to display the transition map with the color codes and label for each class (see the full code in the GEE scripts Section). This version of the Transition map corresponds to the one labeled ‘Transition Map – Sub types’ (see data users guide).

Creating a Basic Visualization

The transition map is an ImageCollection (collection of images) that we can load by copying the following statements into the Code Editor:

var TransitionMap = ee.ImageCollection('projects/JRC/TMF/v1_2020/TransitionMap_Subtypes').mosaic();
Map.addLayer(TransitionMap);

The first statement references the Transition Map Collection that we store in a variable. As we have several images in the collection (one for each continent), we mosaic them to display a unique image.

The second statement adds the TMF Transition Map to the Code Editor's interactive map.

Click on the Code Editor's "Run" button, and after a few seconds you should see a map with grey coloring.

Inspecting Values

To explore values of the Transition Map, we will use the Code Editor's inspector tab. First click on the inspector tab, then click on the map to select a location. The inspector tab will display information on each of the layers that are present where you clicked.

In the example above, the value of the layer named TransitionMap is 42. The value corresponds to the transition class 42 with the label “Deforestation started in 2010-2017“. (see the data users guide)

Adding Visualization Parameters

To display a specific color for each transition class in GEE we add a palette with color codes for each discrete value:

var PALETTETransitionSubtypes2020 = [rgb(0,80,0), rgb(10,100,10), rgb(10,90,60), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(30,120,0), rgb(80,150,0), rgb(100,160,40), rgb(120,170,40), rgb(100,160,40), rgb(120,170,40), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(185,200,60), rgb(200,230,60), rgb(210,250,60), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(255,240,160), rgb(255,150,8), rgb(255,90,10), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(250,60,10), rgb(170,80,10), rgb(140,100,30), rgb(140,120,60), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(40,100,50), rgb(80,150,0), rgb(200,230,60), rgb(210,250,60), rgb(255,230,110), rgb(255,60,10), rgb(155,105,70), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,50,150), rgb(0,150,200), rgb(0,160,150), rgb(0,210,210), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(51,99,51), rgb(98,161,80), rgb(188,209,105), rgb(255,228,148), rgb(250,180,150), rgb(204,163,163), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(255,255,255), rgb(237,255,215), rgb(224,250,157), rgb(214,250,188)];

And a function for converting rgb values into HEX code required for the palette:

function rgb(r,g,b){
    var bin = r << 16 | g << 8 | b;
    return (function(h){
        return new Array(7-h.length).join("0")+h;
    })(bin.toString(16).toUpperCase());
}

To add the color and description of the class, we add the following visualization parameters: the min and max values and a palette with the colors for each class.

Map.addLayer(TransitionMap.updateMask(TransitionMap),{
    'min':10,
    'max': 94,
    'palette': PALETTETransitionSubtypes2020
}, "JRC - Transition Map – Sub types - v1 2020", true);

The full code contains the label of each class.

In the next section, you explore how to recode the transition map for producing a simplified version.

Tutorial 2 - Recoding the Transition map

The following steps show how to recode the transition map for producing a simplified version of the transition classes (see the full code in the GEE scripts Section).

First, we store the Transition Map Collection in a variable named TransitionMap:

var TransitionMap = ee.ImageCollection('projects/JRC/TMF/v1_2020/TransitionMap_Subtypes').mosaic();

The second step consists of recoding the Transition Map to have the same classes as the simplified version of the transition map labeled ‘Transition Map – Main Classes’ (see data users guide) as follows:

value 10. Undisturbed Tropical Moist Forest (TMF)
value 20. Degraded TMF
value 30. TMF regrowth
value 41. Deforested land - Forest converted to tree plantations
value 42. Deforested Land - Forest converted to water
value 43. Deforested Land - Forest converted to other land cover
value 50. Recent deforestation or degradation (2018-2020)
value 60. Permanent or Seasonal Water
value 70. Other land cover (including afforestation)

For recoding we use the image.where() operator as follows:

var TransitionMap_Main = TransitionMap.where((TransitionMap.gte(10)).and(TransitionMap.lte(12)), 10);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(21)).and(TransitionMap.lte(26)), 20);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(61)).and(TransitionMap.lte(62)), 20);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(31)).and(TransitionMap.lte(33)), 30);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(63)).and(TransitionMap.lte(64)), 30);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(81)).and(TransitionMap.lte(86)), 41);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(73)).and(TransitionMap.lte(74)), 42);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(41)).and(TransitionMap.lte(42)), 43);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(65)).and(TransitionMap.lte(66)), 43);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(51)).and(TransitionMap.lte(54)), 50);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.eq(67)), 50);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(71)).and(TransitionMap.lte(72)), 60);
TransitionMap_Main = TransitionMap_Main.where((TransitionMap.gte(91)), 70);

To display a specific color for each transition class in GEE we add a palette with color codes for each discrete value:

var PALETTEMainTransition2020 = [rgb(0,80,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(100,135,35), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(210,250,60), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(255,200,148), rgb(0,200,150), rgb(255,230,100), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(250,140,10), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,70,160), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(0,0,0), rgb(255,255,255)];

And a function for converting rgb values into HEX code required for the palette:

function rgb(r,g,b){
    var bin = r << 16 | g << 8 | b;
    return (function(h){
        return new Array(7-h.length).join("0")+h;
    })(bin.toString(16).toUpperCase());
}

To add the color and description of the class, we add the following visualization parameters: the min and max values and the palette.

Map.addLayer(TransitionMap_Main.updateMask(TransitionMap_Main),{
    'min':10,
    'max': 70,
    'palette': PALETTEMainTransition2020
}, "JRC - Transition Map – Main Classes - v1 2020", true);

In the next section, you explore how to visualize and inspect the Annual Change collection.

Tutorial 3 - Visualizing and inspecting the Annual Change collection

The following steps show how to display the Annual Change collection with the color codes and label for each class (see the full code in the GEE scripts Section).

Inspecting the Annual Change collection

The Annual Change dataset is an ImageCollection (collection of images) that we can load by copying the following statements into the Code Editor:

var AnnualChanges = ee.ImageCollection('projects/JRC/TMF/v1_2020/AnnualChanges').mosaic();

To explore values of the Annual Change collection for the 31 years (1990-2020), we use the Code Editor's inspector tab. First click on the inspector tab, then click on the map to select a location. The inspector tab will display information on each of the year where you clicked.

In the example above, the values are 1 for the period 1990-1994, 2 for the period 1995-2012, and 3 for the period 2013-2020, respectively. The value corresponds to the annual change classes with the label “Undisturbed TMF”, “Degraded forest”, and “Deforested land”. Consequently, this pixel corresponds to a tropical moist forest that has been degraded for the first time in 1995 and remained degraded until 2012. In 2013 the degraded forest has been deforested for the first time and remained deforested until December 2020.

Visualizing one specific year within the Annual Change collection

First, it is necessary to select the year of interest with the following code:

var AnnualChangesYear = AnnualChanges.select('Dec2010');

To display a specific color for each class of the annual change dataset we add a palette with color codes and label for each discrete value:

var PALETTEAnnualChanges = [
    rgb(0,90,0), // val 1. Undisturbed Tropical moist forest (TMF)
    rgb(100,155,35), // val 2. Degraded TMF
    rgb(255,135,15), // val 3. Deforested land
    rgb(210,250,60), // val 4. Forest regrowth
    rgb(0,140,190), // val 5. Permanent or seasonal Water
    rgb(255,255,255), // val 6. Other land cover
];

And we display the year selected with the palette:

Map.addLayer(AnnualChangesYear.updateMask(AnnualChangesYear),{
    'min': 1,
    'max': 6,
    'palette': PALETTEAnnualChanges
}, "JRC - Annual Changes - one year – v1 2020", false);

In the next section, you explore how to analyze the changes between two periods from the Annual Change collection.

Tutorial 4 - Analyzing the changes between two periods

The following steps show how to compute the changes between two periods from the Annual Change collection (see the full code in the GEE scripts Section).

Tutorial 3 shows the steps for selecting a specific year within the Annual Change collection.

Here we select two specific years as follows:

var AnnualChangesYear1=AnnualChanges.select('Dec2005');
var AnnualChangesYear2=AnnualChanges.select('Dec2015');

From these two layers we map four classes of changes:

From Undisturbed TMF to Degraded forest
From TMF to Deforested land
From TMF to Deforested to Forest regrowth
From deforested land to Forest regrowth

We use the image.where() operator for recoding as follows:

From Undisturbed TMF to degraded TMF:

var ChangesBetweenTwoPeriods = ((AnnualChangesYear1.eq(1)).and(AnnualChangesYear2.eq(2)));

From Undisturbed/Degraded TMF to deforested land (including water):

ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(1)).and(AnnualChangesYear2.eq(3)), 2);
ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(2)).and(AnnualChangesYear2.eq(3)), 2);
ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(1)).and(AnnualChangesYear2.eq(5)), 2);
ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(2)).and(AnnualChangesYear2.eq(5)), 2);

From Forest (Undisturbed/Degraded TMF) to deforested land to Forest Regrowth:

ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(1)).and(AnnualChangesYear2.eq(4)), 3);
ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(2)).and(AnnualChangesYear2.eq(4)), 3);

From Deforested land to Forest Regrowth:

ChangesBetweenTwoPeriods = ChangesBetweenTwoPeriods.where((AnnualChangesYear1.eq(3)).and(AnnualChangesYear2.eq(4)), 4);

To display a specific color for each class of the changes we add a palette with color codes and label for each discrete value:

var PALETTECHANGES = [
    rgb(100,135,35), // val 1. From Undisturbed TMF to Degraded forest
    rgb(255,170,35), // val 2. From TMF to Deforested land
    rgb(190,210,60), // val 3. From TMF to Deforested to Forest regrowth
    rgb(210,250,60), // val 4. From deforested land to Forest regrowth
];

And we display the year selected with the palette:

Map.addLayer(ChangesBetweenTwoPeriods.updateMask(ChangesBetweenTwoPeriods),{
    'min': 1,
    'max': 4,
    'palette': PALETTECHANGES
}, "JRC - Changes Between Two Periods – v1 2020", true);

GEE scripts for starting exploring the TMF dataset

The following script displays the transition map (with subtypes) with the color codes and label for each class: https://code.earthengine.google.com/78121ca739880c4330204619051bfe57

The following script allows recoding the transition map in a simplified version with the main transition classes (without subtypes): https://code.earthengine.google.com/7574a2d93d74d21697ea0ac43853e937

The following script displays the annual change collection with the color codes and label for each class: https://code.earthengine.google.com/5c3f556be62f02722e01ee335683ed28

The following script maps the changes between two periods: https://code.earthengine.google.com/bbdb80e73a5471e857fdda536038806d

The following script allows visualizing and inspecting all the TMF layers (maps, metrics and metadata): https://code.earthengine.google.com/cb998e2b1e43fc7746515cca5295575b