Cloudless Mosaic, PlanetScope
//VERSION=3
//Cloudless Mosaic with PlanetScope
function setup() {
return {
input: ["red", "green", "blue", "dataMask", "clear"],
output: { bands: 4 },
mosaicking: "ORBIT",
};
}
function preProcessScenes(collections) {
collections.scenes.orbits = collections.scenes.orbits.filter(function (
orbit
) {
var orbitDateFrom = new Date(orbit.dateFrom);
const nAggregationDays = 7;
return (
orbitDateFrom.getTime() >=
collections.to.getTime() - nAggregationDays * 24 * 3600 * 1000
);
});
return collections;
}
function getLastObservation(arr) {
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i] !== 0) {
// optional check if you are sure all invalid observations are filtered out
return arr[i];
}
}
return 0;
}
function getMedian(sortedValues) {
var index = Math.floor(sortedValues.length / 2);
return sortedValues[index];
}
function evaluatePixel(samples, scenes) {
var reds = [];
var greens = [];
var blues = []; //empty arrays for reds greens and blues
var a = 0; //incrementer
for (var i = 0; i < samples.length; i++) {
//for each sample
var sample = samples[i]; //get current sample
var clear = sample.dataMask && sample.clear; //0 for clouds OR datamask, 1 for neither
if (clear === 1) {
//if not clouds nor datamask
reds[a] = sample.red; //assign values for that sample to the channel arrays
blues[a] = sample.blue;
greens[a] = sample.green;
a = a + 1; //increment a to represent that at this specific pixel, a value was detected
}
}
var rValue;
var gValue;
var bValue;
if (a > 0) {
rValue = getMedian(reds); // or call getLastObservation - which is less guaranteed to remove hazy images
gValue = getMedian(greens);
bValue = getMedian(blues);
transparency = 1;
} else {
rValue = 1;
gValue = 1;
bValue = 1;
transparency = 0;
}
return [rValue / 3000, gValue / 3000, bValue / 3000, transparency];
}
General description
The cloudless mosaic script composites together observations across a time range, which is set as 7 days in this script. Pixels which are not clear in the Useable Data Mask (UDM) are removed. There are two options for functions to select which scene to get the pixel from, getLastObservation
and getMedian
. getLastObservation
will put the most recent non cloudy pixel on top. getMedian
will remove outliers due to shadows or cloud haze that may have been missed by the UDM algorithm.
Below is an example of several PlanetScope scenes being composited across an area that spans several strips and contains gaps when viewed per day. The script returns a continuous image without gaps.