I have written a rather simple script for data selection and subsequent export in GEE:
//Create region of interest -> Should be replaced by manual selection of ROIs or ROI center points and subsequent processing of all ROIs by the process implemented for a single ROI in the following
var roi = ee.Geometry.Rectangle([10, 45, 11, 46]);
//Load Sentinel-2 image collection
var coll_s2 = ee.ImageCollection("COPERNICUS/S2");
//Filter for 10 most recent almost cloud-free images
var coll_s2_filtered = coll_s2.filterBounds(roi)
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5))
.sort('system:time_start',false)
.limit(10);
//Create RGB composite
var s2_median = coll_s2_filtered.reduce(ee.Reducer.median()).select(['B4_median','B3_median','B2_median']);
//Export image
Export.image.toDrive({
image: s2_median,
description: 'Sentinel2',
scale: 10,
region: roi
});
What I actually want to do is to avoid hardcoding of a single ROI. Instead, I'd like to select an arbitrary number of rectangular ROIs around the globe and do the same export process for every ROI. I am thinking about doing this by selecting individual marker points and simply adding a buffer around their coordinates in order to achieve rectangular ROIs. However, I don't seem to be able to wrap my head around two critical things:
- How to do all this in a batch-processing manner (i.e. as a mapping over a feature collection or as an iteration through the elements of a list etc.)?
- How to extract the coordinates from the manually selected marker points in the first place?
I am kind of stuck here.
EDIT: I am now following an advice that suggested to make use of FeatureCollections, mapping, buffers and bounding boxes. I first tried what I want to do in a simple minimal example that actually worked:
var listOfMarkers = /* color: #98ff00 */ee.FeatureCollection(
[ee.Feature(
ee.Geometry.Point([6.8115234375, 60.88836817267309]),
{
"system:index": "0"
}),
ee.Feature(
ee.Geometry.Point([15.1611328125, 57.469327688204295]),
{
"system:index": "1"
}),
ee.Feature(
ee.Geometry.Point([27.0703125, 62.95584745563692]),
{
"system:index": "2"
})]);
// A function to create a bounding box out of a point
var createBBox = function(featurePoint) {
var rectangle = featurePoint.buffer(100000).bounds();
return ee.Feature(rectangle);
};
var roi = listOfMarkers.map(createBBox);
Map.addLayer(roi)
print(roi)
var coll_s2 = ee.ImageCollection("COPERNICUS/S2");
//Filter for 10 most recent almost cloud-free images
var coll_s2_filtered = coll_s2.filterBounds(roi)
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5))
.sort('system:time_start',false)
.limit(10);
For the 3 arbitrarily chosen points in the feature collection, this script would give me the 10 most recent Sentinel-2 images with a cloud coverage below 5%. However, as said before, I want to get these 10 images per every marker-defined ROI. So I tried to extend the script:
//Enter same listOfMarkers as above here...
//A function to create an Image Collection out of a marker point
var createImageCollection = function(featurePoint) {
var rectangle = ee.Feature(featurePoint.buffer(100000).bounds());
var coll_s2 = ee.ImageCollection("COPERNICUS/S2");
//Filter for 10 most recent almost cloud-free images
var coll_s2_filtered = coll_s2.filterBounds(rectangle)
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5))
.sort('system:time_start',false)
.limit(10);
return coll_s2_filtered;
};
var s2data = listOfMarkers.map(createImageCollection);
Map.addLayer(s2data)
print(s2data)
Now, unfortunately, this second script gives me an error: "FeatureCollection (Error), Error in map(ID=2): Feature, argument 'geometry': Invalid type. Expected: Geometry. Actual: Feature."
This seems kind of strange, as I am also using ee.Feature for roi in the first example, and it worked nonetheless. Can anybody shed light on this, or explain how I can convert the rectangle created by
var rectangle = ee.Feature(featurePoint.buffer(100000).bounds());
into an ee.Geometry.Rectangle object?