In our application, we use Sentinel-Hub to fetch historical satellite data (since 2018) for the purpose of analyzing agricultural fields. We fetch the data gradually (month by month instead of a few years at once) for the purpose of handling errors and better user experience (users can observe the ongoing process). Unfortunately, this approach sends too many requests – even the most expensive plan, which offers 1200 requests per minute could potentially be insufficient if we needed to download data about dozens/hundreds fields simultaneously.
Is there any way in which we could reduce the number of requests in our specific case? Alternatively, is there a possibility to increase the request limit?
Below, you’ll find code snippets, which aim to offer a clearer insight into our strategies.
In our app we are using library sentinelhub-js (GitHub - sentinel-hub/sentinelhub-js: Download and process satellite imagery in JavaScript or TypeScript using Sentinel Hub services.) to fetch data from Sentinel Hub. Basically we have 2 fetches per month of satellite data. The goal of the first one is to get available dates and then the second one download - tiff buffer containing data for every day in the month. After that we are processing the data.
Fetch getting dates for the whole month:
let layer = new S2L2ALayer({
instanceId: process.env.INSTANCE_ID,
layerId: "CLOUDINESS",
});
const datesLayer = await layer.findDatesUTC(
bbox,
new Date(Date.UTC(time.getUTCFullYear(), time.getUTCMonth(), 1, 0, 0, 0)),
new Date(Date.UTC(time.getUTCFullYear(), time.getUTCMonth(), time.getUTCDate(), 23, 59,59))
);
“CLOUDINESS” evalscript:
//VERSION=3
function evaluatePixel(samples) {
switch (samples.SCL) {
// Cloud high probability
case 7:
case 8:
case 9:
case 10:
case 11:
return {
default: [1],
dataMask: [samples.dataMask]
};
default:
return {
default: [0],
dataMask: [samples.dataMask]
};
}
}
function setup() {
return {
input: [{
bands: [
"SCL",
"dataMask"
]
}],
output: [
{
id: "default",
bands: 1,
},
{
id: "dataMask",
bands: 1
}
]
}
}
Fetch downloading tiff buffer(with data for every day in the months)
const rawDataLayer = new S2L2ALayer({
instanceId: process.env.INSTANCE_ID,
layerId: "TRUE-COLOR-S2L2A",
evalscript: rawDataEvalscript(dates),
mosaickingOrder: MosaickingOrder.LEAST_RECENT,
});
const getMapParams = createGetMapParams(dates, fieldData);
let imageBlob = await rawDataLayer.getMap(getMapParams, ApiType.WMS);
rawDataEvalscript(dates)
const BANDS_COUNT = 7;
export const rawDataEvalscript = (dates: Date[]) => {
const datesCount = dates.length;
const bandsCount = BANDS_COUNT * datesCount;
return `
//VERSION=3
function setup() {
return {
input: ["B08", "B04", "B03", "B02", "dataMask", "SCL", "CLM"],
output: [
{
id: "default",
bands: ${bandsCount},
sampleType: "UINT8"
},
],
mosaicking: "ORBIT"
};
}
const dates = [${dates.map((date) => `"${date.toISOString().split("T")[0]}"`).join(", ")}];
function evaluatePixel(samples, scenes) {
let data = []
let x = 14;
let length = samples.length
for (let i = 0; i < samples.length; i++) {
const date = scenes.orbits[i].dateFrom.split("T")[0]
if (!dates.includes(date)) continue;
data.push(samples[i].B08 * 255)
data.push(samples[i].B04 * 255)
data.push(samples[i].B03 * 255)
data.push(samples[i].B02 * 255)
data.push(samples[i].dataMask * 255)
data.push(samples[i].SCL)
data.push(samples[i].CLM)
}
return data
}
`;
};