Subscribe PlanetScope data via sentinel-hub Python Package
In the age of information, satellite imagery has become an invaluable asset for various fields including environmental monitoring, agriculture, urban planning, and disaster management. With the advent of platforms like Sentinel Hub, accessing and analyzing satellite data has become more accessible than ever before. One of the key datasets available through Sentinel Hub is PlanetScope imagery, offering high-resolution images of the Earth’s surface. In this blog post, we’ll explore how you can harness the power of PlanetScope data via Sentinel Hub for a myriad of applications.
Understanding PlanetScope Data
PlanetScope is a constellation of Earth-imaging satellites operated by Planet Labs. These satellites capture high-resolution imagery of the Earth’s surface with a high frequency of revisits. The data provided by PlanetScope satellites can be instrumental in monitoring changes in landscapes, tracking deforestation, assessing agricultural health, and much more.
What is Sentinel Hub?
Sentinel Hub is a cloud-based platform that provides access to a wealth of satellite data, including imagery from the European Space Agency’s Sentinel satellites as well as data from commercial providers like Planet Labs. It offers a powerful Application Programming Interface (API) that allows users to retrieve, process, and analyze satellite imagery for various purposes.
Purpose of this blog
PlanetScope let’s you subscribe to the area of interest based on which you will receive year long data. In this blog, we’ll explore steps on how to subscribe to data and use it with sentinelhub-py package
1. Register on sentinel hub and buy planet subscription
Registering on sentinel-hub is free, but you’ll need to purchase planet satellite data depending upon in which region you are interested. Checkout pricing page here.
Once you have paid, you’ll receive planet apikey
that you can use. You’ll also need to create client_id
& client_secret
for your sentinel hub account
2. Authentication API
For all Sentinel-hub APIs, we need to provide authentication, documentaion for it is available https://docs.sentinel-hub.com/api/latest/api/overview/authentication , you can checkout implementation on following link.
This will require client_id
and client_secret
Planet Subscription API
Subscription APIs allow users to register AOI and based on which user can keep receiving deliveries.
3. Create Subscription
Creating subscription will require following body
{
"name": "new_farm", // name of farm
"input": {
"provider": "PLANET",
"planetApiKey": "my_planet_key", // your planet key
"bounds": {
"geometry": {
"coordinates": [
[
[
73.76473486171818,
20.033894468220993
],
[
73.76461339277836,
20.033479489960186
],
[
73.76484528802897,
20.03346911548904
],
[
73.76488945855368,
20.03314750656199
],
[
73.76520969485364,
20.033168255545192
],
[
73.76528699327051,
20.033811472656197
],
[
73.76473486171818,
20.033894468220993
]
]
],
"type": "Polygon"
}
},
"data": [
{
"itemType": "PSScene",
"harmonizeTo": "NONE",
"productBundle": "analytic_8b_sr_udm2",
"dataFilter": {
"timeRange": {
"from": "2024-01-20T00:00:00.000Z" // from when you want to get data
},
"maxCloudCoverage": 30 // Cloud coverage
}
}
]
}
}jso
Click here to see API in working
This will create subscription which is of status CREATED
, to confirm this subscription, we need to hit another API
4. Confirm Subscription
Once the collection is created, you can check the parameters before buying the service, If everything is correct in body, you can then confirm it by hitting API as following
5. Get Subscription details
Once subscription is confirmed, you can get information about it any time you want by hitting following API, it will require id
of your subscription
The result will look like this
6. Get Subscription delivery details
Once the AOI is subscribed, it is time to see how many datasets are available from which we can capture images .
You can get all available deliver dates and ids in following API
This will spit out array of all possible datasets as following
{
"data": [
{
"id": "a1b88b9a-8910-49e9-aeef-5a4522860c3c",
"itemId": "20240225_045407_03_24c7",
"provider": "PLANET",
"created": "2024-02-26T04:45:00.442827Z",
"status": "DONE"
},
{
"id": "cd5793e3-943c-44e9-b929-fae4dc1aaa72",
"itemId": "20240225_045259_35_2415",
"provider": "PLANET",
"created": "2024-02-26T04:28:28.954795Z",
"status": "DONE"
},
{
"id": "5831d7cb-29c2-4a04-866f-4b372dc6b743",
"itemId": "20240224_045451_37_24ba",
"provider": "PLANET",
"created": "2024-02-25T04:52:11.242871Z",
"status": "DONE"
},
{
"id": "23a5048b-9e3b-44e1-b601-51de0ec372dc",
"itemId": "20240224_045453_52_24ba",
"provider": "PLANET",
"created": "2024-02-25T04:49:28.828263Z",
"status": "DONE"
}
],
"links": {
"currentToken": "0",
"@id": "https://services.sentinel-hub.com/api/v1/dataimport/subscriptions/0eadb6a5-4786-4b2d-9ba4-bc4b6776e3e5/deliveries?viewtoken=0"
}
}
7. Get Available dates via catalog API
To get all available dates of given subscription you can use
# This is script may only work with sentinelhub.__version__ >= '3.4.0'
from sentinelhub import SentinelHubCatalog, BBox, Geometry, SHConfig, CRS, DataCollection
# Credentials
config = SHConfig()
config.sh_client_id = '<your client id here>'
config.sh_client_secret = '<your client secret here>'
config.sh_base_url = 'https://services.sentinel-hub.com'
catalog = catalog = SentinelHubCatalog(config=config)
bbox = BBox(bbox=[73.76461339277891, 20.033147506151515, 73.76528699327106, 20.033894467810516], crs=CRS.WGS84)
search_iterator = catalog.search(
'byoc-<collection-id>',
bbox=bbox,
time=('2024-01-16', '2024-02-26'),
)
results = list(search_iterator)
It will give results like
{
"type": "FeatureCollection",
"features": [
{
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/projection/v1.0.0/schema.json"
],
"id": "224e30be-b8a8-4e6f-b32f-475c8fb0657a",
"type": "Feature",
"geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
73.76473486171874,
20.033894467810516
],
[
73.76461339277891,
20.03347948954971
],
[
73.7648452880295,
20.033469115078567
],
[
73.76488945855424,
20.033147506151515
],
[
73.76520969485419,
20.033168255134722
],
[
73.76528699327106,
20.033811472245713
],
[
73.76473486171874,
20.033894467810516
]
]
]
},
"bbox": [
73.76461339277891,
20.033147506151515,
73.76528699327106,
20.033894467810516
],
"properties": {
"datetime": "2024-02-25T04:54:07.033Z",
"proj:epsg": 32643,
"proj:bbox": [
370791,
2215626,
370863,
2215710
],
"proj:geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::32643"
}
},
"coordinates": [
[
[
370804.77704616764,
2215709.2303530485
],
[
370791.7318965648,
2215663.394317053
],
[
370815.98008184193,
2215662.066889043
],
[
370820.3374971178,
2215626.4370114915
],
[
370853.8518226744,
2215628.486143458
],
[
370862.46303212317,
2215699.6178580034
],
[
370804.77704616764,
2215709.2303530485
]
]
]
}
},
"assets": {},
"collection": "byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/",
"rel": "root",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4/items/224e30be-b8a8-4e6f-b32f-475c8fb0657a",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "parent",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "collection",
"type": "application/json"
}
]
},
{
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/projection/v1.0.0/schema.json"
],
"id": "6d49475c-0d98-4888-adae-5611bc240600",
"type": "Feature",
"geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
73.76473486171874,
20.033894467810516
],
[
73.76461339277891,
20.03347948954971
],
[
73.7648452880295,
20.033469115078567
],
[
73.76488945855424,
20.033147506151515
],
[
73.76520969485419,
20.033168255134722
],
[
73.76528699327106,
20.033811472245713
],
[
73.76473486171874,
20.033894467810516
]
]
]
},
"bbox": [
73.76461339277891,
20.033147506151515,
73.76528699327106,
20.033894467810516
],
"properties": {
"datetime": "2024-02-25T04:52:59.353Z",
"proj:epsg": 32643,
"proj:bbox": [
370791,
2215626,
370863,
2215710
],
"proj:geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::32643"
}
},
"coordinates": [
[
[
370804.77704616764,
2215709.2303530485
],
[
370791.7318965648,
2215663.394317053
],
[
370815.98008184193,
2215662.066889043
],
[
370820.3374971178,
2215626.4370114915
],
[
370853.8518226744,
2215628.486143458
],
[
370862.46303212317,
2215699.6178580034
],
[
370804.77704616764,
2215709.2303530485
]
]
]
}
},
"assets": {},
"collection": "byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/",
"rel": "root",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4/items/6d49475c-0d98-4888-adae-5611bc240600",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "parent",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "collection",
"type": "application/json"
}
]
},
{
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/projection/v1.0.0/schema.json"
],
"id": "38506f0e-a961-480d-95f6-241404c09b28",
"type": "Feature",
"geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
73.76473486171874,
20.033894467810516
],
[
73.76461339277891,
20.03347948954971
],
[
73.7648452880295,
20.033469115078567
],
[
73.76488945855424,
20.033147506151515
],
[
73.76520969485419,
20.033168255134722
],
[
73.76528699327106,
20.033811472245713
],
[
73.76473486171874,
20.033894467810516
]
]
]
},
"bbox": [
73.76461339277891,
20.033147506151515,
73.76528699327106,
20.033894467810516
],
"properties": {
"datetime": "2024-02-24T05:32:21.174Z",
"proj:epsg": 32643,
"proj:bbox": [
370791,
2215626,
370863,
2215710
],
"proj:geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::32643"
}
},
"coordinates": [
[
[
370804.77704616764,
2215709.2303530485
],
[
370791.7318965648,
2215663.394317053
],
[
370815.98008184193,
2215662.066889043
],
[
370820.3374971178,
2215626.4370114915
],
[
370853.8518226744,
2215628.486143458
],
[
370862.46303212317,
2215699.6178580034
],
[
370804.77704616764,
2215709.2303530485
]
]
]
}
},
"assets": {},
"collection": "byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/",
"rel": "root",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4/items/38506f0e-a961-480d-95f6-241404c09b28",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "parent",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "collection",
"type": "application/json"
}
]
}
],
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/search",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/search",
"rel": "next",
"type": "application/geo+json",
"title": "Next set of results",
"method": "POST",
"body": {
"next": 10
},
"merge": true
}
],
"context": {
"next": 10,
"limit": 10,
"returned": 10
}
}
In which we can see dates and IDs of available iteration, this then can be used in Process APIs to get data out of it.
8. Get Data using Process API
# This is script may only work with sentinelhub.__version__ >= '3.4.0'
from sentinelhub import SentinelHubRequest, DataCollection, MimeType, CRS, BBox, SHConfig, Geometry
# Credentials
config = SHConfig()
config.sh_client_id = '<your client id here>'
config.sh_client_secret = '<your client secret here>'
evalscript = """
//VERSION=3
function setup() {
return {
input: ["Blue", "Green", "Red"],
output: { bands: 3 }
};
}
function evaluatePixel(sample) {
return [sample.Red / 3000, sample.Green / 3000, sample.Blue / 3000];
}
"""
bbox = BBox(bbox=[73.76461339277891, 20.033147506151515, 73.76528699327106, 20.033894467810516], crs=CRS.WGS84)
geometry = Geometry(geometry={"type":"Polygon","crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:OGC::CRS84"}},"coordinates":[[[73.76473486171874,20.033894467810516],[73.76461339277891,20.03347948954971],[73.7648452880295,20.033469115078567],[73.76488945855424,20.033147506151515],[73.76520969485419,20.033168255134722],[73.76528699327106,20.033811472245713],[73.76473486171874,20.033894467810516]]]}, crs=CRS.WGS84)
request = SentinelHubRequest(
evalscript=evalscript,
input_data=[
SentinelHubRequest.input_data(
data_collection=DataCollection.define_byoc('<collection_id>'),
time_interval=('2024-02-25', '2024-02-25'),
),
],
responses=[
SentinelHubRequest.output_response('default', MimeType.JPG),
],
bbox=bbox,
geometry=geometry,
size=[512, 604.326],
config=config
)
response = request.get_data()
based on catalog data, you can fill up time_interval information.
results will look like this