Module Programming Concept in Google Earth Engine Code Editor
Pulakesh Pradhan
PhD Scholar, MPhil, UGC-SRF (Focus Area: Climate and Agriculture || Rural Geography)
Google Earth Engine (GEE) introduced a module system to simplify the organization, reuse, and sharing of code. In this article, I will build a complete example workflow in Code Editor for NDVI and EVI analysis with Landsat 8 Collection 2 data, drawing parallels to Python principles such as modularization, encapsulation, and reusability.
What Are GEE Modules?
Modules in GEE work much like Python modules: they allow you to group related functions and variables into reusable components. Here’s a breakdown of why modules are such a powerful addition:
With these advantages in mind, let’s dive into building a GEE workflow that mimics Pythonic modularity.
Case Study: Landsat 8 Collection 2 Workflow
Imagine you’re building a script to analyze vegetation changes using Landsat 8 Collection 2 data. This pipeline has three main steps:
Instead of putting all this code in a single script, we’ll create three modules, each corresponding to a step in the pipeline. Then, we’ll use a main script to bring it all together.
Step 1: Preprocessing Module
Our preprocessing module will handle two main tasks: masking clouds and scaling reflectance values. In GEE, LANDSAT/LC08/C02/T1_L2 data requires specific cloud masking and reflectance scaling operations, so encapsulating these functions in a module will make it easy to reuse them in future workflows.
Save File to the Path with Name preprocessing:
Path: users/username/repositoryname/filename
Example: users/username/remote-sensing/preprocessing
// Cloud masking for Landsat 8 Collection 2 Level 2 data
var applyCloudMask = function(image) {
if (image.bandNames().contains('QA_PIXEL')) {
var cloudMask = image.select('QA_PIXEL').bitwiseAnd(1 << 3).eq(0)
.and(image.select('QA_PIXEL').bitwiseAnd(1 << 4).eq(0));
return image.updateMask(cloudMask);
}
return image; // Return original image if 'QA_PIXEL' is missing
};
// Reflectance scaling for Landsat 8 Collection 2 Level 2 data
var scaleReflectance = function(image) {
var requiredBands = ee.List(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7']);
var availableBands = image.bandNames();
// Check if required bands are available
var hasAllBands = requiredBands.map(function(band) {
return availableBands.contains(band);
}).reduce(ee.Reducer.min());
if (hasAllBands) {
var opticalBands = image.select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'])
.multiply(0.0000275).add(-0.2);
return image.addBands(opticalBands, null, true);
}
return image; // Return original image if any band is missing
};
// Export functions
exports.applyCloudMask = applyCloudMask;
exports.scaleReflectance = scaleReflectance;
Step 2: Feature Extraction Module
Feature extraction calculates indices that highlight specific land features — here, NDVI and EVI, which help in studying vegetation. In Python, a module like this might rely on libraries like numpy for array calculations. In GEE, we achieve a similar effect using built-in methods.
领英推荐
File: users/username/remote-sensing/featureExtraction
// Calculate NDVI
var calculateNDVI = function(image) {
return image.addBands(image.normalizedDifference(['SR_B5', 'SR_B4']).rename('NDVI')).copyProperties(image, ['system:time_start']);
};
// Calculate EVI
var calculateEVI = function(image) {
var nir = image.select('SR_B5');
var red = image.select('SR_B4');
var blue = image.select('SR_B2');
var evi = nir.subtract(red)
.divide(nir.add(red.multiply(6)).subtract(blue.multiply(7.5)).add(1))
.multiply(2.5)
.rename('EVI');
return image.addBands(evi).copyProperties(image, ['system:time_start']);
};
// Export functions
exports.calculateNDVI = calculateNDVI;
exports.calculateEVI = calculateEVI;
Step 3: Visualization Module
Visualization parameters control how NDVI and EVI are displayed on the map. This module defines these parameters, similar to how you might set matplotlib styles in Python.
File: users/username/remote-sensing/visualization
// Visualization parameters for NDVI and EVI
var ndviVisParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};
var eviVisParams = {min: 0, max: 1, palette: ['white', 'purple', 'green']};
// Display functions
var displayNDVI = function(image) {
Map.addLayer(image.select('NDVI'), ndviVisParams, 'NDVI');
};
var displayEVI = function(image) {
Map.addLayer(image.select('EVI'), eviVisParams, 'EVI');
};
// Export visualization functions
exports.displayNDVI = displayNDVI;
exports.displayEVI = displayEVI;
exports.ndviVisParams = ndviVisParams;
exports.eviVisParams = eviVisParams;
Main Script: Bringing It All Together
Now that we’ve defined each component, we’ll bring them together in a main script. This is like the main.py file in a Python project, where we import all our functions and execute them.
// Import modules
var preprocessing = require('users/username/remote-sensing:preprocessing');
var featureExtraction = require('users/username/remote-sensing:featureExtraction');
var visualization = require('users/username/remote-sensing:visualization');
// Load a sample image collection (e.g., Landsat 8 Collection 2 Level 2)
var landsat = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
.filterDate('2021-01-01', '2021-12-31')
.filterBounds(ee.Geometry.Point([85.89527, 20.46246]));
// Apply preprocessing (e.g., cloud masking and reflectance scaling)
var preprocessed = landsat.map(preprocessing.applyCloudMask)
.map(preprocessing.scaleReflectance);
// Calculate NDVI and EVI
var withNDVI = preprocessed.map(featureExtraction.calculateNDVI);
var withEVI = withNDVI.map(featureExtraction.calculateEVI);
print(withEVI)
// Select a single image for display
var sampleImage = withEVI.median();
// Display results
visualization.displayNDVI(sampleImage);
visualization.displayEVI(sampleImage);
Pythonic Concepts at Play
Conclusion
With GEE modules, Earth Engine developers can organize their code much like Python projects, making it simpler, more readable, and maintainable. As you work with increasingly complex geospatial workflows, consider using GEE modules to structure your code effectively, following Pythonic principles for clean, reusable, and collaborative scripts.
?? More insights & projects: pulakeshpradhan.github.io