# GEE Example Problem

GEE

## is a Platform as a Service (PaaS)

• offers a web-based Integrated Development Environment (IDE)
• hosts open data sets

# This presentation was developed for students I mentor directly in the

## Global Sustainability Science Bachelors

https://www.uu.nl/bachelors/en/global-sustainability-science

I want to measure change over time in two different locations to learn if a policy or environmental practice was successful.

# Third, are there data available to do that?

0

## Common Study design example

• Define a problem/Research question
•  identify dataset
• Location 1 (and Location 2?)
• Time 1 and Time 2
• Measure change over time
• Compare change in the two locations
• Your findings and discussion: Why the difference?

## do many data choices...

Preprocessed data or straight from the satellite?

0

• Is there a change in net primary production over time in Samoa?
• Dataset: Terra Net Primary Production Yearly Global 500m

•

Processed data example

## MOD17A3H Version 6

```Net Primary Production (NPP) at 500 meter (m) pixel resolution.

Annual NPP is derived from the sum of all 8-day Net Photosynthesis (PSN) products (MOD17A2H) from the given year.

The PSN value is the difference of the Gross Primary Productivity (GPP) and the Maintenance Respiration (MR).```
``````var dataset = ee.ImageCollection('MODIS/006/MOD17A3H')
.filter(ee.Filter.date('2014-01-01', '2015-05-01'));
var npp = dataset.select('Npp');
var nppVis = {
min: 0.0,
max: 19000.0,
palette: ['bbe029', '0a9501', '074b03'],
};
Map.setCenter(6.746, 46.529, 2);
``````

## Print info about the file

0

Location 1

``````var dataset = ee.ImageCollection('MODIS/006/MOD17A3H')
.filter(ee.Filter.date('2014-01-01', '2015-05-01'))
;
var npp = dataset.select('Npp');

print('Net Primary Product: ', npp);

var nppVis = {
min: 0.0,
max: 19000.0,
palette: ['bbe029', '0a9501', '074b03'],
};
//center on samoa
Map.setCenter(-172.34379875488645, -13.780116632620732, 9);
``````

## change color pallet

change dates

0

Location 1

``````var dataset = ee.ImageCollection('MODIS/006/MOD17A3H')
.filter(ee.Filter.date('2013-01-01', '2014-05-01'))
;
var npp = dataset.select('Npp');

print('Net Primary Product: ', npp);

var nppVis = {
min: 0.0,
max: 19000.0,
palette: ['red', 'yellow', 'green'],
};
//center on samoa
Map.setCenter(-172.34379875488645, -13.780116632620732, 12);
``````
```change color pallet again
Compare two different years of data - two layers```
0

Location 1

``````var time2000 = ee.ImageCollection('MODIS/006/MOD17A3H')
.filter(ee.Filter.date('2000-01-01', '2001-05-01'))

;
var time2013 = ee.ImageCollection('MODIS/006/MOD17A3H')
.filter(ee.Filter.date('2013-01-01', '2014-05-01'))

;
var npp2000 = time2000.select('Npp');
var npp2013 = time2013.select('Npp');

var nppVis = {
min: 0.0,
max: 19000.0,
palette: ['red', 'green', 'yellow'],
};
//center on samoa
Map.setCenter(-172.34379875488645, -13.780116632620732, 12);
//data for the year 2000
//data for the year 2013
`instead of NPP look at NDVI`

What else should we change? HINT: ndviVis...

0

Location 1

``````var time2000 = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI')
.filter(ee.Filter.date('2000-01-01', '2000-05-01'))
.filterBounds(ee.Geometry.Point(-172.34379875488645, -13.780116632620732))
;
var time2013 = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI')
.filter(ee.Filter.date('2013-01-01', '2013-05-01'))
.filterBounds(ee.Geometry.Point(-172.34379875488645, -13.780116632620732))
;
var ndvi2000 = time2000.select('NDVI');
var ndvi2013 = time2013.select('NDVI');

var ndviVis = {
min: 0.0,
max: 19000.0,
palette: [ 'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
'66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
'012E01', '011D01', '011301' ],
};
//center on samoa
Map.setCenter(-172.42, -13.6479, 8);
//data for the year 2000
//data for the year 2013
``````

# Yet another way to calculate NDVI

follow this tutorial starting here using LandSat 8 2013- now

what is printed? How many images are returned?

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var spatialFiltered = l8.filterBounds(geometry);
print('spatialFiltered', spatialFiltered);

var temporalFiltered = spatialFiltered.filterDate('2015-01-01', '2015-12-31');
print('temporalFiltered', temporalFiltered);

// This will sort from least to most cloudy.
var sorted = temporalFiltered.sort('CLOUD_COVER');

// Get the first (least cloudy) image.
var scene = sorted.first();

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};

``````

# average pixel value

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

// Get the least cloudy image in 2015.
var image = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

// Get the median over time, in each band, in each pixel.
var median = l8.filterDate('2016-01-01', '2016-12-31').median();

//which bands to be red green blue

var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};

// Display the median composite.

# calculate NDVI

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry =
/* color: #cfced6 */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

// Get the least cloudy image in 2015.
var image = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

// Compute the Normalized Difference Vegetation Index (NDVI).
var nir = image.select('B5');
var red = image.select('B4');

var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Display the result.
Map.centerObject(image, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

``````

# calculate NDVI two different dates

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry =
/* color: #cfced6 */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry =
/* color: #cfced6 */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

// Get the least cloudy image in 2015.
var image2015 = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

// Get the least cloudy image in 2015.
var image2019 = ee.Image(
l8.filterBounds(geometry)
.filterDate('2019-01-01', '2019-12-31')
.sort('CLOUD_COVER')
.first()
);

// Compute the Normalized Difference Vegetation Index (NDVI) for 2015 image.
var nir15 = image2015.select('B5');
var red15 = image2015.select('B4');
//Are above and below different?
var ndvi = image2015.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Compute the Normalized Difference Vegetation Index (NDVI) for 2019 image.
var nir19 = image2019.select('B5');
var red19 = image2019.select('B4');

// Display the result.
Map.centerObject(image2015, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

``````

# print a chart of the NDVI

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry = geometry2;

// Get the least cloudy image in 2015.
var image = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

// Compute the Normalized Difference Vegetation Index (NDVI).
var nir = image.select('B5');
var red = image.select('B4');

var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Map a function over the Landsat 8 TOA collection to add an NDVI band.
var withNDVI = l8.map(function(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
});

var roi = ee.Geometry.Point([-172.24253032635173,-13.773977860672609]);

// Create a chart to show NDVI.
var chart = ui.Chart.image.series({
imageCollection: withNDVI.select('NDVI'),
region: roi,
reducer: ee.Reducer.first(),
scale: 30
}).setOptions({title: 'NDVI over time'});

// Display the chart in the console.
print(chart);

// Display the result.
Map.centerObject(image, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

``````

# print a chart of the NDVI and compare clean version

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry = geometry2;

// Get the least cloudy image in 2015.
var image = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

// Compute the Normalized Difference Vegetation Index (NDVI).
var nir = image.select('B5');
var red = image.select('B4');

var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Map a function over the Landsat 8 TOA collection to add an NDVI band.
var withNDVI = l8.map(function(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
});

var roi = ee.Geometry.Point([-172.24253032635173,-13.773977860672609]);

//Here we filter the cloudless image - you can still see seasonality

var cloudlessNDVI = l8.map(function(image) {
// Get a cloud score in [0, 100].
var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');

// Create a mask of cloudy pixels from an arbitrary threshold.

// Compute NDVI.
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Return the masked image with an NDVI band.
});

print(ui.Chart.image.series({
imageCollection: cloudlessNDVI.select('NDVI'),
region: roi,
reducer: ee.Reducer.first(),
scale: 30

//end

// Create a chart - this is all of the images over time - you can see cloud season.
var chart = ui.Chart.image.series({
imageCollection: withNDVI.select('NDVI'),
region: roi,
reducer: ee.Reducer.first(),
scale: 30
}).setOptions({title: 'NDVI over time'});

// Display the chart in the console.
print(chart);

// Display the result.
Map.centerObject(image, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

``````

# export an image

0

``````
var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry = geometry2;

// Get the least cloudy image in 2015.
var image = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

// Compute the Normalized Difference Vegetation Index (NDVI).
var nir = image.select('B5');
var red = image.select('B4');

var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Map a function over the Landsat 8 TOA collection to add an NDVI band.
var withNDVI = l8.map(function(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
});

var roi = ee.Geometry.Point([-172.24253032635173,-13.773977860672609]);

//Here we filter the cloudless image - you can still see seasonality

var cloudlessNDVI = l8.map(function(image) {
// Get a cloud score in [0, 100].
var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');

// Create a mask of cloudy pixels from an arbitrary threshold.

// Compute NDVI.
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Return the masked image with an NDVI band.
});

print(ui.Chart.image.series({
imageCollection: cloudlessNDVI.select('NDVI'),
region: roi,
reducer: ee.Reducer.first(),
scale: 30

//end

// Create a chart - this is all of the images over time - you can see cloud season.
var chart = ui.Chart.image.series({
imageCollection: withNDVI.select('NDVI'),
region: roi,
reducer: ee.Reducer.first(),
scale: 30
}).setOptions({title: 'NDVI over time'});

// Display the chart in the console.
print(chart);

// Display the result.
Map.centerObject(image, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

//export

// Create a task that you can launch from the Tasks tab.
Export.image.toDrive({
image: ndvi,
description: 'ndvi_composite',
region: geometry2,
scale: 30
});

``````

# Select only a country

## calculate in an area

``````var l8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');

var geometry =
/* color: #cfced6 */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

var geometry =
/* color: #cfced6 */
/* shown: false */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

// Get the least cloudy image in 2015.
var image2015 = ee.Image(
l8.filterBounds(geometry)
.filterDate('2015-01-01', '2015-12-31')
.sort('CLOUD_COVER')
.first()
);

// Get the least cloudy image in 2015.
var image2019 = ee.Image(
l8.filterBounds(geometry)
.filterDate('2019-01-01', '2019-12-31')
.sort('CLOUD_COVER')
.first()
);

// Compute the Normalized Difference Vegetation Index (NDVI) for 2015 image.
var nir15 = image2015.select('B5');
var red15 = image2015.select('B4');
//Are above and below different?
var ndvi = image2015.normalizedDifference(['B5', 'B4']).rename('NDVI');

// Compute the Normalized Difference Vegetation Index (NDVI) for 2019 image.
var nir19 = image2019.select('B5');
var red19 = image2019.select('B4');

//Are above and below different?
var ndvi2019 = image2019.normalizedDifference(['B5', 'B4']).rename('NDVI');

//start

//calculate difference between NDVI in 2015 and 2019

// Load a 5-year Landsat 7 composite 2008-2012.

// Compute multi-band difference between the 2008-2012 composite and the
var diff = image2015.subtract(image2019);
{bands: ['B5', 'B4', 'B2'], min: -32, max: 32}, 'difference');

// Compute the squared difference in each band.
var squaredDifference = diff.pow(2);
{bands: ['B4', 'B3', 'B2'], max: 1000}, 'squared diff.');

//end

// Display the result.
Map.centerObject(image2015, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};

//center on samoa
Map.setCenter(-172.42, -13.6479, 8);

``````

note - my code might work - but it is not perfect!

# clip to a country/area

``````var dataset = ee.ImageCollection('MODIS/006/MOD17A3H')
.filter(ee.Filter.date('2014-01-01', '2015-05-01'))
.filterBounds(geometry);``````
``````// Define a mask to clip the data by.
.filter(ee.Filter.eq('country_na', 'China'));

``````// Create mask for only France

//.filter(ee.Filter.eq('country_na', 'France'));

// Mask to filter only Paris

var collection = ee.ImageCollection('COPERNICUS/S5P/OFFL/L3_NO2')
.select('tropospheric_NO2_column_number_density')
.filterDate('2019-04-17', '2019-04-26')

//create the visualization pallet to "see" No2 pollution

var band_viz = {
min: 0,
max: 0.0002,
palette: ['black', 'blue', 'purple', 'cyan', 'green', 'yellow', 'red']
};

// Add variable for mean value over 12 days
// only select clipped variable for France

var mean = collection.mean();

//add these to the map and center on France

Map.setCenter(2.3489, 48.8566, 5);

// create asset - to export the mean value as a geotiff

var collectionGIS = clippedmean.reduce(ee.Reducer.mean());

Export.image.toAsset({
image: clippedmean,
});``````

# Animation - visualization change over time

``````/**
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/

// Fetch a MODIS NDVI collection and select NDVI.
var col = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI');

//test start

// Define a mask to clip the NDVI data by.
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

//test end

// Define the regional bounds of animation frames.
var region = ee.Geometry.Polygon(
[[[-172.86219970703124, -13.415580758887149],
[-172.86219970703124, -14.135821390629378],
[-171.29664794921874, -14.135821390629378],
[-171.29664794921874, -13.415580758887149]]], null, false);

// Add day-of-year (DOY) property to each image.
col = col.map(function(img) {
var doy = ee.Date(img.get('system:time_start')).getRelative('day', 'year');
return img.set('doy', doy);
});

// Get a collection of distinct images by 'doy'.
var distinctDOY = col.filterDate('2013-01-01', '2014-01-01');

// Define a filter that identifies which images from the complete
// collection match the DOY from the distinct DOY collection.
var filter = ee.Filter.equals({leftField: 'doy', rightField: 'doy'});

// Define a join.
var join = ee.Join.saveAll('doy_matches');

// Apply the join and convert the resulting FeatureCollection to an
// ImageCollection.
var joinCol = ee.ImageCollection(join.apply(distinctDOY, col, filter));

// Apply median reduction among matching DOY collections.
var comp = joinCol.map(function(img) {
var doyCol = ee.ImageCollection.fromImages(
img.get('doy_matches')
);
return doyCol.reduce(ee.Reducer.median());
});

// Define RGB visualization parameters.
var visParams = {
min: 0.0,
max: 9000.0,
palette: [
'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
'66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
'012E01', '011D01', '011301'
],
};

// Create RGB visualization images for use as animation frames.
var rgbVis = comp.map(function(img) {
});

// Define GIF visualization arguments.
var gifParams = {
'region': region,
'dimensions': 600,
'crs': 'EPSG:3857',
'framesPerSecond': 10,
'format': 'gif'
};

// Print the GIF URL to the console.
print(rgbVis.getVideoThumbURL(gifParams));

// Render the GIF animation in the console.
print(ui.Thumbnail(rgbVis, gifParams));``````

lets look at the code

what do you think it does?

``````/**
*
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
*/

// Fetch a MODIS NDVI collection and select NDVI.
var col = ee.ImageCollection('MODIS/006/MOD13A2').select('NDVI');

// Define a mask to clip the NDVI data by.
.filter(ee.Filter.eq('wld_rgn', 'Africa'));

// Define the regional bounds of animation frames.
var region = ee.Geometry.Polygon(
[[[-18.698368046353494, 38.1446395611524],
[-18.698368046353494, -36.16300755581617],
[52.229366328646506, -36.16300755581617],
[52.229366328646506, 38.1446395611524]]],
null, false
);

// Add day-of-year (DOY) property to each image.
col = col.map(function(img) {
var doy = ee.Date(img.get('system:time_start')).getRelative('day', 'year');
return img.set('doy', doy);
});

// Get a collection of distinct images by 'doy'.
var distinctDOY = col.filterDate('2013-01-01', '2014-01-01');

// Define a filter that identifies which images from the complete
// collection match the DOY from the distinct DOY collection.
var filter = ee.Filter.equals({leftField: 'doy', rightField: 'doy'});

// Define a join.
var join = ee.Join.saveAll('doy_matches');

// Apply the join and convert the resulting FeatureCollection to an
// ImageCollection.
var joinCol = ee.ImageCollection(join.apply(distinctDOY, col, filter));

// Apply median reduction among matching DOY collections.
var comp = joinCol.map(function(img) {
var doyCol = ee.ImageCollection.fromImages(
img.get('doy_matches')
);
return doyCol.reduce(ee.Reducer.median());
});

// Define RGB visualization parameters.
var visParams = {
min: 0.0,
max: 9000.0,
palette: [
'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
'66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
'012E01', '011D01', '011301'
],
};

// Create RGB visualization images for use as animation frames.
var rgbVis = comp.map(function(img) {
});

// Define GIF visualization arguments.
var gifParams = {
'region': region,
'dimensions': 600,
'crs': 'EPSG:3857',
'framesPerSecond': 10,
'format': 'gif'
};

// Print the GIF URL to the console.
print(rgbVis.getVideoThumbURL(gifParams));

// Render the GIF animation in the console.
print(ui.Thumbnail(rgbVis, gifParams));``````

By Britta Ricker

• 141