I ended up figuring out my own question, so I'll just leave the solution here:
Example Solution
// ### IMPORTED GEOMETRY ###
var Geom =
/* color: #0b4a8b */
/* displayProperties: [
{
"type": "rectangle"
}
] */
ee.Geometry.Polygon(
[[[-11.11113449176787, 54.43227206644482],
[-11.11113449176787, 51.305678054127945],
[-8.093069992866504, 51.305678054127945],
[-8.093069992866504, 54.43227206644482]]], null, false);
// Filtering imagery for hypothetical timeseries
var START_DATE = '2022-01-01';
var END_DATE = '2022-05-01';
// Filtering imagery to display a particular day on the Map.
var FRST_PRVW_DATE = '2022-03-30';
var LAST_PRVW_DATE = '2022-04-01';
// Setting the Area of Interest
var BOUNDS = Geom;
// Centers the Map on the Area of Interest
Map.centerObject(BOUNDS, 8);
// Sentinel 2 Image Collection and Cloud Masking
function maskS2clouds(image) {
var qa = image.select('QA60');
// Bits 10 and 11 are clouds and cirrus, respectively.
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(qa.bitwiseAnd(cirrusBitMask).eq(0));
// Applies the cloud masking conditions to the IC, and adds the date of acquisition into each image for easy timeseries organising later
return image.updateMask(mask).divide(10000).copyProperties(image, ["system:time_start"]);
}
var S2_L2A = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
.filterDate(START_DATE, END_DATE)
.filterBounds(BOUNDS)
.map(maskS2clouds);
print('S2_L2A_Image Collection', S2_L2A); // Produces 1066 Images/Elements
// Visualisation settings
var rgbVis = {
min: 0,
max: 0.35,
bands: ['B4', 'B3', 'B2'],
};
// Add the Hypothetical timeseries range of imagery to Map (turned off by default because it's intensive)
Map.addLayer(S2_L2A, rgbVis, 'S2_L2A_IC', false);
// Filtering the timeseries range to just a particular day (i.e. 2022-03-31)
var S2_L2A_Filt = S2_L2A.filterDate(FRST_PRVW_DATE, LAST_PRVW_DATE);
print('S2_L2A_IC Filtered (2022-03-31)', S2_L2A_Filt); // Produces 13 Images/Elements that fit the date
// Selecting the first Element of the Filtered IC
var S2_L2A_Filt_1st = S2_L2A_Filt.first();
print ('S2_L2A_Filtered First Element', S2_L2A_Filt_1st); // Produces 1 Image (Element 0 of the previous var)
// Properties Extraction
// Pulls out the System:Index Property of every element in the Filtered IC, puts it in a dictionary, and inserts it into the Properties
var SystemIndex = S2_L2A_Filt.map(function (image) {
return image.set('SysIndex', image.toDictionary(['system:index']));
});
print('Property keys and values of S2_L2A_Filt', SystemIndex); // Returns the same 8 Images/Elements, but now with a 'SysIndex' Object in each Element
// This is done because just trying to extract the original system index brings up null values, or a "this is not a function" error.
// Aggregates the Dictionary into an Array
var list = SystemIndex.aggregate_array('SysIndex');
print('Agg. Array List', list); // Produces the List with only the values of the Dictionary from each Element
// Gets only the first Element of the List
var list_1st = list.get(0);
print('S2_L2A_IC, The First System:Index', list_1st); // Prints the first (0) Elements' System:Index Property.
//Mosaic the S2_L2A_IC that was filtered to the day (Line 39), and gives it the property of the first Element of the List (Line 56)
var S2_L2A_Mosaic = S2_L2A.filterDate(FRST_PRVW_DATE, LAST_PRVW_DATE).mosaic().set(list_1st);
print('S2_Mosaic w/ Properties of the S2_L2A_Filtered_1st', S2_L2A_Mosaic); // The Mosaic now was the same System:Index of the First Element in the IC's List
// Add the Mosaic of one day's imagery to Map
Map.addLayer(S2_L2A_Mosaic, rgbVis, 'S2_L2A_Mosaic_2022_03_31');
// Gets the System:Index of the Mosaic as a String
var index = S2_L2A_Mosaic.get('system:index');
print('System Index in String',index); // "20220331T114349_20220331T114345_T28UGB"
/* Sentinel 2 Imagery follows this naming convention:
* START TIME:'(YYYYMMDD)T(HHMMSS)_' + END TIME:'(YYYYMMDD)T(HHMMSS)_' + UTM MGRS ID: 'T00ABC'
* So slicing it to the first 13 characters gives you the swath start time, to the minute
* This is extracted using getInfo() which can then be put into the image name.
*/
var index = index.getInfo().slice(0,13);
print('Sliced System:Index', index); // "20220331T1143" (i.e. 11:43 AM on March 31st, 2022)
// Just to demonstrate the System:Index being added to the Exported name.
// 'Run' to see the other properties are correct before confirmation of download
// ### DON'T RUN THE TASK ON THE INITIATE EXPORT MENU ### It will be very large.
Export.image.toDrive({
image: S2_L2A_Mosaic.visualize(rgbVis), // .visualize keeps the visualisation parameters for the image for export
description: 'S2_L2A_'+ index, // The Tasks will show a "S2_L2A_20220331T1143" Download available
folder: 'EE_OutputTest', // The destination folder for the imagery in your Account's Google Drive
scale: 'nominal', // Returns requested image AT TRUE SCALE (i.e. 10m).
crs: 'EPSG:3857', // The standard GEE and Wider Internet's Web Mercator Projection, WGS84.
region: Geom, // The Area of Interest
maxPixels: 1e13,
});
In short;
- Run a
.map
function to pull the system:index
out of each image in the Image Collection, put them into a Dictionary, and add that to the Properties of each Image in the Image Collection. (This is important, as trying to extract the original system:index
or system:start_time
results in null). This has the added bonus of being able to extract different and/or multiple properties, should anyone wish.
- Run
.aggregate_array
the created dictionary into a List. I can't explain why you need to do this, only that if you don't and try the next step on the Dictionary function itself, it will bring up an 'Invalid Type' error.
- Create a variable to
.get(0)
the created List to show only the system:index
property of the first Element/Image from the List.
- In the
.Mosaic
, also .set
the List_1st variable to the Mosaic. This puts the system:index
property of the first Image/Element agg.array List into the Mosaic.
- Then just create a variable to
.get('system:index')
on the Mosaic, and another to getInfo()
and slice()
to the string of interest (YYYYMMDDTHHMM). You could include another slice() section to this to include the Tile number (the last characters), or format it.
- In the
description
section of the Export, insert the index variable and you'll have a simple method to insert the date from the first of an Image Collection to your Mosaic, and have it on the Export name.
Best Answer
When getting properties from an image of feature you typically have to cast it to the correct type before using it, or get it as the expected type directly:
value = image.getNumber("CLOUD_COVER_LAND")
or
value = ee.Number(image.get("CLOUD_COVER_LAND"))