Examples of Data Fusion

To request data using any of the request below, you will need to replace the string <your access token> with your Sentinel Hub access token. Sentinel Hub access token will look something like this:

ayJhbGciOiJSUzI1NiJ9.ayJzdWIiOiI0MmYwODZjCy1kMzI3LTRlOTMtYWMxNS00ODAwOGFiZjI0YjIiLCJhdWQiOiJlY2I1MGM1Zi1i
MWM1LTQ3ZTgtYWE4NC0zZTU4NzJlM2I2MTEiLCJqdGkiOiI5MzYxMWE4ODEyNTM4Y2M0MmU0NDJjYjUyMTY0YmJlNyIsImV4cCI6MTU1N
TQyMzk3MiwibmFtZSI6ImFuamEudnJlY2tvQHNpbmVyZ2lzZS5jb20iLCJlbWFpbCI6ImFuamEudnJlY2tvQHNpbmVyZ2lzZS5jb20iLC
JzaWQiOiIzZjVjZDVkNS04MjRiLTQ3ZjYtODgwNy0wNDMyNWY4ODQxZmQifQ.U7FPOy_2jlEOFxXSjyN5KEdBROna3-Dyec0feShIbUOY
1p9lEXdNaMmR5euiINi2RXDayX9Kr47CuSTsvq1zHFvZs1YgkFr1iH6kDuX-t_-wfWpqu5oPjoPVKZ4Rj0Ms_dxAUTQFTXR0rlbLuO-KS
gnaeLVb5iiv_qY3Ctq2XKdIRcFRQLFziFcP4yZJl-NZMlwzsiiwjakcpYpI5jSYAdU2hpZLHRzceseeZt5YfZOe5Px1kZXro9Nd0L2GPC
-qzOXw_V1saMGFa2ov8qV6Dvk92iv2SDDdGhOdII_JOf8XkK4E3g2z0EEFdWhG9F4Iky4ukNsqBPgE8LRb31s0hg

and can be obtained as described in the Authentication chapter.

A Postman collection with examples can be downloaded here. Our Postman collections are deprecated and are not being updated since July 2022.

Pan-sharpen Landsat-8 with Sentinel-2

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
2.1421623229980464,
41.37796785471600,
2.2084236145019527,
41.40784461738553
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"id": "ls8",
"type": "landsat-8-l1c",
"dataFilter": {
"timeRange": {
"from": "2020-05-21T00:00:00Z",
"to": "2020-05-22T00:00:00Z"
}
}
},
{
"id": "l2a",
"type": "sentinel-2-l2a",
"dataFilter": {
"timeRange": {
"from": "2020-05-22T00:00:00Z",
"to": "2020-05-23T00:00:00Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 462
}
}' \
-F 'evalscript=//VERSION=3
function setup() {
return {
input: [{
datasource: "ls8",
bands: ["B02", "B03", "B04"]
}, {
datasource: "l2a",
bands: ["B02", "B03", "B04"]
}
],
output: [{
bands: 3
}]
}
}
let minVal = 0.0
let maxVal = 0.4
let viz = new DefaultVisualizer(minVal, maxVal)
function evaluatePixel(samples, inputData, inputMetadata, customData, outputMetadata) {
var ls8 = samples.ls8[0]
var s2 = samples.l2a[0]
// Use weighted arithmetic average of S2.B02 to S2.B04 for pan-sharpening
let sudoPanW3 = (ls8.B04 + ls8.B03 + ls8.B02) / 3
let s2PanR3 = (s2.B04 + s2.B03 + s2.B02) / 3
let s2ratioWR3 = s2PanR3 / sudoPanW3
let val = [ls8.B04 * s2ratioWR3, ls8.B03 * s2ratioWR3, ls8.B02 * s2ratioWR3]
return viz.processList(val)
}'

Pan-sharpen Sentinel-3 OLCI with Sentinel-2

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
7.388827,
53.537043,
8.35627,
53.901102
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"id": "s2l1c",
"type": "sentinel-2-l1c",
"dataFilter": {
"timeRange": {
"from": "2020-06-01T00:00:00Z",
"to": "2020-06-01T23:59:00Z"
}
}
},
{
"id": "s3olci",
"type": "sentinel-3-olci",
"dataFilter": {
"timeRange": {
"from": "2020-06-01T00:00:00Z",
"to": "2020-06-01T23:59:00Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 1024
}
}' \
-F 'evalscript=//VERSION=3
function setup() {
return {
input: [{
datasource: "s2l1c",
bands: ["B02", "B03", "B04"]
}, {
datasource: "s3olci",
bands: ["B04", "B06", "B08"]
}
],
output: [{
bands: 3
}]
}
}
function evaluatePixel(samples, inputData, inputMetadata, customData, outputMetadata) {
let s3 = samples.s3olci[0]
let s2 = samples.s2l1c[0]
let amount_s2 = 0.5
let gain = 3.00
return [
gain * (s3.B08 * (1 - amount_s2) + s2.B04 * amount_s2),
gain * (s3.B06 * (1 - amount_s2) + s2.B03 * amount_s2),
gain * (s3.B04 * (1 - amount_s2) + s2.B02 * amount_s2)
]
}'

Replace clouds in Sentinel-2 images with Sentinel-1 data

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
33.3219,
44.7014,
33.8073,
44.4791
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"id": "s2l1c",
"type": "sentinel-2-l1c",
"dataFilter": {
"timeRange": {
"from": "2020-05-11T00:00:00Z",
"to": "2020-05-11T23:59:00Z"
}
}
},
{
"id": "s1grd",
"type": "sentinel-1-grd",
"dataFilter": {
"timeRange": {
"from": "2020-05-11T00:00:00Z",
"to": "2020-05-11T23:59:00Z"
}
},
"processing": {
"orthorectify": "true",
"backCoeff": "SIGMA0_ELLIPSOID"
}
}
]
},
"output": {
"width": 1024,
"height": 663
}
}' \
-F 'evalscript=// VERSION=3
function setup() {
return {
input: [{
datasource: "s2l1c",
bands: ["B02", "B03", "B04", "CLP"]
},
{
datasource: "s1grd",
bands: ["VV", "VH"]
}
],
output: [{
bands: 3
}]
}
}
function evaluatePixel(samples, inputData, inputMetadata, customData, outputMetadata) {
var S2L1C = samples.s2l1c[0]
var S1 = samples.s1grd[0]
let WAT = 25 // Water Threshold for SAR
let CLP = S2L1C.CLP / 2.55 // cloud probability in percent
let CLPT = 70 // cloud probability threshold in percent
if (CLP > CLPT) {
if (S1.VV / S1.VH <= WAT) {
return [S1.VV * 3.0, S1.VV * 1.1 + S1.VH * 8.75, S1.VH * 1.75]
} else { // S1.VV / S1.VH > WAT
return [S1.VV * 1, S1.VV * 8, 0.5 + S1.VV * 3 + S1.VH * 2000]
}
}
return [3 * S2L1C.B04, 3 * S2L1C.B03, 3 * S2L1C.B02]
}'

NDVI with Sentinel-1 and Sentinel-2

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
-100.9204,
37.5718,
-100.4865,
37.8640
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"id": "s1",
"type": "sentinel-1-grd",
"dataFilter": {
"timeRange": {
"from": "2019-04-26T00:00:00Z",
"to": "2019-04-26T23:59:00Z"
}
},
"processing": {
"orthorectify": "true",
"backCoeff": "SIGMA0_ELLIPSOID"
}
},
{
"id": "l2a",
"type": "sentinel-2-l2a",
"dataFilter": {
"timeRange": {
"from": "2019-04-26T00:00:00Z",
"to": "2019-04-26T23:59:00Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 1024
}
}' \
-F 'evalscript=//VERSION=3
function setup() {
return {
input: [{
datasource: "s1",
bands: ["VV", "VH"]
}, {
datasource: "l2a",
bands: ["B08", "B04", "SCL"]
}
],
output: [{
bands: 3
}]
}
}
function toDb(linear) {
// Convert the linear backscatter to DB (Filgueiras et al. (2019), eq. 3)
return 10 * Math.LN10 * linear
}
function calc_s1_ndvi(sigmaVV, sigmaVH) {
// Convert sigma0 to Decibels
let vh_Db = toDb(sigmaVH)
let vv_Db = toDb(sigmaVV)
// Calculate NRPB (Filgueiras et al. (2019), eq. 4)
let NRPB = (vh_Db - vv_Db) / (vh_Db + vv_Db)
// Calculate NDVI_nc with approach A3 (Filgueiras et al. (2019), eq. 14)
let NDVInc = 2.572 - 0.05047 * vh_Db + 0.176 * vv_Db + 3.422 * NRPB
return NDVInc
}
// Create an NDVI visualiser
var viz = new ColorMapVisualizer([
[0.0, 0xa50026],
[0.0, 0xd73027],
[0.2, 0xf46d43],
[0.3, 0xfdae61],
[0.4, 0xfee08b],
[0.5, 0xffffbf],
[0.6, 0xd9ef8b],
[0.7, 0xa6d96a],
[0.8, 0x66bd63],
[0.9, 0x1a9850],
[1.0, 0x006837]
])
function evaluatePixel(samples) {
var s1 = samples.s1[0]
var s2 = samples.l2a[0]
// Use the S2-L2A classification to identify clouds
if ([7, 8, 9, 10].includes(s2.SCL)) {
// If clouds are present use S1 NDVI
let s1_ndvi = calc_s1_ndvi(s1.VV, s1.VH) // Calculate S1 NDVI
return viz.process(s1_ndvi)
} else {
// Otherwise use s2 NDVI
let ndvi = index(s2.B08, s2.B04) // Calculate S2 NDVI
return viz.process(ndvi)
}
}'

Ship detection with Sentinel-1 and Sentinel-2

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
119.60987091064452,
32.176774851931214,
119.91474151611328,
32.3640132852233
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"id": "s1grd",
"type": "sentinel-1-grd",
"dataFilter": {
"timeRange": {
"from": "2020-05-23T00:00:00Z",
"to": "2020-05-23T23:59:00Z"
}
},
"processing": {
"orthorectify": "true",
"backCoeff": "SIGMA0_ELLIPSOID"
}
},
{
"id": "s2l2a",
"type": "sentinel-2-l2a",
"dataFilter": {
"timeRange": {
"from": "2020-05-23T00:00:00Z",
"to": "2020-05-23T23:59:00Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 742
}
}' \
-F 'evalscript=//VERSION=3
function setup() {
return {
input: [{
datasource: "s2l2a",
bands: ["B02", "B03", "B04", "B08"]
}, {
datasource: "s1grd",
bands: ["VV", "VH"]
}
],
output: [{
bands: 3
}]
}
}
function evaluatePixel(samples, inputData, inputMetadata, customData, outputMetadata) {
var S2L2A = samples.s2l2a[0]
var S1 = samples.s1grd[0]
let ndwi = (S2L2A.B03 - S2L2A.B08) / (S2L2A.B03 + S2L2A.B08)
if (ndwi > 0.1) {
if (S1.VV > 0.3 || S1.VH > 0.3) {
return [1, 1, 1]
}
return [4 * S2L2A.B04 - 0.2, 4 * S2L2A.B03 - 0.2, 5 * S2L2A.B02 - 0.2]
}
return [4 * S2L2A.B04 - 0.2, 4 * S2L2A.B03 - 0.2, 4 * S2L2A.B02 - 0.2]
}'

Built up areas detection with Sentinel-1 and Sentinel-2

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
12.280998229980469,
45.40206593659076,
12.43274688720703,
45.47361429775641
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"id": "s2l1c",
"type": "sentinel-2-l1c",
"dataFilter": {
"timeRange": {
"from": "2019-12-10T00:00:00Z",
"to": "2019-12-10T23:59:00Z"
}
}
}, {
"id": "s1grd",
"type": "sentinel-1-grd",
"dataFilter": {
"timeRange": {
"from": "2019-12-10T00:00:00Z",
"to": "2019-12-10T23:59:00Z"
}
},
"processing": {
"orthorectify": "true",
"backCoeff": "SIGMA0_ELLIPSOID"
}
},
{
"id": "s2l2a",
"type": "sentinel-2-l2a",
"dataFilter": {
"timeRange": {
"from": "2019-12-10T00:00:00Z",
"to": "2019-12-10T23:59:00Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 1024
}
}' \
-F 'evalscript=//VERSION=3
function setup() {
return {
input: [{
datasource: "s2l1c",
bands: ["B02", "B03", "B04", "B08", "B11"]
}, {
datasource: "s1grd",
bands: ["VV", "VH"]
}, {
datasource: "s2l2a",
bands: ["B02", "B03", "B04"]
}
],
output: [{
bands: 3
}]
}
}
function evaluatePixel(samples) {
var S2L1C = samples.s2l1c[0]
var S2L2A = samples.s2l2a[0]
var S1 = samples.s1grd[0]
let ndvi = (S2L1C.B08 - S2L1C.B04) / (S2L1C.B08 + S2L1C.B04)
if (ndvi > 0.5) {
return [3 * S2L2A.B04, 3 * S2L2A.B03, 3 * S2L2A.B02]
}
let ndmi = (S2L1C.B08 - S2L1C.B11) / (S2L1C.B08 + S2L1C.B11)
if (ndmi > 0) {
return [3 * S2L2A.B04, 3 * S2L2A.B03, 4 * S2L2A.B02]
}
if (S1.VH > 0.2 || S1.VV > 0.2) {
return [S1.VH * 5.5, S1.VV, S1.VH * 8]
}
return [3 * S2L1C.B04 - 0.2, 3 * S2L1C.B03 - 0.2, 3 * S2L1C.B02 - 0.2]
}'

Fire monitoring with Sentinel-1 and Sentinel-2

curl -X POST \
https://services.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
-59.75738525390625,
-19.919130502461016,
-58.7274169921875,
-19.062117883514652
],
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/4326"
}
},
"data": [{
"type": "sentinel-2-l2a",
"id": "l2a_t1",
"dataFilter": {
"timeRange": {
"from": "2019-09-06T00:00:00Z",
"to": "2019-09-08T23:59:59Z"
}
}
},
{
"type": "sentinel-1-grd",
"id": "s1_t1",
"dataFilter": {
"timeRange": {
"from": "2019-09-06T00:00:00Z",
"to": "2019-09-08T23:59:59Z"
}
}
},
{
"type": "sentinel-1-grd",
"id": "s1_t2",
"dataFilter": {
"timeRange": {
"from": "2019-09-11T00:00:00Z",
"to": "2019-09-13T23:59:59Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 1024
}
}' \
-F 'evalscript=//VERSION=3
// Multitemporal forest fire progression monitoring script utilizing a) Sentinel-2 data from 7 September 2019 for the visualization of burned areas
// and b) Sentinel-1 SAR data to monitor forest fire progression in overcast conditions on 12 September 2019.
function setup() {
return {
input: [{
datasource: "s1_t1",
bands: ["VH"]
}, // S1 data from 7 September 2019 (t1)
{
datasource: "s1_t2",
bands: ["VV", "VH"]
}, // S1 data from 12 September 2019 (t2)
{
datasource: "l2a_t1",
bands: ["B03", "B04", "B08", "B11", "B12"]
}
], // S2 data from 7 September 2019 (t1)
output: [{
bands: 3
}]
}
}
function evaluatePixel(samples, inputData, inputMetadata, customData, outputMetadata) {
var s1_1 = samples.s1_t1[0] //Assigns S1 data from t1
var s1_2 = samples.s1_t2[0] //Assigns S1 data from t2
var s2_1 = samples.l2a_t1[0] //Assigns S2 data from t1
// Calculate indices with S2 data from t1 for Burned Area visualization by Monja Sebela
var NDWI = index(s2_1.B03, s2_1.B08)
var NDVI = index(s2_1.B08, s2_1.B04)
var INDEX = ((s2_1.B11 - s2_1.B12) / (s2_1.B11 + s2_1.B12)) + (s2_1.B08)
// Calculate difference in S1 VH backscatter between second (t2) and first scene (t1) (Belenguer-Plomer et al. 2019)
var VH_diff = (s1_2.VH - s1_1.VH)
// Set classification threshholds
var thr_VH = 0.03
var thr_VH_diff = -0.015
var thr_VV = 0.2
if (NDWI > 0.15 || NDVI > 0.35 || INDEX > 0.2) { // If non-burned areas in S2 image from t1
if (s1_2.VH < thr_VH && VH_diff < thr_VH_diff) { // are classified as burned in S1 image from t2 via thresholds for VH backscatter and the calculated difference layer
return [1, 0, 0] // Return red color
} else {
return [2.5 * s2_1.B12, 2.5 * s2_1.B08, 2.5 * s2_1.B04] // Else return SWIR composite
}
} else {
if (s1_2.VV < thr_VV) { // Else, if already burnt area is also burned in S1 image from t2
return [0.9, 0.9, 0.7] // Return beige color
} else {
return [0, 0, 1] // Else return blue for areas that are no longer burned in S1 image from t2
}
}
}'

Monitoring low pressure clouds with Sentinel-3 OLCI and Sentinel-5P

curl -X POST \
https://creodias.sentinel-hub.com/api/v1/process \
-H 'Authorization: Bearer <your access token>' \
-F 'request={
"input": {
"bounds": {
"bbox": [
-154.82,
21.96,
-135.66,
13.56
],
"properties": {
"crs": "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
}
},
"data": [{
"id": "s3olci",
"type": "sentinel-3-olci",
"dataFilter": {
"timeRange": {
"from": "2020-07-24T00:00:00Z",
"to": "2020-07-24T23:59:59Z"
}
}
},
{
"id": "s5pl2",
"type": "sentinel-5p-l2",
"dataFilter": {
"timeRange": {
"from": "2020-07-24T00:00:00Z",
"to": "2020-07-24T23:59:59Z"
}
}
}
]
},
"output": {
"width": 1024,
"height": 449
}
}' \
-F 'evalscript=//VERSION=3
function setup() {
return {
input: [{
datasource: "s3olci",
bands: ["B04", "B06", "B08"]
}, {
datasource: "s5pl2",
bands: ["CLOUD_TOP_PRESSURE"]
}
],
output: [{
bands: 3
}]
}
}
var minVal = 10000.0
var maxVal = 110000.0
var diff = maxVal - minVal
var limits = [minVal, minVal + 0.125 * diff, minVal + 0.375 * diff, minVal + 0.625 * diff, minVal + 0.875 * diff, maxVal]
var colors = [
[0, 0, 0.5],
[0, 0, 1],
[0, 1, 1],
[1, 1, 0],
[1, 0, 0],
[0.5, 0, 0]
]
function evaluatePixel(samples, inputData, inputMetadata, customData, outputMetadata) {
var S5 = samples.s5pl2[0]
var S3 = samples.s3olci[0]
var CLOUD_TOP_PRESSURE = S5.CLOUD_TOP_PRESSURE
if (CLOUD_TOP_PRESSURE > 0) {
return colorBlend(CLOUD_TOP_PRESSURE, limits, colors)
}
return [S3.B08 * 3, S3.B06 * 3, S3.B04 * 3.5]
}'