Examples of Third Party Data Import

The first example below demonstrates the import of PlanetScope data and the second one the import of Pleiades data. We included the examples of both Simple and Native search so that you can compare their interfaces even though both would usually not be used in the same workflow. Similar applies for the examples of Order products and of Order using query.

A Postman collection with examples can be downloaded here. Please provide your Planet's api key as a value of collection variable called PLANET_API_KEY in order to use the PlanetScope examples. You will also need a SH access token.

The examples in the Postman collection as provided are demonstrational, thus you can try out the whole workflow free of charge and do not need to set PLANET_API_KEY as long as you do not modify the input objects of the data orders.

The requests are given also in Python. To execute them you need to create an OAuth client as is explained here. It is named oauth in these examples.

Get your quota

url = "https://services.sentinel-hub.com/api/v1/dataimport/quotas"
response = oauth.get(url=url)
response.raise_for_status()
response.json()

PlanetScope data import

Provide your Planet API key in <PlanetApiKey>, set the field provider to "PLANET" and run one of the examples below.

For PlanetScope simple search, data.itemType must be set to "PSScene4Band".

url = "https://services.sentinel-hub.com/api/v1/dataimport/search"
query = {
"provider": "PLANET",
"planetApiKey": <PlanetApiKey>,
"bounds": {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
15.825815,
46.714048
],
[
15.813988,
46.707248
],
[
15.832682,
46.703062
],
[
15.839931,
46.711694
],
[
15.835353,
46.716664
],
[
15.825815,
46.714048
]
]
]
}
},
"data": [
{
"itemType": "PSScene4Band",
"dataFilter": {
"timeRange": {
"from": "2019-04-27T00:00:00.000Z",
"to": "2019-04-30T00:00:00.000Z"
},
"maxCloudCoverage": 30,
"nativeFilter": {
"type": "StringInFilter",
"field_name": "quality_category",
"config": [
"standard"
]
}
}
}
]
}
response = oauth.post(url, json=query)
response.raise_for_status()
results = response.json()

To get product ids:

item_ids = [feature["id"] for feature in results["features"]]

This native search is equivalent to the above simple search. Search for PlanetScope is requested by the inclusion of "PSScene4Band" in the native search field item_types in native searches. Note also the added Planet-specific filters PermissionFilter and AssetFilter.

url = "https://services.sentinel-hub.com/api/v1/dataimport/nativesearch"
payload = {
"provider": "PLANET",
"planetApiKey": <PlanetApiKey>,
"item_types": [
"PSScene4Band"
],
"filter": {
"type": "AndFilter",
"config": [
{
"type": "GeometryFilter",
"field_name": "geometry",
"config": {
"type": "Polygon",
"coordinates": [
[
[
15.825815,
46.714048
],
[
15.813988,
46.707248
],
[
15.832682,
46.703062
],
[
15.839931,
46.711694
],
[
15.835353,
46.716664
],
[
15.825815,
46.714048
]
]
]
}
},
{
"type": "DateRangeFilter",
"field_name": "acquired",
"config": {
"gte": "2019-04-27T00:00:00.000Z",
"lte": "2019-04-30T00:00:00.000Z"
}
},
{
"type": "RangeFilter",
"field_name": "cloud_cover",
"config": {
"lte": 0.3
}
},
{
"type": "StringInFilter",
"field_name": "quality_category",
"config": [
"standard"
]
},
{
"type" : "PermissionFilter",
"config" : [ "assets:download" ]
},
{
"type" : "AssetFilter",
"config" : [ "analytic" ]
}
]
}
}
response = oauth.post(url, json=payload)
response.raise_for_status()
results = response.json()

To get product ids:

item_ids = [feature["id"] for feature in results["features"]]

Order

To order PlanetScope data, set provider to "PLANET" data.itemType to "PSScene4Band".

Order products

To order the import of the products, which we got as a result of search and are stored in the variable item_ids:

url = "https://services.sentinel-hub.com/api/v1/dataimport/orders"
payload = {
"name": "planet products",
"input": {
"provider": "PLANET",
"planetApiKey": "",
"bounds": {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
15.825815,
46.714048
],
[
15.813988,
46.707248
],
[
15.832682,
46.703062
],
[
15.839931,
46.711694
],
[
15.835353,
46.716664
],
[
15.825815,
46.714048
]
]
]
}
},
"data": [
{
"itemType": "PSScene4Band",
"productBundle": "analytic",
"itemIds": item_ids
}
]
}
}
response = oauth.post(url, json=payload)
response.raise_for_status()
results = response.json()

Order using query

Another way to order data is using search query, in this case using the query from above:

url = "https://services.sentinel-hub.com/api/v1/dataimport/orders"
query['data'][0]["productBundle"] = "analytic"
payload = {
"name": "some name",
"input": query
}
response = oauth.post(url, json=payload)
response.raise_for_status()
order = response.json()

To extract the order id from the response:

order_id = order['id']

To extract the cost in square kilometers:

sqkm = order['sqkm']

Confirm the order

Confirming the order will subtract the ordered area in km2 from your quota. To initiate import, confirm the order:

url = f"https://services.sentinel-hub.com/api/v1/dataimport/orders/{order_id}/confirm"
response = oauth.post(url)
response.raise_for_status()

Get order information

url = f"https://services.sentinel-hub.com/api/v1/dataimport/orders/{order_id}"
response = oauth.get(url)
response.raise_for_status()
order = response.json()

To extract the order status:

status = order['status']

To extract the BYOC collection ID:

collection_id = order['collectionId']

List all your orders

url = "https://services.sentinel-hub.com/api/v1/dataimport/orders"
response = oauth.get(url)
response.raise_for_status()
response.json()

Access PlanetScope data in a BYOC collection and process a truecolor image

This is a normal Process API request that uses a BYOC collectionId that can be fetched from the get order information request.

response = oauth.post('https://services.sentinel-hub.com/api/v1/process',
headers={"Authorization" : "Bearer <your_access_token>"},
json={
'input': {
"bounds": {
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/32633"
},
"bbox": [562218,5174019,564201,5172501]
},
"data": [{
"type": "CUSTOM",
"dataFilter": {
"collectionId": collection_id,
"timeRange": {
"from": "2019-04-27T00:00:00Z",
"to": "2019-04-28T00:00:00Z"
}
}
}
]
},
"output": {
"width": 512,
"height": 512
},
"evalscript": """
//VERSION=3
function setup() {
return {
input: [{"bands": ["B1", "B2", "B3","dataMask"]}],
output: { bands: 4}
};
}
var f = 10000;
function evaluatePixel(sample) {
return [sample.B3/f*2.5, sample.B2/f*2.5, sample.B1/f*2.5, sample.dataMask];
}
"""
}
)

Pleiades and SPOT data import

Search

Simple Search

To search for Pleiades data, set data.constellation to "PHR", and for SPOT data, set it to "SPOT". In both cases provider must be set to "AIRBUS".

url = "https://services.sentinel-hub.com/api/v1/dataimport/search"
query = {
"provider": "AIRBUS",
"bounds": {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
15.825815,
46.714048
],
[
15.813988,
46.707248
],
[
15.832682,
46.703062
],
[
15.839931,
46.711694
],
[
15.835353,
46.716664
],
[
15.825815,
46.714048
]
]
]
}
},
"data": [
{
"constellation": "PHR",
"dataFilter": {
"timeRange": {
"from": "2017-01-01T00:00:00.000Z",
"to": "2018-01-01T00:00:00.000Z"
}
}
}
]
}
response = oauth.post(url, json=query)
response.raise_for_status()
results = response.json()

To get product ids:

item_ids = [feature["properties"]["id"] for feature in results["features"]]

Please note: Airbus search can return products that don't overlap with the given area of interest. However, orders that include such non-overlapping products are rejected by Airbus. Therefore, Sentinel Hub automatically filters out those products from simple search and when ordering products using a query. Native search, on the other hand, functions purely as a proxy search, thus we don't filter products nor modify responses in other ways.

Native Search

This native search is equivalent to the above simple search. Note the added Airbus-specific field processingLevel.

url = "https://services.sentinel-hub.com/api/v1/dataimport/nativesearch"
payload = {
"provider": "AIRBUS",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
15.825815,
46.714048
],
[
15.813988,
46.707248
],
[
15.832682,
46.703062
],
[
15.839931,
46.711694
],
[
15.835353,
46.716664
],
[
15.825815,
46.714048
]
]
]
},
"constellation": "PHR",
"acquisitionDate": "[2017-01-01T00:00:00.000Z,2018-01-01T00:00:00.000Z]",
"processingLevel" : "ALBUM,SENSOR"
}
response = oauth.post(url, json=payload)
response.raise_for_status()
results = response.json()

To get product ids:

item_ids = [feature["properties"]["id"] for feature in results["features"]]

To get info on how to use the native search, you can check this Airbus guide.

Order

To order Pleaides data, set input.data.constellation to "PHR", and for SPOT data, set it to "SPOT". In both cases provider must be set to "AIRBUS".

Order products

To order the import of the products, which we got as a result of search and are stored in the variable item_ids:

url = "https://services.sentinel-hub.com/api/v1/dataimport/orders"
payload = {
"name": "airbus products",
"input": {
"provider": "AIRBUS",
"bounds": {
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
15.825815,
46.714048
],
[
15.813988,
46.707248
],
[
15.832682,
46.703062
],
[
15.839931,
46.711694
],
[
15.835353,
46.716664
],
[
15.825815,
46.714048
]
]
]
}
},
"data": [
{
"constellation": "PHR",
"products": [
{
"id": item_ids[0]
}
]
}
]
}
}
response = oauth.post(url, json=payload)
response.raise_for_status()
results = response.json()

Order using query

Another way to order data is using search query, in this case using query from above:

url = "https://services.sentinel-hub.com/api/v1/dataimport/orders"
payload = {
"name": "airbus query",
"input": query
}
response = oauth.post(url, json=payload)
response.raise_for_status()
order = response.json()

To extract the order id from the response:

order_id = order['id']

To extract the cost in square kilometers:

sqkm = order['sqkm']

Confirm the order

Confirming the order will subtract the ordered area in km2 from your quota.

To initiate import, confirm the order:

url = f"https://services.sentinel-hub.com/api/v1/dataimport/orders/{order_id}/confirm"
response = oauth.post(url)
response.raise_for_status()

Get order information

url = f"https://services.sentinel-hub.com/api/v1/dataimport/orders/{order_id}"
response = oauth.get(url)
response.raise_for_status()
order = response.json()

To extract the order status:

status = order['status']

To extract the BYOC collection ID:

collection_id = order['collectionId']

List all your orders

url = "https://services.sentinel-hub.com/api/v1/dataimport/orders"
response = oauth.get(url)
response.raise_for_status()
response.json()

Access Pleiades data in a BYOC collection and process a truecolor image

This is a normal Process API request that uses a BYOC collectionId that can be fetched from the get order information request.

response = oauth.post('https://services.sentinel-hub.com/api/v1/process',
headers={"Authorization" : "Bearer <your_access_token>"},
json={
'input': {
"bounds": {
"properties": {
"crs": "http://www.opengis.net/def/crs/EPSG/0/32633"
},
"bbox": [562218,5174019,564201,5172501]
},
"data": [{
"type": "CUSTOM",
"dataFilter": {
"collectionId": collection_id,
"timeRange": {
"from": "2017-09-13T00:00:00Z",
"to": "2017-09-13T23:59:59Z"
}
}
}
]
},
"output": {
"width": 512,
"height": 512
},
"evalscript": """
//VERSION=3
function setup() {
return {
input: ["B0", "B1", "B2", "dataMask"],
output: { bands: 4 }
};
}
var f = 2000;
function evaluatePixel(sample) {
return [sample.B2/f, sample.B1/f, sample.B0/f, sample.dataMask];
}
"""
}
)