Getting started with AxelGlobe STAC API
Introduction
The AxelGlobe STAC API provides users the following capabilities.
- Get STAC Catalogs
- Get STAC Collections
- Get STAC Items (features)
- Search STAC Items (features)
- Download assets
For example, you can search the AxelGlobe Image Product items with the following parameters.
bbox
: A set of latitudes and longitudes representing a square.bbox
parameter should be[minX, minY, maxX, maxY]
. e.g.[133,35,137,36]
datetime
: A range of captured time. e.g.2021-04-10T00:00:00Z/2021-06-30T23:59:59Z
collections
: A list of collections you want search. e.g.["grus-1"]
The AxelGlobe STAC API is implemented following the STAC API.
What is a STAC Spec ?
The "STAC" stands for "The SpatioTemporal Asset Catalog" and provides a common language to describe a range of geospatial information.
The goal is for all providers of spatiotemporal assets (Imagery, SAR, Point Clouds, Data Cubes, Full Motion Video, etc) to expose their data as SpatioTemporal Asset Catalogs (STAC), so that new code doesn't need to be written whenever a new data set or API is released.
There are several public STAC catalogs.
What kind of assets are available on the AxelGlobe STAC API?
The AxelGlobe STAC API's grus-1
collection provides the following assets.
Asset type | Description |
---|---|
thumbnail | An thumbnail of the True Color Image product. |
tci | Pansharpened True Color Image. GSD is 2.5m. |
band0 | Panchromatic band image. GSD is 2.5m. |
band1 | Blue band image. GSD is 5m. |
band2 | Green band image. GSD is 5m. |
band3 | Red band image. GSD is 5m. |
band4 | RedEdge band image. GSD is 5m. |
band5 | NIR band image. GSD is 5m. |
msi_udm | Multispectral Unusable Data Mask. GSD is 5m. |
Getting started
Prerequisites
To try to use the AxelGlobe STAC API, you need to meet the following conditions.
- You have contracts for your AOIs.
- You have the following API resources. (If you are interested in the API, please contact us.)
client_id
client_secret
Authorization
The AxelGlobe STAC API is a protected by authorization, so you need to be authorized to access the AxelGlobe STAC API resources.
You can get an access token following the OAuth 2.1 Client Credential Flow. To get access token, you need the pair of client_id
and client_secret
.
curl --request POST \
--url https://auth.axelglobe.com/oauth/token \
--header "Content-Type: application/json" \
--data "{
\"grant_type\": \"client_credentials\",
\"client_id\": \"${YOUR_CLIENT_ID}\",
\"client_secret\": \"${YOUR_CLIENT_SECRET}\",
\"audience\": \"https://api.axelglobe.com\"
}"
You will get the following response.
Request an access token response example
{
"access_token": "${ACCESS_TOKEN_GOES_HERE}",
"expires_in": 86400,
"token_type": "Bearer"
}
The access_token
is valid for 24 hours (86400 seconds) since the request succeeds.
Caveat
Regarding the authorization, there is one caveat. If your access_token
is still valid,
but you request authorization unnecessarily frequently, the system will restrict you to request APIs
for a certain period of time.
Once the system restricts your requests, you could not request APIs until the restriction is mitigated.
Get STAC Catalog collections
You can get STAC catalog collections provided by the AxelGlobe STAC API like the followings.
curl --request GET \
--url "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections" \
--header "Authorization: Bearer ${YOUR_ACCESS_TOKEN_GOES_HERE}"
You will get the following response.
Get collections response example
{
"collections": [
{
"type": "Collection",
"id": "grus-1",
"stac_version": "1.0.0",
"description": "GRUS imagery processed to level 1",
"links": [
{
"rel": "items",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features"
},
{
"rel": "self",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1",
"type": "application/json"
},
{
"rel": "parent",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe",
"type": "application/json",
"title": "The AxelGlobe STAC catalog"
}
],
"stac_extensions": [
"https://stac-extensions.github.io/eo/v1.0.0/schema.json",
"https://stac-extensions.github.io/view/v1.0.0/schema.json",
"https://stac-extensions.github.io/sat/v1.0.0/schema.json"
],
"title": "GRUS 1",
"extent": {
"spatial": {
"bbox": [
[
-180.0,
-80.0,
180.0,
80.0
]
]
},
"temporal": {
"interval": [
[
"2019-10-15T00:00:00Z",
null
]
]
}
},
"license": "proprietary",
"providers": [
{
"name": "Axelspace",
"roles": [
"producer"
],
"url": "https://www.axelspace.com"
},
{
"name": "AxelGlobe",
"roles": [
"host",
"processor"
],
"url": "https://axelglobe.com"
}
],
"summaries": {
"platform": [
"GRUS-1A",
"GRUS-1B",
"GRUS-1C",
"GRUS-1D",
"GRUS-1E"
],
"constellation": [
"GRUS-1"
],
"instruments": [
"msi"
],
"eo:bands": [
{
"name": "band0",
"common_name": "pan",
"center_wave_length": 0.673,
"full_width_half_max": 0.446,
"solar_illumination": 1604.11
},
{
"name": "band1",
"common_name": "blue",
"center_wave_length": 0.476,
"full_width_half_max": 0.054,
"solar_illumination": 1985.83
},
{
"name": "band2",
"common_name": "green",
"center_wave_length": 0.549,
"full_width_half_max": 0.068,
"solar_illumination": 1823.2
},
{
"name": "band3",
"common_name": "red",
"center_wave_length": 0.652,
"full_width_half_max": 0.063,
"solar_illumination": 1571.65
},
{
"name": "band4",
"common_name": "rededge",
"center_wave_length": 0.724,
"full_width_half_max": 0.038,
"solar_illumination": 1344.18
},
{
"name": "band5",
"common_name": "nir",
"center_wave_length": 0.834,
"full_width_half_max": 0.128,
"solar_illumination": 1098.04
}
]
}
}
],
"links": [
{
"rel": "self",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections",
"type": "application/json"
},
{
"rel": "root",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe",
"type": "application/json"
}
]
}
Search STAC Items
This section describes example searches for several possible scenarios.
Scenario: search for items that intersect with bbox and have an item-level cloud coverage of N% or less
You can search STAC items provided by the AxelGlobe grus-1
collection like the followings.
curl --request GET \
--url "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/search" \
--header "Authorization: Bearer ${YOUR_ACCESS_TOKEN_GOES_HERE}" \
-G \
--data-urlencode "bbox=133,35,137,36" \
--data-urlencode "datetime=2021-04-10T00:00:00Z/2021-06-30T23:59:59Z" \
--data-urlencode "collections=grus-1" \
--data-urlencode "limit=5" \
--data-urlencode "filter=eo:cloud_cover <= 30"
This search with these paremeters means that find all Tiles in (bbox) with a capture date from 2021-04-10 to 2021-06-30 from captures and cloud cover less than or equal to 30%
.
You will get the following response.
Search items response example
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"stac_version": "1.0.0",
"id": "00129aa5-f8cd-41a7-a3a8-8b36b6512509",
"properties": {
"eo:bands": [
{
"name": "band0",
"common_name": "pan",
"center_wave_length": 0.673,
"full_width_half_max": 0.446,
"solar_illumination": 1.60411216811148
},
{
"name": "band1",
"common_name": "blue",
"center_wave_length": 0.476,
"full_width_half_max": 0.054,
"solar_illumination": 1.98583364081622
},
{
"name": "band2",
"common_name": "green",
"center_wave_length": 0.549,
"full_width_half_max": 0.068,
"solar_illumination": 1.8232034021491599
},
{
"name": "band3",
"common_name": "red",
"center_wave_length": 0.652,
"full_width_half_max": 0.063,
"solar_illumination": 1.5716542224007
},
{
"name": "band4",
"common_name": "rededge",
"center_wave_length": 0.724,
"full_width_half_max": 0.038,
"solar_illumination": 1.34418032275358
},
{
"name": "band5",
"common_name": "nir",
"center_wave_length": 0.834,
"full_width_half_max": 0.128,
"solar_illumination": 1.09804143023128
}
],
"eo:cloud_cover": 0.0,
"view:off_nadir": 4.699864,
"sat:orbit_state": "ascending",
"constellation": "GRUS-1",
"instruments": [
"msi"
],
"platform": "GRUS-1A",
"gsd": 2.5,
"datetime": "2021-12-23T01:44:42Z"
},
"geometry": {
"type": "Polygon",
"crs": {
"type": "Polygon",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
131.43531494320698,
32.68181818181818
],
[
131.43531494320698,
32.72727272727273
],
[
131.48842012096182,
32.72727272727273
],
[
131.48842012096182,
32.68181818181818
],
[
131.43531494320698,
32.68181818181818
]
]
]
},
"links": [
{
"rel": "parent",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1",
"type": "application/json",
"title": "GRUS 1"
},
{
"rel": "self",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509",
"type": "application/json"
},
{
"rel": "collection",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1",
"type": "application/json",
"title": "GRUS 1"
}
],
"assets": {
"thumbnail": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_thumbnail.jpg",
"title": "Thumbnail",
"roles": [
"thumbnail"
]
},
"tci": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_tci.tif",
"title": "Pansharpened True Color Image",
"roles": [
"data"
]
},
"band0": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_band0.tif",
"title": "Panchromatic band",
"eo:bands": [
{
"name": "band0",
"common_name": "pan",
"center_wave_length": 0.673,
"full_width_half_max": 0.446,
"solar_illumination": 1.60411216811148
}
],
"roles": [
"data"
]
},
"band1": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_band1.tif",
"title": "Blue band",
"eo:bands": [
{
"name": "band1",
"common_name": "blue",
"center_wave_length": 0.476,
"full_width_half_max": 0.054,
"solar_illumination": 1.98583364081622
}
],
"roles": [
"data"
]
},
"band2": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_band2.tif",
"title": "Green band",
"eo:bands": [
{
"name": "band2",
"common_name": "green",
"center_wave_length": 0.549,
"full_width_half_max": 0.068,
"solar_illumination": 1.8232034021491599
}
],
"roles": [
"data"
]
},
"band3": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_band3.tif",
"title": "Red band",
"eo:bands": [
{
"name": "band3",
"common_name": "red",
"center_wave_length": 0.652,
"full_width_half_max": 0.063,
"solar_illumination": 1.5716542224007
}
],
"roles": [
"data"
]
},
"band4": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_band4.tif",
"title": "RedEdge band",
"eo:bands": [
{
"name": "band4",
"common_name": "rededge",
"center_wave_length": 0.724,
"full_width_half_max": 0.038,
"solar_illumination": 1.34418032275358
}
],
"roles": [
"data"
]
},
"band5": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_band5.tif",
"title": "Near-Infrared band",
"eo:bands": [
{
"name": "band5",
"common_name": "nir",
"center_wave_length": 0.834,
"full_width_half_max": 0.128,
"solar_illumination": 1.09804143023128
}
],
"roles": [
"data"
]
},
"msi_udm": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_msi_udm.tif",
"title": "Unusable Data Musk for Multi Spectral Image",
"roles": [
"data"
]
},
"msi_udm_metadata": {
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_msi_udm_metadata.json",
"title": "Unusable Data Musk Metadata for Multi Spectral Image",
"roles": [
"metadata"
]
}
},
"bbox": [
131.435315,
32.681818,
131.48842,
32.727273
],
"stac_extensions": [
"https://stac-extensions.github.io/eo/v1.0.0/schema.json",
"https://stac-extensions.github.io/view/v1.0.0/schema.json",
"https://stac-extensions.github.io/sat/v1.0.0/schema.json"
],
"collection": "grus-1"
}
],
"links": [
{
"rel": "next",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/search?page=2",
"type": "application/json"
},
{
"rel": "self",
"href": "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/search",
"type": "application/json"
}
],
"timestamp": "2022-08-31T07:09:06.235450",
"numberReturned": 1
}
Scenario: search for items that intersect with bbox and have an AOI-level cloud coverage of N% or less
As another search use case, if you want to search tiles by average cloud cover within an AOI (bbox), you can request like the following.
curl --request GET \
--url "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/search" \
--header "Authorization: Bearer ${YOUR_ACCESS_TOKEN_GOES_HERE}" \
-G \
--data-urlencode "bbox=133,35,137,36" \
--data-urlencode "datetime=2021-04-10T00:00:00Z/2021-06-30T23:59:59Z" \
--data-urlencode "collections=grus-1" \
--data-urlencode "limit=5" \
--data-urlencode "filter=avg(eo:cloud_cover) <= 30"
If the avg(eo:cloud_cover)
of tiles which belong to the same capture and intersect with the bbox is 20%, the response will include those tiles.
If it is 40%, the response will not include those tiles.
Scenario: search for items that intersect with more expressive geometry than bbox and have an AOI-level cloud coverage of N% or less
If you want to search items by more complex geometry, you can use CQL-2 S_INTERSECTS
spatial function.
S_INTERSECTS
spatial function syntax is like the following.
S_INTERSECTS({queryable}, {geometry data type})
On the collection grus-1
, following geometry types are supported or are not supported.
geometry data type | supported | example |
---|---|---|
POINT | ○ | POINT(-50.38 -21.5) |
LINESTRING | ○ | LINESTRING(-50.38 -21.5, -50.09 -21.22) |
MULTIPOINT | ○ | MULTIPOINT(-50.38 -21.5, -50.21 -21.35, -50.09 -21.22) |
MULTILINESTRING | ○ | MULTILINESTRING((-50.38 -21.5, -50.09 -21.22), (-50.40 -21.5, -50.20 -21.22)) |
POLYGON | ○ | POLYGON ((-50.20505723737355 -21.232224612155605, -50.241064225176046 -21.313183636346878, -50.46497592428804 -21.236341502437398, -50.393497166332 -21.3760852767586, -50.44812052553934 -21.413061245887874, -50.39418449523467 -21.46133360699264, -50.28895655861953 -21.377395489410375, -50.3429761155798 -21.48154901026048, -50.246261937136524 -21.504062285999552, -50.24589922810463 -21.42714150367614, -50.10308176515423 -21.461298512790606, -50.06293125593601 -21.332805004588934, -50.20505723737355 -21.232224612155605)) |
MULTIPOLYGON | ○ | MULTIPOLYGON (((-50.377998355519196 -21.25571182037737, -50.39389773429008 -21.306903229767897, -50.33831203728997 -21.326928577662557, -50.30119747112292 -21.30514840932203, -50.30233752991262 -21.265344869483116, -50.377998355519196 -21.25571182037737)), ((-50.30307167289692 -21.33556537511332, -50.29675481118801 -21.352508108156158, -50.320483483126424 -21.37151690592809, -50.33829784306903 -21.37531838541942, -50.32083308423938 -21.415381832666043, -50.27781101074311 -21.39743120280255, -50.26742062143981 -21.40399484490206, -50.24515788837763 -21.3798116216757, -50.20469383948901 -21.389847864440497, -50.19355419558164 -21.371524192627504, -50.249239808424704 -21.337647270055186, -50.30307167289692 -21.33556537511332))) |
GEOMETRYCOLLECTION | × | GEOMETRYCOLLECTION(POLYGON ((-50.377998355519196 -21.25571182037737, -50.39389773429008 -21.306903229767897, -50.33831203728997 -21.326928577662557, -50.30119747112292 -21.30514840932203, -50.30233752991262 -21.265344869483116, -50.377998355519196 -21.25571182037737)),POLYGON ((-50.30307167289692 -21.33556537511332, -50.29675481118801 -21.352508108156158, -50.320483483126424 -21.37151690592809, -50.33829784306903 -21.37531838541942, -50.32083308423938 -21.415381832666043, -50.27781101074311 -21.39743120280255, -50.26742062143981 -21.40399484490206, -50.24515788837763 -21.3798116216757, -50.20469383948901 -21.389847864440497, -50.19355419558164 -21.371524192627504, -50.249239808424704 -21.337647270055186, -50.30307167289692 -21.33556537511332))) |
BBOX | ○ | BBOX(-50.38, -21.5, -50.09, -21.22) |
ENVELOPE | × | ENVELOPE(-50.38, -21.5, -50.09, -21.22) |
The following HTTP request sample is to search items that intersect with your geometry (MULTIPOLYGON
) and have an AOI-level cloud coverage of N%.
curl --request GET \
--url "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/search" \
--header "Authorization: Bearer ${YOUR_ACCESS_TOKEN_GOES_HERE}" \
-G \
--data-urlencode "datetime=2021-04-10T00:00:00Z/2021-06-30T23:59:59Z" \
--data-urlencode "collections=grus-1" \
--data-urlencode "limit=5" \
--data-urlencode "filter=avg(eo:cloud_cover) <= 20 AND S_INTERSECTS(geometry, MULTIPOLYGON (((-50.377998355519196 -21.25571182037737, -50.39389773429008 -21.306903229767897, -50.33831203728997 -21.326928577662557, -50.30119747112292 -21.30514840932203, -50.30233752991262 -21.265344869483116, -50.377998355519196 -21.25571182037737)), ((-50.30307167289692 -21.33556537511332, -50.29675481118801 -21.352508108156158, -50.320483483126424 -21.37151690592809, -50.33829784306903 -21.37531838541942, -50.32083308423938 -21.415381832666043, -50.27781101074311 -21.39743120280255, -50.26742062143981 -21.40399484490206, -50.24515788837763 -21.3798116216757, -50.20469383948901 -21.389847864440497, -50.19355419558164 -21.371524192627504, -50.249239808424704 -21.337647270055186, -50.30307167289692 -21.33556537511332))))"
If the avg(eo:cloud_cover)
of tiles which belong to the same capture and intersect with the geometry is 18.75%, the response will include those tiles.
If it is 30%, the response will not include those tiles.
Scenario: search for items that tie to your task you requested through the Tasking API
Let's assume that you requested a task and you could get the capture id from the Tasking API responses.
If you want to search the collection grus-1
items which tie the capture id (e.g. 52eZg9k7rPEyYQGX
), you can request like the following.
curl --request GET \
--url "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/search" \
--header "Authorization: Bearer ${YOUR_ACCESS_TOKEN_GOES_HERE}" \
-G \
--data-urlencode "collections=grus-1" \
--data-urlencode "limit=20" \
--data-urlencode "filter=ag:capture_id = '52eZg9k7rPEyYQGX'"
Download Asset
After you get links for download assets (e.g. thumbnail) from STAC item, you can download an asset using the gotten URL like the followings.
Once your request is accepted, the server will return a response containing the redirection to the resource.
To download an asset in one request, you need to add a option to follow the redirect URL. e.g. curl
provides us --location
option.
curl --location --request GET \
--url "https://api.axelglobe.com/stac/v1/catalogs/axelglobe/collections/grus-1/features/00129aa5-f8cd-41a7-a3a8-8b36b6512509/2021-12-23_00129aa5-f8cd-41a7-a3a8-8b36b6512509_thumbnail.jpg" \
--header "Authorization: Bearer ${YOUR_ACCESS_TOKEN_GOES_HERE}"
That's all!