Skip to main content

Hi,


I have requested several products with the TPDI API and I am now deriving NDVI using the Process API with the following code:


response = oauth.post('https://services.sentinel-hub.com/api/v1/process',
json={
"input": {
"bounds": {
"bbox": geom
},
"data": [{
"type": collection,
"dataFilter": {
"timeRange": {dates
}
}
}]
},

# Set size of image resx and resy parameters can be used too
"output": {
"width": 512,
"height": 512
},

"evalscript": """
//VERSION=3

function setup() {
return {
input: ["Red", "NIR", "dataMask"],
output: {
bands: 4
}
};
}
function evaluatePixel(sample) {
var NDVI = index(sample.NIR , sample.Red)
return valueInterpolate(NDVI,
[0.0, 0.3, 1.0],
[
[1, 0, 0, sample.dataMask],
[1, 1, 0, sample.dataMask],
[0.1, 0.3, 0, sample.dataMask],
])
}
"""
})

I get a 200 resopnse code and when exploring the response.content I get a very long string.


Using the code bellow, I can plot the content:
image = Image.open(BytesIO(response.content))


but I only get one NDVI visualized. My request for NDVI was for several images, so my doubt is how should I proceed with the response from the Process API in order to access all the outputs. I have tried looking for some kind of separator in the response but nothing clear so far


Thks!!

Hi,

According to the payload and the Evalscript you provided, there’s only one output in your request. Would you mind elaborating a bit more on the request you’re trying to make? Are you trying to get NDVI visualisation for each selected timestamp?


Hi,

Thanks for the feedback, my goal is to order several products, derive NDVI on each of them and using the api response, get a visualiaztion for each one (+ ideally saved as png and geotiff). I thought the function is applied to every product in the request.


Hi,

Would you mind letting us know the collection id (just the first & the last 4 digits) you’re using for your workflow?

Regarding your workflow, what is the area of interest and the timestamp for those products? Could you give me an explicit example?

When compiling a request, the input of the payload defines the geometry, data collection, and time range. Then you could process the data with the Evalscript, i.e., the evalscript works for the data defined in your request. Here is an example to have multiple outputs in a request, it shows how to get visualisation as png and NDVI as tif at the same time.

Note that the mosaicking is set to SIMPLE as a default option in the above script, so you will get only one acquisition (either the most recent, the least recent or the least cloud coverage depending on the setting of mosaickingOrder in the payload). If you’d like to deal with a time series, here is the Evalscript that uses the mosaicking: "ORBIT" to have NDVI visualisation time series as a multi-band tif.


Hi,

Here is the info:

  • first:4
  • last 4: 1fb3
  • Time span 2023-01-01 to 2023-01-14
  • AOI:

-6.14191, # lon ul corner
37.01578, # lat ul corner
-6.11655, # lon lr corner
36.99872] # lat lr corner

I have adapted my code with the first example you mentioned:

## PYTHON

response = oauth.post('https://services.sentinel-hub.com/api/v1/process',
json={
"input": {
"bounds": {
"bbox": [
-6.14191, # lon ul corner
37.01578, # lat ul corner
-6.11655, # lon lr corner
36.99872] # lat lr corner
},
"data": [{
"type": f"byoc-{my_collection}",
"dataFilter": {
"timeRange": {
"from": "2023-01-01T00:00:00Z",
"to": "2023-01-14T23:59:59Z"
}
}
}]
},

"output": {
"width": 512,
"height": 512,
"responses": [
{
"identifier": "default",
"format": {
"type": "image/tiff"
}
}
]
},


"evalscript": """
//VERSION=3

function setup() {
return {
input: ["Red", "NIR"],
output: {
id: "default",
bands: 1,
sampleType: SampleType.FLOAT32
}
};
}
function evaluatePixel(sample) {
let ndvi = (sample.NIR - sample.Red) / (sample.NIR + sample.Red)
return [ ndvi ]
}
"""
})

As I run this code over several products from 2023-01-01 to 2023-01-14, my question is how can I explore/ visualize the multiple NDVIs that are produce from the API response I get back. (I am working in Python btw)


Hi,

Note that the code you provided is not returning multiple responses. It is requesting the NDVI value of the latest acquisition in your collection, i.e., data from 2023-01-13.

You need to set up multiple outputs in your Evalscript and multiple responses in your request body to be able to get the NDVI time series and the visualisation for each timestamp in one single request.

An example request will look like below:

curl -X POST https://services.sentinel-hub.com/api/v1/process \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ' \
-H 'Accept: application/tar' \
-d '{
"input": {
"bounds": {
"bbox": [
-6.14191,
37.01578,
-6.11655,
36.99872
]
},
"data": [
{
"dataFilter": {
"timeRange": {
"from": "2023-01-01T00:00:00Z",
"to": "2023-01-14T23:59:59Z"
}
},
"type": "byoc-*******************1fb3"
}
]
},
"output": {
"width": 752,
"height": 633.42,
"responses": [
{
"identifier": "ndvi_time_series",
"format": {
"type": "image/tiff"
}
},
{
"identifier": "vis_03",
"format": {
"type": "image/png"
}
},
{
"identifier": "vis_04",
"format": {
"type": "image/png"
}
},
{
"identifier": "vis_06",
"format": {
"type": "image/png"
}
},
{
"identifier": "vis_11",
"format": {
"type": "image/png"
}
},
{
"identifier": "vis_12",
"format": {
"type": "image/png"
}
},
{
"identifier": "vis_13",
"format": {
"type": "image/png"
}
}
]
},
"evalscript": "//VERSION=3\n\nfunction setup() {\n return {\n input: [\"Red\", \"NIR\", \"dataMask\"],\n output: [\n {\n id: \"ndvi_time_series\",\n bands: 6,\n sampleType: SampleType.FLOAT32\n },\n {\n id: \"vis_03\",\n bands: 3,\n sampleType: SampleType.AUTO\n },\n {\n id: \"vis_04\",\n bands: 3,\n sampleType: SampleType.AUTO\n },\n {\n id: \"vis_06\",\n bands: 3,\n sampleType: SampleType.AUTO\n },\n {\n id: \"vis_11\",\n bands: 3,\n sampleType: SampleType.AUTO\n },\n {\n id: \"vis_12\",\n bands: 3,\n sampleType: SampleType.AUTO\n },\n {\n id: \"vis_13\",\n bands: 3,\n sampleType: SampleType.AUTO\n }\n ],\n mosaicking: \"ORBIT\"\n };\n}\n\nvar arr_map = {\n \"2023-01-03\": 0,\n \"2023-01-04\": 1,\n \"2023-01-06\": 2,\n \"2023-01-11\": 3,\n \"2023-01-12\": 4,\n \"2023-01-13\": 5\n}\n\nfunction evaluatePixel(samples, scenes) {\n let ndvi_arr = new Array(6).fill(NaN);\n let vis_map = {};\n samples.forEach((sample, pos) => {\n timestamp = scenes.orbits[pos].dateFrom.split(\"T\")[0];\n ndvi_val = index(samples[pos].NIR, samples[pos].Red);\n ndvi_arr[arr_map[timestamp]] = ndvi_val;\n vis_map[\"vis_\".concat(timestamp.split(\"-\")[2])] = valueInterpolate(\n ndvi_val,\n [0.0, 0.3, 1.0],\n [\n [1, 0, 0, samples[pos].dataMask],\n [1, 1, 0, samples[pos].dataMask],\n [0.1, 0.3, 0, samples[pos].dataMask],\n ]\n )\n\n });\n return {\n ndvi_time_series: ndvi_arr,\n vis_03: vis_map[\"vis_03\"],\n vis_04: vis_map[\"vis_04\"],\n vis_06: vis_map[\"vis_06\"],\n vis_11: vis_map[\"vis_11\"],\n vis_12: vis_map[\"vis_12\"],\n vis_13: vis_map[\"vis_13\"],\n }\n}"
}'

The script has 7 outputs (as you can see from the request body and the evalscript), which are the NDVI time series (a multi-band tiff containing NDVI values on 2023-01-03, 2023-01-04, 2023-01-06, 2023-01-11, 2023-01-12 and 2023-01-13) and the visualisation of each acquisition. You could copy this curl request to Requests Builder and translate it to sentinelhub-py code, which is a wrapper of our services.

You could also find basic examples in the documentation to learn more about the package.


Reply