STAC API#

Overview#

This notebook explains the use of the STAC API interface with GeoJSON response format. It uses the pystac [RD17] and pystac_client [RD18] libraries to access the interface. The visualisation of search results is borrowed from the ODC notebook available at [RD19]. Examples using curl on the command-line are provided as well.

URL_LANDING_PAGE =  'https://eocat.esa.int/eo-catalogue/' 

Access landing page#

The landing page provides access to collections (rel=”data”), child catalogs (rel=”child”) and the STAC item search endpoint (rel=”search”). Get the catalogue landing page with links to other resources and available collections.

curl -X GET -G https://eocat.esa.int/eo-catalogue/
from pystac_client import Client 

api = Client.open(URL_LANDING_PAGE) 
# show as a dictionary
api.to_dict()
{'type': 'Catalog',
 'id': 'fedeo',
 'stac_version': '1.0.0',
 'description': 'ESA Catalog provides interoperable access, following ISO/OGC interface guidelines, to Earth Observation metadata',
 'links': [{'rel': 'self',
   'href': 'https://eocat.esa.int/eo-catalogue/',
   'type': 'application/json'},
  {'rel': 'search',
   'href': 'https://eocat.esa.int/eo-catalogue/api?httpAccept=application/opensearchdescription%2Bxml',
   'type': 'application/opensearchdescription+xml',
   'title': 'OpenSearch Description Document'},
  {'rel': 'service-desc',
   'href': 'https://eocat.esa.int/eo-catalogue/api?httpAccept=application/vnd.oai.openapi%2Bjson;version=3.0',
   'type': 'application/vnd.oai.openapi+json;version=3.0',
   'title': 'OpenAPI definition in JSON format'},
  {'rel': 'service-desc',
   'href': 'https://eocat.esa.int/eo-catalogue/api?httpAccept=application/json;profile=http://explain.z3950.org/dtd/2.0/',
   'type': 'application/json;profile="http://explain.z3950.org/dtd/2.0/"',
   'title': 'Explain Document'},
  {'rel': 'service-desc',
   'href': 'https://eocat.esa.int/eo-catalogue/api?httpAccept=application/sru%2Bxml',
   'type': 'application/sru+xml',
   'title': 'Explain Document'},
  {'rel': 'data',
   'href': 'https://eocat.esa.int/eo-catalogue/collections',
   'type': 'application/json',
   'title': 'Metadata about the feature collections'},
  {'rel': 'data',
   'href': 'https://eocat.esa.int/eo-catalogue/collections',
   'type': 'application/ld+json',
   'title': 'Metadata about the feature collections'},
  {'rel': 'data',
   'href': 'https://eocat.esa.int/eo-catalogue/collections',
   'type': 'application/rdf+xml',
   'title': 'Metadata about the feature collections'},
  {'rel': 'data',
   'href': 'https://eocat.esa.int/eo-catalogue/collections',
   'type': 'text/turtle',
   'title': 'Metadata about the feature collections'},
  {'rel': 'conformance',
   'href': 'https://eocat.esa.int/eo-catalogue/conformance',
   'type': 'application/json',
   'title': 'OGC conformance classes implemented by this API'},
  {'rel': 'service-doc',
   'href': 'https://eocat.esa.int/eo-catalogue/readme.html',
   'type': 'text/html',
   'title': 'API Documentation'},
  {'rel': 'service-doc',
   'href': 'https://eocat.esa.int/eo-catalogue/index.html',
   'type': 'text/html',
   'title': 'API Documentation (Jupyter)'},
  {'rel': 'service-doc',
   'href': 'https://redocly.github.io/redoc/?url=https://eocat.esa.int/eo-catalogue/api&nocors',
   'type': 'text/html',
   'title': 'API documentation in ReDoc format'},
  {'rel': 'service-doc',
   'href': 'http://petstore.swagger.io/?url=https://eocat.esa.int/eo-catalogue/api',
   'type': 'text/html',
   'title': 'API documentation in Swagger.io format'},
  {'rel': 'alternate',
   'href': 'https://eocat.esa.int/eo-catalogue?httpAccept=text/html',
   'type': 'text/html',
   'title': 'Landing Page in HTML media type.'},
  {'rel': 'alternate',
   'href': 'https://eocat.esa.int/eo-catalogue?httpAccept=application/ld%2Bjson',
   'type': 'application/ld+json',
   'title': 'Landing Page in JSON-LD media type.'},
  {'rel': 'search',
   'href': 'https://eocat.esa.int/eo-catalogue/search',
   'type': 'application/geo+json',
   'title': 'STAC Search',
   'method': 'GET'},
  {'rel': 'search',
   'href': 'https://eocat.esa.int/eo-catalogue/search',
   'type': 'application/geo+json',
   'title': 'STAC Search',
   'method': 'POST'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/series/eo:platform',
   'type': 'application/json',
   'title': 'platform'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics',
   'type': 'application/json',
   'title': 'Earth Topics'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/instruments',
   'type': 'application/json',
   'title': 'ESA Instruments'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/platforms',
   'type': 'application/json',
   'title': 'ESA Platforms'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/sciencekeyword',
   'type': 'application/json',
   'title': 'GCMD Science Keywords'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/series/eo:organisationName',
   'type': 'application/json',
   'title': 'organisation'},
  {'rel': 'root',
   'href': 'https://eocat.esa.int/eo-catalogue',
   'type': 'application/json',
   'title': 'ESA Catalog'}],
 'extent': {'spatial': {'bbox': [[-180, -90, 180, 90]]},
  'temporal': {'interval': [[None, None]]}},
 'license': 'various',
 'conformsTo': ['http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core',
  'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30',
  'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson',
  'http://www.opengis.net/spec/ogcapi_common-2/1.0/conf/collections',
  'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/simple-query',
  'http://www.opengis.net/spec/ogcapi-records-1/1.0/req/cql-filter',
  'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson',
  'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter',
  'https://api.stacspec.org/v1.0.0-rc.2/core',
  'https://api.stacspec.org/v1.0.0-rc.2/stac-search',
  'https://api.stacspec.org/v1.0.0-rc.2/stac-response',
  'https://api.stacspec.org/v1.0.0-rc.2/collection-search',
  'https://api.stacspec.org/v1.0.0-rc.2/collection-search#filter',
  'https://api.stacspec.org/v1.0.0-rc.1/collection-search#free-text',
  'https://api.stacspec.org/v1.0.0-rc.2/item-search',
  'https://api.stacspec.org/v1.0.0-rc.2/item-search#filter',
  'http://www.opengis.net/spec/cql2/1.0/conf/cql2-text',
  'http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2'],
 'title': 'ESA Catalog'}
# Get catalog title and description
print("Title\t\t:", api.title)
print("Description\t:", api.description)
print("Search link\t:", api.get_search_link())

# List child catalogs
print("Child catalogs:")
# for child in api.get_children():
#    print("\t", child.id)
    
children = [c for c in api.get_children()]
children
Title		: ESA Catalog
Description	: ESA Catalog provides interoperable access, following ISO/OGC interface guidelines, to Earth Observation metadata
Search link	: <Link rel=search target=https://eocat.esa.int/eo-catalogue/search>
Child catalogs:
[<CollectionClient id=eo:platform>,
 <CollectionClient id=5c476560-e0a3-554a-9187-187a90da1309>,
 <CollectionClient id=c98c8eae-7561-55de-bf01-2fb866693c14>,
 <CollectionClient id=738c519f-48db-5344-bebc-030c16781c22>,
 <CollectionClient id=1eb0ea0a-312c-4d74-8d42-6f1ad758f999>,
 <CollectionClient id=eo:organisationName>]
# Show title and id for each of the children.
for count, child in enumerate(children):
    print(f'\t{count} - {child.title}, id="{child.id}"')
	0 - EO platforms, id="eo:platform"
	1 - Earth Topic, id="5c476560-e0a3-554a-9187-187a90da1309"
	2 - Instrument, id="c98c8eae-7561-55de-bf01-2fb866693c14"
	3 - Platform, id="738c519f-48db-5344-bebc-030c16781c22"
	4 - Science Keywords, id="1eb0ea0a-312c-4d74-8d42-6f1ad758f999"
	5 - EO organisations, id="eo:organisationName"

The collections are organised as a tree structure which can be traversed until arriving to a collection with items (granules). Get the details of one of the children of the root catalog as an example.

child = children[1]
child.to_dict()
{'type': 'Collection',
 'id': '5c476560-e0a3-554a-9187-187a90da1309',
 'stac_version': '1.0.0',
 'description': 'Earth Topic',
 'links': [{'rel': 'root',
   'href': 'https://eocat.esa.int/eo-catalogue',
   'type': 'application/json',
   'title': 'ESA Catalog'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/bbe13d71-bea9-55c2-9b65-a24043c35937',
   'type': 'application/json',
   'title': 'Agriculture [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/0d2133c5-b0bb-5ce2-b000-243ade6a65b8',
   'type': 'application/json',
   'title': 'Atmosphere [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/5ff2bf3e-a8da-5aa5-81d2-f801ae6454af',
   'type': 'application/json',
   'title': 'Biosphere [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/4ca68be3-d205-5dea-a292-6f0a7ab35595',
   'type': 'application/json',
   'title': 'Climate [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/e6a9631e-b7cf-5b3e-b414-1600379a72b3',
   'type': 'application/json',
   'title': 'Cryosphere [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/2a1c3522-f4a0-5d63-9d47-7af06a220302',
   'type': 'application/json',
   'title': 'Human Dimensions [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/e4d01e03-0ef5-5b4c-b40f-2b5f49667f53',
   'type': 'application/json',
   'title': 'Land Surface [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/8dc47b68-6cad-59ce-836f-7328372de417',
   'type': 'application/json',
   'title': 'Oceans [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/1589db19-32b2-5945-ad4b-6c3b13713176',
   'type': 'application/json',
   'title': 'Solid Earth [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/a59746f5-d93d-5637-b7fa-6e6220196104',
   'type': 'application/json',
   'title': 'Space Weather [Earth Topics]'},
  {'rel': 'child',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics/8111e456-a0ff-588f-9ab6-9ef66d8df94a',
   'type': 'application/json',
   'title': 'Terrestrial Hydrosphere [Earth Topics]'},
  {'rel': 'self',
   'href': 'https://eocat.esa.int/eo-catalogue/concepts/earthtopics',
   'type': 'application/json'},
  {'rel': 'parent',
   'href': 'https://eocat.esa.int/eo-catalogue/',
   'type': 'application/json',
   'title': 'ESA Catalog'}],
 'title': 'Earth Topic',
 'extent': {'spatial': {'bbox': [[-180, -90, 180, 90]]},
  'temporal': {'interval': [[None, None]]}},
 'license': 'various',
 'providers': [{'name': 'ESA Catalog',
   'roles': ['host'],
   'url': 'https://eocat.esa.int/eo-catalogue/readme.html'}]}
# May have again children, get the list
children = [c for c in child.get_children()]
children
[<CollectionClient id=bbe13d71-bea9-55c2-9b65-a24043c35937>,
 <CollectionClient id=0d2133c5-b0bb-5ce2-b000-243ade6a65b8>,
 <CollectionClient id=5ff2bf3e-a8da-5aa5-81d2-f801ae6454af>,
 <CollectionClient id=4ca68be3-d205-5dea-a292-6f0a7ab35595>,
 <CollectionClient id=e6a9631e-b7cf-5b3e-b414-1600379a72b3>,
 <CollectionClient id=2a1c3522-f4a0-5d63-9d47-7af06a220302>,
 <CollectionClient id=e4d01e03-0ef5-5b4c-b40f-2b5f49667f53>,
 <CollectionClient id=8dc47b68-6cad-59ce-836f-7328372de417>,
 <CollectionClient id=1589db19-32b2-5945-ad4b-6c3b13713176>,
 <CollectionClient id=a59746f5-d93d-5637-b7fa-6e6220196104>,
 <CollectionClient id=8111e456-a0ff-588f-9ab6-9ef66d8df94a>]
# Display shortened version of the catalog/collection tree structure.
# print_catalog_as_tree( api, max_level=3, max_children=3 )

Collection properties#

Collection identification#

URL = URL_LANDING_PAGE + 'collections/' + 'TropForest'
# URL = URL_LANDING_PAGE + 'collections/' + COLLECTION_ID1
curl -X GET -G https://eocat.esa.int/eo-catalogue/collections/TropForest
response = requests.get(URL)
data = json.loads(response.text)
jstr = json.dumps(data, indent=3)
md("```json\n" + jstr + "\n```\n")
{
   "extent": {
      "spatial": {
         "bbox": [
            [
               -100,
               -50,
               160,
               40
            ]
         ]
      },
      "temporal": {
         "interval": [
            [
               "2009-01-27T00:00:00.000Z",
               "2011-08-09T23:59:59.999Z"
            ]
         ]
      }
   },
   "stac_version": "1.0.0",
   "sci:doi": "10.5270/esa-qoe849q",
   "keywords": [
      "South East Asia",
      "South America",
      "Multi-mission collection",
      "JRC",
      "Food and Agriculture Organization (FAO)",
      "Agriculture",
      "Forestry",
      "Land Surface",
      "Vegetation",
      "EARTH SCIENCE > AGRICULTURE",
      "EARTH SCIENCE > BIOSPHERE > ECOSYSTEMS > TERRESTRIAL ECOSYSTEMS > FORESTS",
      "EARTH SCIENCE > LAND SURFACE",
      "EARTH SCIENCE > BIOSPHERE > VEGETATION",
      "VIS (0.40 - 0.75 \u00b5m)",
      "NIR (0.75 - 1.30 \u00b5m)",
      "Sun-synchronous",
      "Very High Resolution - VHR (0 - 5m)",
      "High Resolution - HR (5 - 20 m)",
      "AL1_AV2_2F",
      "DE1_SL6_2F",
      "KO2_MSC_2F",
      "DE1 663 km;  KO2 685 km; AL1 692 km",
      "DE1 625 km; KO2 15 km; AL1 70 km",
      "Imaging Spectrometers/Radiometers",
      "Cameras",
      "ALOS-1",
      "GEOSAT-1",
      "KOMPSAT-2",
      "AVNIR-2",
      "SLIM6",
      "MSC"
   ],
   "description": "The objective of the ESA TropForest project was to create a harmonised geo-database of ready-to-use satellite imagery to support 2010 global forest assessment performed by the Joint Research Centre (JRC) of the European Commission and by the Food and Agriculture Organization (FAO). Assessments for year 2010 were essential for building realistic deforestation benchmark rates at global to regional levels. To reach this objective, the project aimed to create a harmonised ortho-rectified/pre-processed imagery geo-database based on satellite data acquisitions (ALOS AVNIR-2, GEOSAT-1 SLIM6, KOMPSAT-2 MSC) performed during year 2009 and 2010, for the Tropical Latin America (excluding Mexico) and for the Tropical South and Southeast Asia (excluding China), resulting in 1971 sites located at 1 deg x 1 deg geographical lat/long intersections. The project finally delivered 1866 sites (94.7% of target) due to cloud coverages too high for missing sites",
   "type": "Collection",
   "title": "TropForest- ALOS, GEOSAT-1 &amp; KOMPSAT-2 optical coverages over tropical forests",
   "license": "various",
   "assets": {
      "search": {
         "roles": [
            "search"
         ],
         "href": "https://fedeo-client.ceos.org?url=https://eocat.esa.int/eo-catalogue/api?httpAccept=application/opensearchdescription%252Bxml&uid=TropForest",
         "type": "text/html",
         "title": "Search client"
      },
      "metadata_ogc_17_069r3": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest",
         "type": "application/geo+json;profile=\"http://www.opengis.net/spec/ogcapi-features-1/1.0\"",
         "title": "OGC 17-069r3 metadata"
      },
      "metadata_iso_19139": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/vnd.iso.19139%2Bxml",
         "title": "ISO 19139 metadata",
         "type": "application/vnd.iso.19139+xml"
      },
      "metadata_iso_19139_2": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/vnd.iso.19139-2%2Bxml",
         "title": "ISO 19139-2 metadata",
         "type": "application/vnd.iso.19139-2+xml"
      },
      "metadata_dif_10": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/dif10%2Bxml",
         "title": "DIF-10 metadata",
         "type": "application/dif10+xml"
      },
      "metadata_iso_19115_3": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/vnd.iso.19115-3%2Bxml",
         "title": "ISO 19115-3 metadata",
         "type": "application/vnd.iso.19115-3+xml"
      },
      "metadata_ogc_17_084r1": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?mode=owc",
         "title": "OGC 17-084r1 metadata",
         "type": "application/geo+json;profile=\"http://www.opengis.net/spec/eoc-geojson/1.0\""
      },
      "metadata_html": {
         "roles": [
            "metadata"
         ],
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=text/html",
         "title": "HTML",
         "type": "text/html"
      }
   },
   "links": [
      {
         "rel": "self",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest",
         "type": "application/json"
      },
      {
         "rel": "root",
         "href": "https://eocat.esa.int/eo-catalogue",
         "type": "application/json",
         "title": "ESA Catalog"
      },
      {
         "rel": "parent",
         "href": "https://eocat.esa.int/eo-catalogue",
         "title": "collections",
         "type": "application/json"
      },
      {
         "rel": "items",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest/items?httpAccept=application/geo%2Bjson;profile=https://stacspec.org",
         "type": "application/geo+json",
         "title": "Datasets search for the series TropForest"
      },
      {
         "rel": "http://www.opengis.net/def/rel/ogc/1.0/queryables",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest/queryables",
         "type": "application/schema+json",
         "title": "Queryables for TropForest"
      },
      {
         "rel": "search",
         "href": "https://eocat.esa.int/eo-catalogue/collections/series/items/TropForest/api",
         "type": "application/opensearchdescription+xml",
         "title": "OpenSearch Description Document"
      },
      {
         "rel": "describedby",
         "href": "http://due.esrin.esa.int/page_project134.php",
         "type": "text/html",
         "title": "More about TropForest - Other"
      },
      {
         "rel": "describedby",
         "href": "https://earth.esa.int/eogateway/documents/20142/1488753/ALOS_Deimos_Kompsat_TropForest_joined_2.jpg",
         "title": "Available products in TropForest dataset map - Available products in TropForest dataset (dark green, light green and blue circles)"
      },
      {
         "rel": "describedby",
         "href": "https://esatellus.service-now.com/csp?id=esa_simple_request&sys_id=f27b38f9dbdffe40e3cedb11ce961958",
         "type": "text/html",
         "title": "Get Help? - ESA Earth Observation User Services Portal"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/atom%2Bxml",
         "type": "application/atom+xml",
         "title": "Atom format"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest",
         "type": "application/geo+json;profile=\"http://www.opengis.net/spec/ogcapi-features-1/1.0\"",
         "title": "OGC 17-069r3 metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/vnd.iso.19139%2Bxml",
         "type": "application/vnd.iso.19139+xml",
         "title": "ISO 19139 metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/vnd.iso.19139-2%2Bxml",
         "type": "application/vnd.iso.19139-2+xml",
         "title": "ISO 19139-2 metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/vnd.iso.19115-3%2Bxml",
         "type": "application/vnd.iso.19115-3+xml",
         "title": "ISO 19115-3 metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/dif10%2Bxml",
         "type": "application/dif10+xml",
         "title": "DIF-10 metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/xml",
         "type": "application/xml",
         "title": "Dublin Core metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/json",
         "type": "application/json",
         "title": "STAC metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/ld%2Bjson",
         "type": "application/ld+json",
         "title": "JSON-LD metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/ld%2Bjson;profile=https://schema.org",
         "type": "application/ld+json;profile=\"https://schema.org\"",
         "title": "JSON-LD (schema.org) metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/ld%2Bjson;profile=http://data.europa.eu/930/",
         "type": "application/ld+json;profile=\"http://data.europa.eu/930/\"",
         "title": "JSON-LD (GeoDCAT-AP) metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/rdf%2Bxml",
         "type": "application/rdf+xml",
         "title": "RDF/XML metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/rdf%2Bxml;profile=https://schema.org",
         "type": "application/rdf+xml;profile=\"https://schema.org\"",
         "title": "RDF/XML (schema.org) metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=application/rdf%2Bxml;profile=http://data.europa.eu/930/",
         "type": "application/rdf+xml;profile=\"http://data.europa.eu/930/\"",
         "title": "RDF/XML (GeoDCAT-AP) metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=text/turtle",
         "type": "text/turtle",
         "title": "Turtle metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=text/turtle;profile=https://schema.org",
         "type": "text/turtle;profile=\"https://schema.org\"",
         "title": "Turtle (schema.org) metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=text/turtle;profile=http://data.europa.eu/930/",
         "type": "text/turtle;profile=\"http://data.europa.eu/930/\"",
         "title": "Turtle (GeoDCAT-AP) metadata"
      },
      {
         "rel": "alternate",
         "href": "https://eocat.esa.int/eo-catalogue/collections/TropForest?httpAccept=text/html",
         "type": "text/html",
         "title": "HTML"
      },
      {
         "rel": "cite-as",
         "href": "https://doi.org/10.5270/esa-qoe849q",
         "type": "text/html",
         "title": "Landing page"
      }
   ],
   "id": "TropForest",
   "stac_extensions": [
      "https://stac-extensions.github.io/scientific/v1.0.0/schema.json"
   ],
   "providers": [
      {
         "roles": [
            "producer"
         ],
         "name": "ESA/ESRIN",
         "url": "http://www.esa.int"
      },
      {
         "roles": [
            "host"
         ],
         "name": "ESA Catalog",
         "url": "https://eocat.esa.int/eo-catalogue/readme.html"
      }
   ],
   "summaries": {
      "instruments": [
         "AVNIR-2",
         "SLIM6",
         "MSC"
      ],
      "platform": [
         "ALOS-1",
         "GEOSAT-1",
         "KOMPSAT-2"
      ]
   }
}
# use stac_client class for STAC collection
c = Collection.from_dict(data)
print("id\t\t:", c.id)
print("title\t\t:", c.title)
print("description\t:", c.description)
print("keywords\t:", c.keywords)
print("spatial extent\t:", c.extent.spatial)
print("temporal extent\t:", c.extent.temporal)
# print("providers\t:", c.providers)
# c
id		: TropForest
title		: TropForest- ALOS, GEOSAT-1 &amp; KOMPSAT-2 optical coverages over tropical forests
description	: The objective of the ESA TropForest project was to create a harmonised geo-database of ready-to-use satellite imagery to support 2010 global forest assessment performed by the Joint Research Centre (JRC) of the European Commission and by the Food and Agriculture Organization (FAO). Assessments for year 2010 were essential for building realistic deforestation benchmark rates at global to regional levels. To reach this objective, the project aimed to create a harmonised ortho-rectified/pre-processed imagery geo-database based on satellite data acquisitions (ALOS AVNIR-2, GEOSAT-1 SLIM6, KOMPSAT-2 MSC) performed during year 2009 and 2010, for the Tropical Latin America (excluding Mexico) and for the Tropical South and Southeast Asia (excluding China), resulting in 1971 sites located at 1 deg x 1 deg geographical lat/long intersections. The project finally delivered 1866 sites (94.7% of target) due to cloud coverages too high for missing sites
keywords	: ['South East Asia', 'South America', 'Multi-mission collection', 'JRC', 'Food and Agriculture Organization (FAO)', 'Agriculture', 'Forestry', 'Land Surface', 'Vegetation', 'EARTH SCIENCE > AGRICULTURE', 'EARTH SCIENCE > BIOSPHERE > ECOSYSTEMS > TERRESTRIAL ECOSYSTEMS > FORESTS', 'EARTH SCIENCE > LAND SURFACE', 'EARTH SCIENCE > BIOSPHERE > VEGETATION', 'VIS (0.40 - 0.75 µm)', 'NIR (0.75 - 1.30 µm)', 'Sun-synchronous', 'Very High Resolution - VHR (0 - 5m)', 'High Resolution - HR (5 - 20 m)', 'AL1_AV2_2F', 'DE1_SL6_2F', 'KO2_MSC_2F', 'DE1 663 km;  KO2 685 km; AL1 692 km', 'DE1 625 km; KO2 15 km; AL1 70 km', 'Imaging Spectrometers/Radiometers', 'Cameras', 'ALOS-1', 'GEOSAT-1', 'KOMPSAT-2', 'AVNIR-2', 'SLIM6', 'MSC']
spatial extent	: <pystac.collection.SpatialExtent object at 0x7f20cf0b7590>
temporal extent	: <pystac.collection.TemporalExtent object at 0x7f20cf05a710>

The collection id (id) is to be used as collections parameter for a corresponding STAC item (granule) search. It can also be used in the ids parameter when searching collections by identifier.

Collection DOI#

Not all collections have a digital object identifier assigned. if they do, then it is available as sci:doi property. This value can be used for searching collections by DOI. Collections with DOI, typically also contain a link with rel=”cite-as” referring to their landing page.

try: 
    print(data['sci:doi'])
except:
    print("Not available")
10.5270/esa-qoe849q

Collection geometry#

Geometry information for a collection is included in the JSON response at the path $.extent.spatial.

data['extent']['spatial']
{'bbox': [[-100, -50, 160, 40]]}

Collection temporal extent#

The JSON response element provides temporal information for a collection, i.e. the start time and end time at the path $.extent.temporal. The end time may be absent indicating that the collection is not completed.

try: 
    print(data['extent']['temporal'])
except:
    print("Not available")
{'interval': [['2009-01-27T00:00:00.000Z', '2011-08-09T23:59:59.999Z']]}

Collection assets#

Collections provide access to a dictionary with assets. The roles attribute indicates the purpose of the asset. The href attribute provides the URL to access the asset. Collection assets may include thumbnail (when available), search interfaces, and various metadata formats.

The table below list some frequently used metadata formats and their corresponding media type (type).

Format

type

ISO19139

application/vnd.iso.19139+xml

ISO19139-2

application/vnd.iso.19139-2+xml

ISO19115-3

application/vnd.iso.19115-3+xml

ISO19157-2

application/vnd.iso.19157-2+xml

URL = URL_LANDING_PAGE + 'collections/' + COLLECTION_ID1
response = requests.get(URL)
data = json.loads(response.text)

# Show assets of the collection (GeoJSON)
jstr = json.dumps(data['assets'], indent=3)
md("```json\n" + jstr + "\n```\n")
{
   "search": {
      "roles": [
         "search"
      ],
      "href": "https://fedeo-client.ceos.org?url=https://eocat.esa.int/eo-catalogue/api?httpAccept=application/opensearchdescription%252Bxml&uid=PROBA.CHRIS.1A",
      "type": "text/html",
      "title": "Search client"
   },
   "metadata_ogc_17_069r3": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A",
      "type": "application/geo+json;profile=\"http://www.opengis.net/spec/ogcapi-features-1/1.0\"",
      "title": "OGC 17-069r3 metadata"
   },
   "metadata_iso_19139": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A?httpAccept=application/vnd.iso.19139%2Bxml",
      "title": "ISO 19139 metadata",
      "type": "application/vnd.iso.19139+xml"
   },
   "metadata_iso_19139_2": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A?httpAccept=application/vnd.iso.19139-2%2Bxml",
      "title": "ISO 19139-2 metadata",
      "type": "application/vnd.iso.19139-2+xml"
   },
   "metadata_dif_10": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A?httpAccept=application/dif10%2Bxml",
      "title": "DIF-10 metadata",
      "type": "application/dif10+xml"
   },
   "metadata_iso_19115_3": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A?httpAccept=application/vnd.iso.19115-3%2Bxml",
      "title": "ISO 19115-3 metadata",
      "type": "application/vnd.iso.19115-3+xml"
   },
   "metadata_ogc_17_084r1": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A?mode=owc",
      "title": "OGC 17-084r1 metadata",
      "type": "application/geo+json;profile=\"http://www.opengis.net/spec/eoc-geojson/1.0\""
   },
   "metadata_html": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A?httpAccept=text/html",
      "title": "HTML",
      "type": "text/html"
   }
}
# Display assets belonging to the collection
c = Collection.from_dict(data)
assets = c.assets
df = pd.DataFrame(columns=['roles', 'title', 'type'])
for key in assets:
    ndf = pd.DataFrame({ 
            'roles': assets[key].roles, 
            'type': assets[key].media_type, 
            'title': assets[key].title, 
            # 'href': assets[key].href  
        }, index = [0])
    df = pd.concat([df, ndf], ignore_index=True)
df
roles title type
0 search Search client text/html
1 metadata OGC 17-069r3 metadata application/geo+json;profile="http://www.openg...
2 metadata ISO 19139 metadata application/vnd.iso.19139+xml
3 metadata ISO 19139-2 metadata application/vnd.iso.19139-2+xml
4 metadata DIF-10 metadata application/dif10+xml
5 metadata ISO 19115-3 metadata application/vnd.iso.19115-3+xml
6 metadata OGC 17-084r1 metadata application/geo+json;profile="http://www.openg...
7 metadata HTML text/html

Granule properties#

Granules are returned via item links in the Catalog or Collection objects, or via the STAC API (Feature). An item is a GeoJSON Feature and the encoding is derived from the original OGC 17-003r2 encoding according to a documented mapping.

The properties available include attributes from STAC extensions as well:

Assets#

Granules provide access to a dictionary with assets. The roles attribute indicates the purpose of the asset. The href attribute provides the URL to access the asset. Granule assets include thumbnail (when available), a data download link (equivalent to the rel=enclosure), and various metadata formats.

The table below list some frequently used metadata formats and their corresponding media type (type).

Format

type

ISO19139

application/vnd.iso.19139+xml

ISO19139-2

application/vnd.iso.19139-2+xml

ISO19115-3

application/vnd.iso.19115-3+xml

OGC 10-157r4

application/gml+xml;profile=http://www.opengis.net/spec/EOMPOM/1.1

OGC 17-003r2

application/geo+json;profile=http://www.opengis.net/spec/eo-geojson/1.0

# Show assets of first search result (GeoJSON)
data = results.get_all_items_as_dict()
jstr = json.dumps(data['features'][1]['assets'], indent=3)
md("```json\n" + jstr + "\n```\n")
{
   "thumbnail": {
      "roles": [
         "thumbnail"
      ],
      "href": "http://landsat-diss.eo.esa.int/oads/meta/LandsatETM/browse/L07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078_v0100.SIP.ZIP_BID.PNG",
      "type": "image/png",
      "title": "QUICKLOOK"
   },
   "metadata_ogc_10_157r3": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/LANDSAT.ETM.GTC/items/LS07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078?httpAccept=application/gml%2Bxml&recordSchema=om10",
      "title": "OGC 10-157r3 metadata",
      "type": "application/gml+xml;profile=\"http://www.opengis.net/spec/EOMPOM/1.0\""
   },
   "enclosure": {
      "roles": [
         "data"
      ],
      "href": "https://landsat-diss.eo.esa.int/oads/data/LandsatETM/L07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078_v0100.SIP.ZIP",
      "type": "application/x-binary",
      "title": "Download"
   },
   "metadata_ogc_10_157r4": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/LANDSAT.ETM.GTC/items/LS07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078?httpAccept=application/gml%2Bxml&recordSchema=om",
      "title": "OGC 10-157r4 metadata",
      "type": "application/gml+xml;profile=\"http://www.opengis.net/spec/EOMPOM/1.1\""
   },
   "metadata_ogc_17_069r3": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/LANDSAT.ETM.GTC/items/LS07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078",
      "type": "application/geo+json;profile=\"http://www.opengis.net/spec/ogcapi-features-1/1.0\"",
      "title": "OGC 17-069r3 metadata"
   },
   "metadata_ogc_17_003r2": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/LANDSAT.ETM.GTC/items/LS07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078?mode=owc",
      "title": "OGC 17-003r2 metadata",
      "type": "application/geo+json;profile=\"http://www.opengis.net/spec/eo-geojson/1.0\""
   },
   "metadata_iso_19139": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/LANDSAT.ETM.GTC/items/LS07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078?httpAccept=application/vnd.iso.19139%2Bxml",
      "title": "ISO 19139 metadata",
      "type": "application/vnd.iso.19139+xml"
   },
   "metadata_html": {
      "roles": [
         "metadata"
      ],
      "href": "https://eocat.esa.int/eo-catalogue/collections/LANDSAT.ETM.GTC/items/LS07_RFUI_ETM_GTC_1P_19990731T093427_19990731T093456_001555_0189_0033_9078?httpAccept=text/html",
      "title": "HTML",
      "type": "text/html"
   }
}
df = pd.DataFrame(columns=['roles', 'title', 'type'])
    
# Display assets belonging to first item in results
for item in results.items():
    assets = item.assets
    for key in assets:     
        ndf = pd.DataFrame({ 
            'roles': assets[key].roles, 
            'type': assets[key].media_type, 
            'title': assets[key].title, 
            # 'href': assets[key].href  
        }, index = [0])
        df = pd.concat([df, ndf], ignore_index=True)
    
    break
df
roles title type
0 thumbnail QUICKLOOK image/png
1 metadata OGC 10-157r3 metadata application/gml+xml;profile="http://www.opengi...
2 data Download application/x-binary
3 metadata OGC 10-157r4 metadata application/gml+xml;profile="http://www.opengi...
4 metadata OGC 17-069r3 metadata application/geo+json;profile="http://www.openg...
5 metadata OGC 17-003r2 metadata application/geo+json;profile="http://www.openg...
6 metadata ISO 19139 metadata application/vnd.iso.19139+xml
7 metadata HTML text/html

Advanced topics#

Conformance classes#

The conformance classes supported by the STAC interface are advertised in the conformsTo property of the landing page.

[
   "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core",
   "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30",
   "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson",
   "http://www.opengis.net/spec/ogcapi_common-2/1.0/conf/collections",
   "http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/simple-query",
   "http://www.opengis.net/spec/ogcapi-records-1/1.0/req/cql-filter",
   "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson",
   "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter",
   "https://api.stacspec.org/v1.0.0-rc.2/core",
   "https://api.stacspec.org/v1.0.0-rc.2/stac-search",
   "https://api.stacspec.org/v1.0.0-rc.2/stac-response",
   "https://api.stacspec.org/v1.0.0-rc.2/collection-search",
   "https://api.stacspec.org/v1.0.0-rc.2/collection-search#filter",
   "https://api.stacspec.org/v1.0.0-rc.1/collection-search#free-text",
   "https://api.stacspec.org/v1.0.0-rc.2/item-search",
   "https://api.stacspec.org/v1.0.0-rc.2/item-search#filter",
   "http://www.opengis.net/spec/cql2/1.0/conf/cql2-text",
   "http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2"
]

Additional search parameters#

Additional search parameters beyond the STAC search parameters can be used to filter collection search results. The available parameters for collection search are advertised at https://eocat.esa.int/eo-catalogue/collections/queryables and represented as a JSON Schema.

URL_QUERYABLES = URL_LANDING_PAGE + 'collections/queryables'
curl -X GET -G https://eocat.esa.int/eo-catalogue/collections/queryables
response = requests.get(URL_QUERYABLES)   
data = json.loads(response.text)    
df = pd.DataFrame(data['properties'].items(),columns=['key','value'])
df['type'] = df.apply(lambda row : row[1]['type'], axis = 1)
df['format'] = df.apply(lambda row : row[1]['format'] if 'format' in row[1] else '-' , axis = 1)
df.drop('value',axis=1).sort_values(by=['key'])
/tmp/ipykernel_367/2988820384.py:4: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  df['type'] = df.apply(lambda row : row[1]['type'], axis = 1)
/tmp/ipykernel_367/2988820384.py:5: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  df['format'] = df.apply(lambda row : row[1]['format'] if 'format' in row[1] else '-' , axis = 1)
key type format
15 classifiedAs string uri
14 doi string -
3 externalId string -
4 instrument string -
9 modificationDate string date-time
12 offering string -
8 organisationName string -
6 otherConstraint string -
2 parentIdentifier string -
7 platform string -
10 processingLevel string -
13 publisher string -
1 query string -
0 subject string -
5 title string -
11 useLimitation string -
{
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "description": "Queryable names for the STAC API Collection Search filter.",
   "type": "object",
   "title": "Queryables for the STAC API",
   "properties": {
      "subject": {
         "description": "{dc:subject}",
         "title": "Subject",
         "type": "string"
      },
      "query": {
         "description": "{os:searchTerms}",
         "title": "Query",
         "type": "string"
      },
      "parentIdentifier": {
         "description": "{eo:parentIdentifier}",
         "title": "Parent identifier",
         "type": "string"
      },
      "externalId": {
         "description": "Search by external identifier {API Records}",
         "title": "External identifiers",
         "type": "string"
      },
      "instrument": {
         "description": "{eo:instrument}",
         "title": "Instrument",
         "type": "string",
         "enum": [
            "AATSR",
            "ACC",
            "ACE-FTS",
            "ACGS",
            "AIRSAFE",
            "ALADIN",
            "AMI/SAR",
            "AMI/Scatterometer",
            "ASAR",
            "ASM",
            "ATSR-1",
            "ATSR-2",
            "AVHRR",
            "AVNIR-2",
            "AwiFS",
            "BGI",
            "CAPI",
            "CHRIS",
            "CSG-SAR",
            "DORIS",
            "EFI",
            "EGG",
            "EOC",
            "ETM",
            "GIS",
            "GOME",
            "GOMOS",
            "GPSR",
            "GRACE ACC",
            "GRACE INTERFEROMETER",
            "GRACE LRR",
            "GRACE SCA",
            "HRC",
            "HRG",
            "HRS",
            "HRV",
            "HRVIR",
            "HiRAIS",
            "HiRI",
            "HyperScout-2",
            "KBR",
            "LISS-3",
            "LISS-4",
            "LRR",
            "MAESTRO",
            "MERIS",
            "MESSR",
            "MGM",
            "MIPAS",
            "MIRAS",
            "MODIS",
            "MSC",
            "MSI",
            "MSS",
            "MWR",
            "NAOMI",
            "OCM-2",
            "OLI",
            "OMI",
            "OPS",
            "OSA",
            "OSIRIS",
            "P-SAR",
            "PALSAR",
            "PAN",
            "PAZ-SAR",
            "PNEO",
            "PRARE",
            "PRISM",
            "PlanetScope Camera",
            "RA",
            "RA-2",
            "RBV",
            "SAOCOM-SAR",
            "SAR",
            "SCIAMACHY",
            "SENSE",
            "SIRAL",
            "SLIM6",
            "SMR",
            "SSTI",
            "SSTL S1-4",
            "STR",
            "STRATOS",
            "SeaWiFS",
            "SeaWinds",
            "SkySat Camera",
            "SpaceView-110",
            "TANSO-CAI",
            "TANSO-CAI-2",
            "TANSO-FTS",
            "TANSO-FTS-2",
            "TDX-1",
            "TIRS",
            "TM",
            "TSX-1",
            "VFM",
            "VGT",
            "VTIR",
            "WAF-P",
            "WV110",
            "WV60",
            "X-SAR"
         ]
      },
      "title": {
         "description": "{dc:title}",
         "title": "Title",
         "type": "string"
      },
      "otherConstraint": {
         "description": "{eo:otherConstraint}",
         "title": "Other constraint",
         "type": "string"
      },
      "platform": {
         "description": "{eo:platform}",
         "title": "Platform",
         "type": "string",
         "enum": [
            "ALOS-1",
            "AQUA",
            "Aeolus",
            "Aura",
            "Beijing-1",
            "Biomass",
            "COSMO-SkyMed Second Generation",
            "COSMO-SkyMed",
            "CryoSat-2",
            "ERS-1",
            "ERS-2",
            "Envisat",
            "FFSCat",
            "GEOSAT-1",
            "GEOSAT-2",
            "GHGSat-C1",
            "GHGSat-C2",
            "GOCE",
            "GOSAT-1",
            "GOSAT-2",
            "GRACE",
            "GeoEye-1",
            "ICEYE",
            "IKONOS-2",
            "IRS-1C",
            "IRS-1D",
            "IRS-P5",
            "IRS-P6",
            "IRS-R2",
            "JERS-1",
            "KOMPSAT-1",
            "KOMPSAT-2",
            "Landsat-1",
            "Landsat-2",
            "Landsat-3",
            "Landsat-4",
            "Landsat-5",
            "Landsat-7",
            "Landsat-8",
            "MOS-1",
            "MOS-1B",
            "Metop",
            "NOAA POES",
            "NigeriaSat-1",
            "ODIN",
            "OceanSat-2",
            "OrbView-2",
            "PAZ",
            "PROBA-1",
            "PROBA-V",
            "PlanetScope",
            "Pleiades Neo",
            "Pleiades",
            "Pleiades-1A",
            "Pleiades-1B",
            "QuickBird-2",
            "QuikSCAT",
            "RADARSAT-1",
            "RADARSAT-2",
            "RapidEye",
            "SAOCOM-1A",
            "SAOCOM-1B",
            "SCISAT-1",
            "SMOS",
            "SPOT 1",
            "SPOT 2",
            "SPOT 3",
            "SPOT 4",
            "SPOT 5",
            "SPOT 6",
            "SPOT 7",
            "Seasat",
            "SkySat",
            "Spire",
            "Swarm",
            "TERRA",
            "TanDEM-X",
            "TanSat",
            "TerraSAR-X",
            "UK-DMC-1",
            "Vision-1",
            "WorldView-1",
            "WorldView-2",
            "WorldView-3",
            "WorldView-4"
         ]
      },
      "organisationName": {
         "description": "{eo:organisationName}",
         "title": "Organisation name",
         "type": "string",
         "enum": [
            "ESA/ESRIN"
         ]
      },
      "modificationDate": {
         "format": "date-time",
         "description": "{eo:modificationDate}",
         "title": "Modification date",
         "type": "string"
      },
      "processingLevel": {
         "description": "{eo:processingLevel}",
         "title": "Processing level",
         "type": "string",
         "enum": [
            "level 0",
            "level 1",
            "level 1.5",
            "level 1a",
            "level 1b",
            "level 1b+",
            "level 1c",
            "level 1d",
            "level 1g",
            "level 1gt",
            "level 1r",
            "level 1t",
            "level 2",
            "level 2a",
            "level 2b",
            "level 2c",
            "level 3",
            "level 3a",
            "level 3b",
            "level 4",
            "level-a",
            "level-a+",
            "multiple"
         ]
      },
      "useLimitation": {
         "description": "{eo:useLimitation}",
         "title": "Use limitation",
         "type": "string",
         "enum": [
            "data service request",
            "eo sign in authentication (open)",
            "eo sign in authentication",
            "external data",
            "fast registration with approval",
            "fast registration with immediate access",
            "open access",
            "project proposal (restrained)",
            "project proposal",
            "restrained data"
         ]
      },
      "offering": {
         "description": "{eo:offering}",
         "title": "Offering",
         "type": "string"
      },
      "publisher": {
         "description": "{dc:publisher}",
         "title": "Publisher",
         "type": "string"
      },
      "doi": {
         "description": "{eo:doi}",
         "title": "Doi",
         "type": "string"
      },
      "classifiedAs": {
         "format": "uri",
         "description": "{semantic:classifiedAs}",
         "title": "Classified as",
         "type": "string"
      }
   },
   "$id": "https://eocat.esa.int/eo-catalogue/collections/queryables"
}

Additional search parameters beyond the STAC search parameters can be used to filter granule search results. The available parameters for granule search are advertised for each individual collection and represented as a JSON Schema.

For example, the collection PROBA.CHRIS.1A, advertises its search parameters at https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A/queryables in JSON Schema format. Therefore, the following parameters can be used within a filter expression.

Get filter parameters for granule search

curl -X GET -G https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A/queryables
/tmp/ipykernel_367/3178706419.py:4: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  df['type'] = df.apply(lambda row : row[1]['type'], axis = 1)
/tmp/ipykernel_367/3178706419.py:5: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  df['format'] = df.apply(lambda row : row[1]['format'] if 'format' in row[1] else '-' , axis = 1)
key type format
0 acquisitionType string -
2 externalId string -
14 frame string -
1 illuminationAzimuthAngle number -
12 illuminationElevationAngle number -
3 instrument string -
9 offering string -
5 orbitNumber integer -
4 platform string -
6 platformSerialIdentifier string -
13 productType string -
8 productionStatus string -
7 q string -
11 sensorMode string -
10 track string -
{
   "$schema": "https://json-schema.org/draft/2019-09/schema",
   "description": "Queryable names for the STAC API Item Search filter.",
   "type": "object",
   "title": "Queryables for PROBA.CHRIS.1A collection",
   "properties": {
      "acquisitionType": {
         "description": "{eo:acquisitionType}",
         "title": "Acquisition type",
         "type": "string",
         "enum": [
            "NOMINAL"
         ]
      },
      "illuminationAzimuthAngle": {
         "description": "{eo:illuminationAzimuthAngle}",
         "maximum": 360,
         "title": "Illumination azimuth angle",
         "type": "number",
         "minimum": 0
      },
      "externalId": {
         "description": "Search by external identifier {API Records}",
         "title": "External identifiers",
         "type": "string"
      },
      "instrument": {
         "description": "{eo:instrument}",
         "title": "Instrument",
         "type": "string",
         "enum": [
            "CHRIS"
         ]
      },
      "platform": {
         "description": "{eo:platform}",
         "title": "Platform",
         "type": "string",
         "enum": [
            "PROBA"
         ]
      },
      "orbitNumber": {
         "description": "{eo:orbitNumber}",
         "title": "Orbit number",
         "type": "integer"
      },
      "platformSerialIdentifier": {
         "description": "{eo:platformSerialIdentifier}",
         "title": "Platform serial identifier",
         "type": "string"
      },
      "q": {
         "description": "Free text search {API Records}",
         "title": "API Records Query",
         "type": "string"
      },
      "productionStatus": {
         "description": "{eo:productionStatus}",
         "title": "Production status",
         "type": "string",
         "enum": [
            "ARCHIVED"
         ]
      },
      "offering": {
         "description": "{eo:offering}",
         "title": "Offering",
         "type": "string"
      },
      "track": {
         "description": "{eo:track}",
         "title": "Track",
         "type": "string"
      },
      "sensorMode": {
         "description": "{eo:sensorMode}",
         "title": "Sensor mode",
         "type": "string"
      },
      "illuminationElevationAngle": {
         "description": "{eo:illuminationElevationAngle}",
         "maximum": 180,
         "title": "Illumination elevation angle",
         "type": "number",
         "minimum": 0
      },
      "productType": {
         "description": "{eo:productType}",
         "title": "Product type",
         "type": "string",
         "enum": [
            "CHR_MO3_1P",
            "CHR_MO4_1P",
            "CHR_MO5_1P",
            "CHR_MO1_1P",
            "CHR_MO2_1P"
         ]
      },
      "frame": {
         "description": "{eo:frame}",
         "title": "Frame",
         "type": "string"
      }
   },
   "$id": "https://eocat.esa.int/eo-catalogue/collections/PROBA.CHRIS.1A/queryables"
}

CQL filter expressions#

The STAC interface supports the filter parameter and filter expressions in cql-text filter format at the following endpoints:

  • /collections

  • /collections/{collection-id}/items

  • /search

At the /search endpoint, it is required that a single collection can be determined from the collections or ids parameter. The queryables allowed in the filter expression are then identical to the ones at the corresponding /collections/{collection-id}/items/queryables endpoint. filter cannot be used at the /search endpoint when collections contains 0 or more than 1 collection identifiers.

Filter expressions are to be expressed with the Text encoding of the Basic Common Query Language (Basic CQL2-Text) [RD22]. See the OGC API Features “Conformance class Filter” section for CQL2 examples.

Example: 8.1

CQL Filter for collection search with logical operators (and, or).

filter = "platform = 'Envisat' and ( instrument = 'MERIS' or instrument = 'MIPAS' ) and organisationName = 'ESA/ESRIN'"
params = { 'filter': filter } 
URL = f'{URL_LANDING_PAGE}collections?{urllib.parse.urlencode(params)}'
curl -X GET -G https://eocat.esa.int/eo-catalogue/collections \
	--data-urlencode "filter=platform = 'Envisat' and ( instrument = 'MERIS' or instrument = 'MIPAS' ) and organisationName = 'ESA/ESRIN'"
response = requests.get(URL)
data = json.loads(response.text)
df = pd.json_normalize(data, record_path=['collections'])
df[['id', 'title']]
id title
0 MER_FRS_1P Envisat MERIS Full Resolution - Level 1 [MER_F...
1 MER.RR__2P Envisat MERIS Reduced Resolution Geophysical P...
2 ENVISAT.MIP.NL__1P Envisat MIPAS L1 - Geo-located and calibrated ...
3 MER_FRS_2P Envisat MERIS Full Resolution - Level 2 [MER_F...
4 ENVISAT.MIP.NL__2P Envisat MIPAS L2 - Temperature, pressure and a...
5 MER.RR__1P Envisat MERIS Reduced Resolution - Level 1 [ME...

Example: 8.2

CQL filter for granule search with comparison operators. Search granules with cloudCover between 10 and 15%.

from pystac_client import Client 
api = Client.open(URL_LANDING_PAGE)  

results = api.search(
    method = 'GET',   
    max_items = 30,
    collections = [COLLECTION_ID3_CLOUDS],
    filter = "cloudCover >= 10 and cloudCover < 15"   
)
curl -X GET -G https://eocat.esa.int/eo-catalogue/search \
	--data-urlencode "limit=30" \
	--data-urlencode "collections=IKONOS.ESA.archive" \
	--data-urlencode "filter=cloudCover >= 10 and cloudCover < 15" \
	--data-urlencode "filter-lang=cql2-text"
print(f"{results.matched()} items found.")
26 items found.
# Display cloud-cover values as histogram to show that range is taken into account
stac_json = results.get_all_items_as_dict()
gdf = gpd.GeoDataFrame.from_features(stac_json)
try:
  _ = gdf[['title','eo:cloud_cover']].hist()
except:
  print("eo:cloud_cover information is not available.")
_images/710e655ef03e60b23e4482584034da0650a34f579341c264a8781fa034dc3287.png

Further Reading#

ID

Title

RD11

STAC API - Item Search

RD12

STAC API - Filter Extension

RD13

STAC Catalog Specification

RD14

STAC Collection Specification

RD15

STAC API Specification

RD16

STAC Item Specification

RD17

PySTAC Documentation

RD18

PySTAC Client Usage

RD19

ODC STAC - Plot STAC Items on a map

RD20

OGC17-069r3, OGC API - Features - Part 1: Core

RD21

OGC17-079r1, OGC API - Features - Part 3: Filtering

RD22

OGC21-065, Common Query Language (CQL2)

RD23

RFC 7946 - The GeoJSON Format

RD24

JSON Schema: A Media Type for Describing JSON Documents, draft-handrews-json-schema-02

RD25

STAC API - Collection Search

RD27

Intake-STAC Documentation