In GEE I'm using Awesome GEE's ESRI LULC Dataset to map out and mask water areas for the years 2017 to 2022. Due to it being an Image Collection of multiple dynamic years, I had to filter, mosaic, and remap the layers and create multiple variables of the same Image Collection to have annual layers, e.g. 'ESRI LULC 2017', '...2018', etc.
/* Geometry is unimportant for this example, just draw a box somewhere with land inside */
var ESRLULCdictPalette = {
"names": [
"Water","Trees","Flooded Vegetation","Crops","Built Area","Bare Ground","Snow/Ice",
"Clouds","Rangeland"
],
"colors": [
"#1A5BAB","#358221","#87D19E","#FFDB5C","#ED022A","#EDE9E4","#F2FAFF","#C8C8C8","#C6AD8D"
]};
function Crop(image) {
return image.clip(geometry);
}
// ESRI LULC 2017-22 - Water is 1
var ESRI_LULC17 = ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS")
.filterDate('2017-01-01','2017-12-31');
var LULC17_mosaic = ESRI_LULC17.mosaic()
.remap([1,2,4,5,7,8,9,10,11],[1,2,3,4,5,6,7,8,9])
.clip(geometry);
var ESRI_LULC18 =ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS")
.filterDate('2018-01-01','2018-12-31');
var LULC18_mosaic = ESRI_LULC18.mosaic()
.remap([1,2,4,5,7,8,9,10,11],[1,2,3,4,5,6,7,8,9])
.clip(geometry);
var ESRI_LULC19 = ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS")
.filterDate('2019-01-01','2019-12-31');
var LULC19_mosaic = ESRI_LULC19.mosaic()
.remap([1,2,4,5,7,8,9,10,11],[1,2,3,4,5,6,7,8,9])
.clip(geometry);
var ESRI_LULC20 = ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS")
.filterDate('2020-01-01','2020-12-31');
var LULC20_mosaic = ESRI_LULC20.mosaic()
.remap([1,2,4,5,7,8,9,10,11],[1,2,3,4,5,6,7,8,9])
.clip(geometry);
var ESRI_LULC21 = ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS")
.filterDate('2021-01-01','2021-12-31');
var LULC21_mosaic = ESRI_LULC21.mosaic()
.remap([1,2,4,5,7,8,9,10,11],[1,2,3,4,5,6,7,8,9])
.clip(geometry);
var ESRI_LULC22 = ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS")
.filterDate('2022-01-01','2022-12-31');
var LULC22_mosaic = ESRI_LULC22.mosaic()
.remap([1,2,4,5,7,8,9,10,11],[1,2,3,4,5,6,7,8,9])
.clip(geometry);
var ESRILULCMaskWater17 = LULC17_mosaic.eq(1); // Only Water
var ESRILULCMaskWater17 = LULC17_mosaic.updateMask(ESRILULCMaskWater17).clip(geometry);
var WCMask = function(image) {
return image.updateMask(ESRILULCMaskWater17);
};
var ESRILULCMaskWater18 = LULC18_mosaic.eq(1); // Only Water
var ESRILULCMaskWater18 = LULC18_mosaic.updateMask(ESRILULCMaskWater18).clip(geometry);
var LULCMask = function(image) {
return image.updateMask(ESRILULCMaskWater18);
};
var ESRILULCMaskWater19 = LULC19_mosaic.eq(1); // Only Water
var ESRILULCMaskWater19 = LULC19_mosaic.updateMask(ESRILULCMaskWater19).clip(geometry);
var LULCMask = function(image) {
return image.updateMask(ESRILULCMaskWater19);
};
var ESRILULCMaskWater20 = LULC20_mosaic.eq(1); // Only Water
var ESRILULCMaskWater20 = LULC20_mosaic.updateMask(ESRILULCMaskWater20).clip(geometry);
var LULCMask = function(image) {
return image.updateMask(ESRILULCMaskWater20);
};
var ESRILULCMaskWater21 = LULC21_mosaic.eq(1); // Only Water
var ESRILULCMaskWater21 = LULC21_mosaic.updateMask(ESRILULCMaskWater21).clip(geometry);
var LULCMask = function(image) {
return image.updateMask(ESRILULCMaskWater21);
};
var ESRILULCMaskWater22 = LULC22_mosaic.eq(1); // Only Water
var ESRILULCMaskWater22 = LULC22_mosaic.updateMask(ESRILULCMaskWater22).clip(geometry);
var LULCMask = function(image) {
return image.updateMask(ESRILULCMaskWater22);
};
// Landcover with no masking
Map.addLayer(LULC17_mosaic, {min:1, max:9, palette:ESRLULCdictPalette['colors']}, 'ESRI LULC 2017', false);
Map.addLayer(LULC18_mosaic, {min:1, max:9, palette:ESRLULCdictPalette['colors']}, 'ESRI LULC 2018', false);
Map.addLayer(LULC19_mosaic, {min:1, max:9, palette:ESRLULCdictPalette['colors']}, 'ESRI LULC 2019', false);
Map.addLayer(LULC20_mosaic, {min:1, max:9, palette:ESRLULCdictPalette['colors']}, 'ESRI LULC 2020', false);
Map.addLayer(LULC21_mosaic, {min:1, max:9, palette:ESRLULCdictPalette['colors']}, 'ESRI LULC 2021', false);
Map.addLayer(LULC22_mosaic, {min:1, max:9, palette:ESRLULCdictPalette['colors']}, 'ESRI LULC 2022', false);
// Landcover with masking (only Water)
Map.addLayer(ESRILULCMaskWater17, {"opacity":1,"bands":["remapped"],"palette":["002bff"]}, 'ESRI LULC 2017 Water Mask', false);
Map.addLayer(ESRILULCMaskWater18, {"opacity":1,"bands":["remapped"],"palette":["002bff"]}, 'ESRI LULC 2018 Water Mask', false);
Map.addLayer(ESRILULCMaskWater19, {"opacity":1,"bands":["remapped"],"palette":["002bff"]}, 'ESRI LULC 2019 Water Mask', false);
Map.addLayer(ESRILULCMaskWater20, {"opacity":1,"bands":["remapped"],"palette":["002bff"]}, 'ESRI LULC 2020 Water Mask', false);
Map.addLayer(ESRILULCMaskWater21, {"opacity":1,"bands":["remapped"],"palette":["002bff"]}, 'ESRI LULC 2021 Water Mask', false);
Map.addLayer(ESRILULCMaskWater22, {"opacity":1,"bands":["remapped"],"palette":["ff0000"]}, 'ESRI LULC 2022 Water Mask', false);
Map.centerObject(geometry, 7);
I'm also using a native GEE Dataset, ESA Worldcover 2021 for a similar project and uses a similar workflow. The code is a bit simpler however since it's only one layer of one year;
/* Geometry is unimportant for this example, just draw a box somewhere with land inside */
var WCdictPalette = {
"names": [
"Trees", "Shrubland", "Grassland", "Cropland", "Built-Up",
"Barren/Sparse", "Snow/Ice", "Open Water", "Herbaceous Wetland", "Mangroves",
"Moss/Lichen"
],
"colours": [
'#006400', '#ffbb22', '#ffff4c', '#f096ff', '#fa0000',
'#b4b4b4', '#f0f0f0', '#0064c8', '#0096a0', '#00cf75',
'#fae6a0'
]};
function Crop(image) {
return image.clip(geometry);
}
// ESA Worldcover - Water is 7
var WCv2021 = ee.ImageCollection("ESA/WorldCover/v200");
var WCmosaic = WCv2021.mosaic()
.remap([10,20,30,40,50,60,70,80,90,95,100],[0,1,2,3,4,5,6,7,8,9,10])
.clip(geometry);
var ESAWCMaskWater = WCmosaic.eq(7); // Only Water
var ESAWCMaskWater = WCmosaic.updateMask(ESAWCMaskWater).clip(geometry);
var WCMask = function(image) {
return image.updateMask(ESAWCMaskWater);
};
// Land cover without Masking
Map.addLayer(WCmosaic, {min:0, max:10, palette:WCdictPalette['colours']}, 'ESA WorldCover 2021', false);
// Landcover with Masking (only water)
Map.addLayer(ESAWCMaskWater, {"opacity":1,"bands":["remapped"],"palette":["002bff"]}, 'ESA Worldcover Water Mask', false);
Map.centerObject(geometry, 7);
I want to try to reduce the amount of code I'm entering for the ESRI LULC Dataset annual Layers, and I think I could reduce it at the ESAWCMaskWater
/ESRILULCMaskWaterxx
variable ad WCMaskWater
/LULCMask
function because the function is repeated 5 times, it's just the year changes (17,18,19,20,21,22).
I found on the GEE Devhelp page that you can use Regular Expressions to select Image bands within Image Collections, but can you do something similar with Variables?
i.e.
/* This will not work but I can't think of the 'correct' way to use regexp in this manner for Variables */
var ESRILULCMaskWater = image.select('LULC[17-22]_mosaic').eq(1); // Only Water
var ESRILULCMaskWater = 'LULC[17-22]_mosaic'.updateMask(ESRILULCMaskWater).clip(geometry);
var LULCMask = function(image) {
return image.updateMask('ESRILULCMaskWater[17-22]');
};
My script works fine as it stands if it isn't possible, but I'd just like to have less Variables to edit and think about if I need to change the Mask later from Water to Built-up Areas, for example.
var ESRILULCMaskWater17 = LULC17_mosaic.eq(1); // Only Water var ESRILULCMaskWater17 = LULC17_mosaic.updateMask(ESRILULCMaskWater17).clip(geometry); var WCMask = function(image) { return image.updateMask(ESRILULCMaskWater17); };
...to cover all years instead of each year individually. At the moment I get nothing and expect nothing, but don't know if it's possible with GEE.