Geographic Information Systems Asked on March 8, 2021
I have written a script which calculates the mean NDVI, NDWI, and NDDI (Normalized Difference Drought Index) values for a given county in a specified time period. These values are then outputted to a graph. So far I have been testing the script using a shapefile of just one county.
My problem is that I need the script to run over all 78 counties in the country (South Sudan). I have loaded the counties shapefile (all 78) as an asset named ‘aoi’ and created a list based on the county names:
var countyList = aoi.aggregate_array('admin2RefN')
I’m new to GEE and JavaScript and don’t know how to create a loop which goes through each county in the shapefile and outputs a separate graph for each county.
If someone could explain how this can be done it would be very helpful.
Here is my full code:
var countyList = aoi.aggregate_array('admin2RefN')
//------------------------------- SPECIFY DATE RANGE --------------------------//
// Specify the date range required
var startDate = ee.Date('2020-01-01');
var endDate = ee.Date('2021-01-01');
print('Observations begin on: ', startDate.format('YYYY-MM-dd'),
'and end on: ', endDate.format('YYYY-MM-dd'));
// Calculate the number of months to process
var nMonths = ee.Number(endDate.difference(startDate,'month')).round();
print ('Number of months to process: ', nMonths)
//------------------------------- REQUIRED FUNCTIONS --------------------------//
// Function to create NDVI & NDWI bands
var addIndices = function(image) {
var ndvi = image.normalizedDifference(['B2', 'B1']).rename('NDVI')
var ndwi = image.normalizedDifference(['B2', 'B7']).rename('NDWI')
return image.addBands([ndvi,ndwi]);
};
// Function to create NDDI band
var addNDDI = function(image) {
var nddi = image.normalizedDifference(['NDVI', 'NDWI']).rename('NDDI')
return image.addBands(nddi);
};
// Helper function to extract the QA bits
function getQABits(image, start, end, newName) {
// Compute the bits we need to extract.
var pattern = 0;
for (var i = start; i <= end; i++) {
pattern += Math.pow(2, i);
}
// Return a single band image of the extracted QA bits, giving the band
// a new name.
return image.select([0], [newName])
.bitwiseAnd(pattern)
.rightShift(start);
}
// Function to mask out cloudy pixels
function maskQuality(image) {
// Select the QA band.
var QA = image.select('StateQA');
// Get the internal_cloud_algorithm_flag bit.
var internalQuality = getQABits(QA,8, 13, 'internal_quality_flag');
// Return an image masking out cloudy areas.
return image.updateMask(internalQuality.eq(0));
}
//---------------------- LOAD MODIS IMAGE COLLECTION -------------------------//
var modis = ee.ImageCollection('MODIS/006/MOD09A1')
.filter(ee.Filter.date(startDate, endDate))
.select(['sur_refl_b01','sur_refl_b02','sur_refl_b03',
'sur_refl_b04','sur_refl_b05','sur_refl_b06',
'sur_refl_b07','StateQA'],
//rename band names
['B1','B2','B3','B4','B5','B6','B7','StateQA'])
.map(maskQuality)
.map(addIndices)
.map(addNDDI)
.map(function(image) { return image.clip(aoi); });
// Create composite image from MODIS collection
var modisCom = modis.median();
print('Basic band info: ', modisCom);
//---------------------------------- GRAPHS ---------------------------------//
var byMonth = ee.ImageCollection(
// map over each month
ee.List.sequence(0,nMonths).map(function (n) {
// calculate the offset from startDate
var ini = startDate.advance(n,'month');
// advance just one month
var end = ini.advance(1,'month');
// filter and reduce
return modis.filterDate(ini,end)
.select('NDDI','NDVI','NDWI').mean()
.set('system:time_start', ini);
}));
// Plot full NDDI, NDVI, NDWI time series
print(
ui.Chart.image.series({
imageCollection: byMonth,
region: aoi,
reducer: ee.Reducer.mean(),
scale: 500,
})
.setOptions({
title: 'Average NDDI, NDVI, NDWI by month',
hAxis: {title: 'Time Period'},
vAxis: {title: 'Range'},
pointSize: 0,
lineSize: 3,
colors: ['ee5859', '84bc7d', '5499c5'],
curveType: 'function'
}));
You need client-side iteration to do this. Call aggregate_array()
with a property that uniquely identify each element in your collection. Then evaluate()
the result, to turn it into a client-side array. I normally use system:index
, but here I used the name of the county, ADM2_NAME
, to easily get the county name as a client-side string for use in the chart title. You can then iterate the client-side array, names
, pick up each county from the collection based on name, and chart it. Wrap your charting code into a function that takes the county to chart as an argument.
https://code.earthengine.google.com/2053dfef17efa08df0f5594a36da496f
countyList.aggregate_array('ADM2_NAME').evaluate(function (names) {
names.map(function (name) {
var county = countyList
.filter(ee.Filter.equals('ADM2_NAME', name))
.first()
chartAoi(county.geometry(), name)
})
})
function chartAoi(aoi, name) {
// I pass the client-side `name` string, to use in the chart title
// Your charting code goes here
}
Answered by Daniel Wiell on March 8, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP