diff --git a/book/opensearch_6_idn.ipynb b/book/opensearch_6_idn.ipynb index a550e94..f7141a8 100644 --- a/book/opensearch_6_idn.ipynb +++ b/book/opensearch_6_idn.ipynb @@ -6,6 +6,7 @@ "id": "d99fea47", "metadata": {}, "source": [ + "(chapter-idn)=\n", "# Use Case - Collection Search (IDN)\n", "\n", "This chapter provides a comprehensive and detailed process about how to implement a WGISS\n", @@ -15,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": null, "id": "90481aae", "metadata": { "tags": [ @@ -38,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": null, "id": "1942bb9c", "metadata": { "tags": [ @@ -117,10 +118,11 @@ "id": "766f19de", "metadata": {}, "source": [ + "(section_Retrieve_Collections_via_IDN_OpenSearch)=\n", "## Retrieve Collections via IDN OpenSearch\n", "\n", "CEOS OpenSearch supports searching for collections through the IDN. Searching for granules in a specific collection is supported at the data partners via the Granule Gateways (see chapter\n", - "“CWIC” and chapter “FedEO”). It executes a collection or inventory search, as appropriate, and returns the matching results. In order to create a valid request, clients have to obtain the IDN OpenSearch OSDD and fill request\n", + "“CWIC” and chapter [\"FedEO\"](chapter-fedeo)). It executes a collection or inventory search, as appropriate, and returns the matching results. In order to create a valid request, clients have to obtain the IDN OpenSearch OSDD and fill request\n", "parameters with proper values." ] }, @@ -135,7 +137,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": null, "id": "75bcedb3", "metadata": {}, "outputs": [], @@ -153,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": null, "id": "7186f6c8", "metadata": { "tags": [ @@ -161,119 +163,7 @@ "remove-input" ] }, - "outputs": [ - { - "data": { - "text/markdown": [ - "```xml\n", - " \n", - " CMR Collections \n", - " NASA CMR Collection search using geo, time and parameter extensions \n", - " echodev@echo.nasa.gov \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " NASA CMR \n", - " open \n", - " CMR NASA CWIC CEOS-OS-BP-V1.1/L3 ESIP OGC collection pageOffset=1 indexOffset=0 \n", - "\n", - "```\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "response = requests.get( URL_OSDD )\n", "xmlstr = minidom.parseString(response.text).toprettyxml(indent=' ',newl='')\n", @@ -299,21 +189,10 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": null, "id": "4a578ebd", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'https://cmr.earthdata.nasa.gov/opensearch/collections.atom?keyword={os:searchTerms?}&instrument={echo:instrument?}&satellite={eo:platform?}&boundingBox={geo:box?}&lat={geo:lat?}&lon={geo:lon?}&radius={geo:radius?}&geometry={geo:geometry?}&placeName={geo:name?}&startTime={time:start?}&endTime={time:end?}&cursor={os:startPage?}&numberOfResults={os:count?}&offset={os:startIndex?}&uid={geo:uid?}&hasGranules={echo:hasGranules?}&isCwic={echo:isCwic?}&isGeoss={echo:isGeoss?}&isCeos={echo:isCeos?}&isEosdis={echo:isEosdis?}&isFedeo={echo:isFedeo?}&provider={echo:provider?}&clientId=ceosOpenSearchDoc'" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# find URL template for collection search\n", "root = ElementTree.fromstring(response.text)\n", @@ -327,21 +206,10 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": null, "id": "613efbe7", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'https://cmr.earthdata.nasa.gov/opensearch/collections.atom?keyword=Landsat_8&numberOfResults=10&clientId=ceosOpenSearchDoc'" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "request_url = get_api_request(collection_template, {'count': '10', 'searchTerms': 'Landsat_8'})\n", "request_url" @@ -349,105 +217,14 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": null, "id": "4cf78fc4", "metadata": { "tags": [ "output_scroll" ] }, - "outputs": [ - { - "data": { - "text/markdown": [ - "```xml\n", - " \n", - " 2024-12-06T09:53:12.778Z \n", - " https://cmr.earthdata.nasa.gov/opensearch/collections.atom \n", - " \n", - " CMR \n", - " echodev@echo.nasa.gov \n", - " \n", - " ECHO dataset metadata \n", - " Search parameters: keyword => Landsat_8 \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " 1 \n", - " 10 \n", - " 1 \n", - " \n", - " https://cmr.earthdata.nasa.gov/opensearch/collections.atom?uid=C1235542031-USGS_LTA \n", - " \n", - " CMR \n", - " echodev@echo.nasa.gov \n", - " \n", - " CEOS \n", - " CWIC \n", - " Landsat 8 \n", - " The Operational Land Imager (OLI) and Thermal Infrared Sensor (TIRS) are onboard the Landsat 8 satellite, have acquired images of the Earth since February 2013. The sensors collect images of the Earth with a 16-day repeat cycle, referenced to the Worldwide Reference System-2. The approximate scene size is 170 km north-south by 183 km east-west (106 mi by 114 mi).\n", - "\n", - "Landsat 8 image data files consist of 11 spectral bands with a spatial resolution of 30 meters for bands 1-7 and bands 9-11; 15-meters for the panchromatic band 8. Delivered Landsat 8 Level-1 data typically include both OLI and TIRS data files; however, there may be OLI-only and/or TIRS-only scenes in the USGS archive. A Quality Assurance (QA.tif) band is also included. This file provides bit information regarding conditions that may affect the accuracy and usability of a given pixel – clouds, water or snow, for example. \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " C1235542031-USGS_LTA \n", - " 2013-02-11T00:00:00.000Z/ \n", - " Landsat 8 \n", - " Landsat_8 \n", - " Not provided \n", - " Landsat_8 \n", - " USGS_LTA \n", - " DOI/USGS/EROS \n", - " DOI/USGS/EROS \n", - " Not Provided \n", - " CARTESIAN \n", - " \n", - " -82.71 -180 82.74 180 \n", - " false \n", - " false \n", - " false \n", - " false \n", - " false \n", - " false \n", - " false \n", - " 0.97999995 \n", - " \n", - " gov.nasa.eosdis \n", - " \n", - " \n", - " org.geoss.geoss_data-core \n", - " \n", - " \n", - " org.ceos.wgiss.cwic.granules.provider \n", - " "USGSLSI" \n", - " \n", - " \n", - " org.ceos.wgiss.cwic.granules.prod \n", - " " " \n", - " \n", - " true \n", - " true \n", - " \n", - "\n", - "```\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "response = requests.get( request_url )\n", "xmlstr = minidom.parseString(response.text).toprettyxml(indent=' ', newl='')\n", @@ -465,21 +242,10 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": null, "id": "4481ceea", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'https://cmr.earthdata.nasa.gov/opensearch/collections.atom?&numberOfResults=10&uid=C1235542031-USGS_LTA&clientId=ceosOpenSearchDoc'" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "request_url = get_api_request(collection_template, {'count': '10', 'geo:uid': 'C1235542031-USGS_LTA'})\n", "request_url" @@ -487,100 +253,10 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": null, "id": "7caab6c5", "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "```xml\n", - " \n", - " 2024-12-06T09:53:13.788Z \n", - " https://cmr.earthdata.nasa.gov/opensearch/collections.atom \n", - " \n", - " CMR \n", - " echodev@echo.nasa.gov \n", - " \n", - " ECHO dataset metadata \n", - " Search parameters: uid => C1235542031-USGS_LTA \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " 1 \n", - " 10 \n", - " 1 \n", - " \n", - " https://cmr.earthdata.nasa.gov/opensearch/collections.atom?uid=C1235542031-USGS_LTA \n", - " \n", - " CMR \n", - " echodev@echo.nasa.gov \n", - " \n", - " CEOS \n", - " CWIC \n", - " Landsat 8 \n", - " The Operational Land Imager (OLI) and Thermal Infrared Sensor (TIRS) are onboard the Landsat 8 satellite, have acquired images of the Earth since February 2013. The sensors collect images of the Earth with a 16-day repeat cycle, referenced to the Worldwide Reference System-2. The approximate scene size is 170 km north-south by 183 km east-west (106 mi by 114 mi).\n", - "\n", - "Landsat 8 image data files consist of 11 spectral bands with a spatial resolution of 30 meters for bands 1-7 and bands 9-11; 15-meters for the panchromatic band 8. Delivered Landsat 8 Level-1 data typically include both OLI and TIRS data files; however, there may be OLI-only and/or TIRS-only scenes in the USGS archive. A Quality Assurance (QA.tif) band is also included. This file provides bit information regarding conditions that may affect the accuracy and usability of a given pixel – clouds, water or snow, for example. \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " C1235542031-USGS_LTA \n", - " 2013-02-11T00:00:00.000Z/ \n", - " Landsat 8 \n", - " Landsat_8 \n", - " Not provided \n", - " Landsat_8 \n", - " USGS_LTA \n", - " DOI/USGS/EROS \n", - " DOI/USGS/EROS \n", - " Not Provided \n", - " CARTESIAN \n", - " \n", - " -82.71 -180 82.74 180 \n", - " false \n", - " false \n", - " false \n", - " false \n", - " false \n", - " false \n", - " false \n", - " \n", - " gov.nasa.eosdis \n", - " \n", - " \n", - " org.geoss.geoss_data-core \n", - " \n", - " \n", - " org.ceos.wgiss.cwic.granules.provider \n", - " "USGSLSI" \n", - " \n", - " \n", - " org.ceos.wgiss.cwic.granules.prod \n", - " " " \n", - " \n", - " true \n", - " true \n", - " \n", - "\n", - "```\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "response = requests.get( request_url )\n", "xmlstr = minidom.parseString(response.text).toprettyxml(indent=' ', newl='')\n", @@ -598,27 +274,10 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": null, "id": "f1ea492e", "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "```xml\n", - "\n", - " \n", - "```\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "root = ElementTree.fromstring(response.text)\n", "# Extract element with the OSDD for the granule search with Atom response\n", @@ -637,21 +296,10 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": null, "id": "9b2ab19c", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'https://cmr.earthdata.nasa.gov/opensearch/granules/descriptor_document.xml?collectionConceptId=C1235542031-USGS_LTA'" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "url_osdd = el.attrib['href']\n", "el.attrib['href']" @@ -663,7 +311,7 @@ "metadata": {}, "source": [ "**Step 4** \n", - "> From the collection OSDD found in the IDN OpenSearch response, formulate a valid granule search request. How to do this is explained in sections (“CWIC”) and (“FedEO”). " + "> From the collection OSDD found in the IDN OpenSearch response, formulate a valid granule search request. How to do this is explained in sections (“CWIC”) and [\"FedEO\"](chapter-fedeo). " ] }, { @@ -684,6 +332,7 @@ "id": "08becdcf", "metadata": {}, "source": [ + "(section_Available_Collection_Search_Criteria_IDN)=\n", "## Available Collection Search Criteria" ] }, @@ -710,102 +359,20 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": null, "id": "bab4e4b7", "metadata": { "tags": [ "remove-input" ] }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
Request
\n", - "Parameter
\n", - "Description\n", - "Value &\n", - "Cardinality
\n", - "(M) = mandatory
\n", - "(O) = optional\n", - "
\n", - "Type
boundingBox Inventory with a spatial extent overlapping\n", - "this bounding box\n", - "(O) geo:box
keyword Inventory with terms expressed by these\n", - "search terms\n", - "(O) os:searchTerms
instrument Inventory associated with a satellite\n", - "instrument expressed by this short name\n", - "(O) echo:instrument
satellite Inventory associated with a\n", - "Satellite/platform expressed by this short\n", - "name\n", - "(O) eo:platform
geometry Inventory with a spatial extent overlapping\n", - "this geometry\n", - "(O) geo:geometry
placeName Inventory with a spatial location described\n", - "by this name\n", - "(O) geo:name
startTime Inventory with a temporal extent containing\n", - "this start time\n", - "(O) time:start
endTime Inventory with a temporal extent containing\n", - "this end time\n", - "(O) time:end
cursor Start page for the search result (O) os:startPage
numberOfResults Maximum number of records in the search\n", - "result\n", - "(O) os:count
offset 0 - based offset used to skip the specified\n", - "number of results in the search result set\n", - "(O) os:startIndex
uid Inventory associated with this unique ID(O) geo:uid
hasGranules Inventory with granules(O) echo:hasGranules
isCwic Inventory related to CWIC(O) echo:isCwic
isGeoss Inventory related to GEOSS(O) echo:isGeoss
isCeos Inventory related to CEOS(O)
isEosdis Inventory related to EOSDIS(O) echo:isEosdis
provider Inventory associated with a provider(O) echo:provider
clientId Client identifier to be used for metrics(O) cswOpenSearchDoc
\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%%html\n", "\n", "\n", "\n", - "\n", + "OpenSearch Parameter\n", "\n", "\n", "
Request
\n", + "
HTTP Query
\n", "Parameter
\n", "Description\n", "Value &\n", @@ -813,7 +380,7 @@ "(M) = mandatory
\n", "(O) = optional\n", "
\n", - "Type
boundingBox Inventory with a spatial extent overlapping\n", diff --git a/book/opensearch_7_cmr.ipynb b/book/opensearch_7_cmr.ipynb new file mode 100644 index 0000000..fad617e --- /dev/null +++ b/book/opensearch_7_cmr.ipynb @@ -0,0 +1,581 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "d99fea47", + "metadata": {}, + "source": [ + "(chapter-cwic)=\n", + "# Use Case - Granule Search (CWIC/CMR)\n", + "\n", + "This chapter provides a comprehensive and detailed process about how to implement a WGISS\n", + "OpenSearch client, which includes how to retrieve the IDN collection ID for the collection of\n", + "interest, and how to build an OpenSearch request for a CWIC data partner. Within CMR, CWIC\n", + "partners are available directly from CMR. The IDN response records contain direct links to the\n", + "OSDD from the CWIC partner server, where possible. This can be used to construct a granule\n", + "search directly from the partner." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "30675075", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "import re\n", + "import json, requests, xml\n", + "import pandas as pd\n", + "\n", + "from xml.dom import minidom\n", + "from xml.etree import ElementTree\n", + "from IPython.display import Markdown as md\n", + "# from IPython.display import HTML as html" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "0bc1e2cc", + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "def get_api_request(template, os_querystring):\n", + " #\n", + " # Fill (URL) template with OpenSearch parameter values provided in os_querystring and \n", + " # return as short HTTP URL without empty parameters.\n", + " #\n", + " \n", + " # Limitation: the OSDD may use a default namespace for OpenSearch instead of using \"os\".\n", + " # We make a simple correction here allowing to use OpenSearch queryables without namespace in requests.\n", + " # A more generic solution to obtain namespaces from the OSDD and compare them with user supplied namespaces is future work.\n", + " \n", + " OS_NAMESPACE = 'os:'\n", + " \n", + " # perform substitutions in template\n", + " for p in os_querystring:\n", + " # print(\" .. replacing:\", p, \"by\", os_querystring[p])\n", + " # template = re.sub('\\{'+p+'.*?\\}', os_querystring[p] , template)\n", + " result = re.subn('\\{'+p+'.*?\\}', os_querystring[p] , template)\n", + " n = result[1]\n", + " template = result[0]\n", + " if (n<1):\n", + " if (':' in p):\n", + " print(\"ERROR: parameter \" + p + \" not found in template.\")\n", + " else:\n", + " # try with explicit namespace\n", + " result = re.subn('\\{'+OS_NAMESPACE+p+'.*?\\}', os_querystring[p] , template)\n", + " n = result[1]\n", + " template = result[0]\n", + " if (n<1):\n", + " print(\"ERROR: parameter \" + OS_NAMESPACE+p + \" not found in template.\") \n", + " \n", + " # print(\"- intermediate new template:\" + template)\n", + " \n", + " # remove empty search parameters\n", + " template=re.sub('&?[a-zA-Z]*=\\{.*?\\}', '' , template)\n", + " \n", + " # remove remaining empty search parameters which did not have an HTTP query parameter attached (e.g. /{time:end}).\n", + " template=re.sub('.?\\{.*?\\}', '' , template)\n", + " \n", + " # print(\"API request: \" + template)\n", + " \n", + " return (template)" + ] + }, + { + "cell_type": "markdown", + "id": "4cdb746c", + "metadata": {}, + "source": [ + "## Retrieve Collection OSDD via IDN OpenSearch" + ] + }, + { + "cell_type": "markdown", + "id": "27f7a410", + "metadata": {}, + "source": [ + "The steps in this section are identical to the steps explained in the section [Retrieve Collections via IDN OpenSearch](section_Retrieve_Collections_via_IDN_OpenSearch). To fit the end-to-end\n", + "CWIC use case, the parameter values for the collection search has been selected in such a way that\n", + "the granule search is eventually performed through CWIC.\n", + "\n", + "\n", + "| **Use Case Overview** | | \n", + "| -------- | --------- | \n", + "| Title | Clients start from the IDN OpenSearch | \n", + "| Description | This use case describes steps for retrieving a collection ID from the IDN OpenSearch. | \n", + "| Actors | OpenSearch client, IDN OpenSearch Server | \n", + "| Initial Status and Preconditions | Clients have the IDN OpenSearch access URL. | \n", + "\n", + "The following steps describe this use case." + ] + }, + { + "cell_type": "markdown", + "id": "730d2d61", + "metadata": {}, + "source": [ + "**Step 1** \n", + "> Obtain the IDN OpenSearch OSDD to formulate a valid IDN OpenSearch request." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "8572ead4", + "metadata": { + "tags": [ + "remove-input" + ] + }, + "outputs": [], + "source": [ + "url_osdd = \"https://cmr.earthdata.nasa.gov/opensearch/collections/descriptor_document.xml?clientId=ceosOpenSearchDoc\"" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "2ed09441", + "metadata": { + "tags": [ + "remove-input" + ] + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "The OpenSearch Description Document is accessible at the fixed location [https://cmr.earthdata.nasa.gov/opensearch/collections/descriptor_document.xml?clientId=ceosOpenSearchDoc](https://cmr.earthdata.nasa.gov/opensearch/collections/descriptor_document.xml?clientId=ceosOpenSearchDoc) and contains the URL template to be used for collection search." + ], + "text/plain": [ + "" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "md(\"The OpenSearch Description Document is accessible at the fixed location [{url}]({url}) and contains the URL template to be used for collection search.\".format(url=url_osdd))" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "01c80dcd", + "metadata": { + "tags": [ + "output_scroll" + ] + }, + "outputs": [], + "source": [ + "response = requests.get( url_osdd )\n", + "\n", + "xmlstr = minidom.parseString(response.text).toprettyxml(indent=' ',newl='')\n", + "# md(\"```xml\\n\" + xmlstr + \"\\n```\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "07aa5a21", + "metadata": {}, + "source": [ + "Find the URL template for collection search with Atom responses." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "fd8cdefc", + "metadata": { + "tags": [ + "output_scroll" + ] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://cmr.earthdata.nasa.gov/opensearch/collections.atom?keyword={os:searchTerms?}&instrument={echo:instrument?}&satellite={eo:platform?}&boundingBox={geo:box?}&lat={geo:lat?}&lon={geo:lon?}&radius={geo:radius?}&geometry={geo:geometry?}&placeName={geo:name?}&startTime={time:start?}&endTime={time:end?}&cursor={os:startPage?}&numberOfResults={os:count?}&offset={os:startIndex?}&uid={geo:uid?}&hasGranules={echo:hasGranules?}&isCwic={echo:isCwic?}&isGeoss={echo:isGeoss?}&isCeos={echo:isCeos?}&isEosdis={echo:isEosdis?}&isFedeo={echo:isFedeo?}&provider={echo:provider?}&clientId=ceosOpenSearchDoc'" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "root = ElementTree.fromstring(response.text)\n", + "\n", + "ns = {'os': 'http://a9.com/-/spec/opensearch/1.1/'}\n", + "collection_url_atom = root.find('os:Url[@rel=\"collection\"][@type=\"application/atom+xml\"]', ns)\n", + "\n", + "collection_template = collection_url_atom.attrib['template']\n", + "collection_template" + ] + }, + { + "cell_type": "markdown", + "id": "97a967cf", + "metadata": {}, + "source": [ + "**Step 2** \n", + "> Search collections of interest through IDN OpenSearch with proper request parameters (e.g. spatial footprint, temporal extent and keyword). A complete list of supported request parameters, extracted from the IDN OpenSearch OSDD, was included in the section [Available Collection Search Criteria](section_Available_Collection_Search_Criteria_IDN)." + ] + }, + { + "cell_type": "markdown", + "id": "0d3f24c0", + "metadata": {}, + "source": [ + "An example request can be formed as follows." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "d78fe4c0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://cmr.earthdata.nasa.gov/opensearch/collections.atom?keyword=Landsat_8&numberOfResults=1&clientId=ceosOpenSearchDoc'" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "request_url = get_api_request(collection_template, {'count': '1', 'searchTerms': 'Landsat_8'})\n", + "request_url" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "d0e72b46", + "metadata": { + "tags": [ + "output_scroll" + ] + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "```xml\n", + " \n", + " 2024-12-06T15:51:03.435Z \n", + " https://cmr.earthdata.nasa.gov/opensearch/collections.atom \n", + " \n", + " CMR \n", + " echodev@echo.nasa.gov \n", + " \n", + " ECHO dataset metadata \n", + " Search parameters: keyword => Landsat_8 \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " 1 \n", + " 1 \n", + " 1 \n", + " \n", + " https://cmr.earthdata.nasa.gov/opensearch/collections.atom?uid=C1235542031-USGS_LTA \n", + " \n", + " CMR \n", + " echodev@echo.nasa.gov \n", + " \n", + " CEOS \n", + " CWIC \n", + " Landsat 8 \n", + " The Operational Land Imager (OLI) and Thermal Infrared Sensor (TIRS) are onboard the Landsat 8 satellite, have acquired images of the Earth since February 2013. The sensors collect images of the Earth with a 16-day repeat cycle, referenced to the Worldwide Reference System-2. The approximate scene size is 170 km north-south by 183 km east-west (106 mi by 114 mi).\n", + "\n", + "Landsat 8 image data files consist of 11 spectral bands with a spatial resolution of 30 meters for bands 1-7 and bands 9-11; 15-meters for the panchromatic band 8. Delivered Landsat 8 Level-1 data typically include both OLI and TIRS data files; however, there may be OLI-only and/or TIRS-only scenes in the USGS archive. A Quality Assurance (QA.tif) band is also included. This file provides bit information regarding conditions that may affect the accuracy and usability of a given pixel – clouds, water or snow, for example. \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " C1235542031-USGS_LTA \n", + " 2013-02-11T00:00:00.000Z/ \n", + " Landsat 8 \n", + " Landsat_8 \n", + " Not provided \n", + " Landsat_8 \n", + " USGS_LTA \n", + " DOI/USGS/EROS \n", + " DOI/USGS/EROS \n", + " Not Provided \n", + " CARTESIAN \n", + " \n", + " -82.71 -180 82.74 180 \n", + " false \n", + " false \n", + " false \n", + " false \n", + " false \n", + " false \n", + " false \n", + " 0.97999995 \n", + " \n", + " org.ceos.wgiss.cwic.granules.prod \n", + " " " \n", + " \n", + " \n", + " org.ceos.wgiss.cwic.granules.provider \n", + " "USGSLSI" \n", + " \n", + " \n", + " org.geoss.geoss_data-core \n", + " \n", + " \n", + " gov.nasa.eosdis \n", + " \n", + " true \n", + " true \n", + " \n", + "\n", + "```\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response = requests.get( request_url )\n", + "xmlstr = minidom.parseString(response.text).toprettyxml(indent=' ', newl='')\n", + "md(\"```xml\\n\" + xmlstr + \"\\n```\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "f14a17b4", + "metadata": {}, + "source": [ + "**Step 3** \n", + "> From the IDN OpenSearch response, obtain the OSDD endpoint for the collection by parsing the href attribute under `` " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "15c70321", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "```xml\n", + "\n", + " \n", + "```\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "root = ElementTree.fromstring(response.text)\n", + "# Extract element with the OSDD for the granule search\n", + "el = root.find('{http://www.w3.org/2005/Atom}entry/{http://www.w3.org/2005/Atom}link[@rel=\"search\"][@type=\"application/opensearchdescription+xml\"]')\n", + "xmltxt = ElementTree.tostring(el, encoding='unicode', method='xml')\n", + "md(\"```xml\\n\" + xmltxt + \"\\n```\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "a20ecd3c", + "metadata": {}, + "source": [ + "This response will provide the key component of searching CMR for the desired collection using\n", + "the CMR conceptID. For Landsat 8, this will be C1235542031-USGS_LTA. Now obtain from\n", + "CMR the URL for the local OSDD (in this case, at USGS), with the request" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "e612a026", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://cmr.earthdata.nasa.gov/opensearch/granules/descriptor_document.xml?collectionConceptId=C1235542031-USGS_LTA'" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "url_osdd = el.attrib['href']\n", + "el.attrib['href']" + ] + }, + { + "cell_type": "markdown", + "id": "3f2fa331", + "metadata": {}, + "source": [ + "Retrieve the response (i.e. the OSDD document)." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "e2a03174", + "metadata": { + "tags": [ + "output_scroll" + ] + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "```xml\n", + " \n", + " OpenSearch Exception \n", + " No native id present within the `org.ceos.wgiss.cwic.granules.native_id` tag. \n", + " 2024-12-06T15:51:04Z \n", + " https://cmr.earthdata.nasa.gov/opensearch/granules/descriptor_document.xml?collectionConceptId=C1235542031-USGS_LTA \n", + " \n", + " 0 \n", + "\n", + "```\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "response = requests.get( el.attrib['href'] )\n", + "\n", + "xmlstr = minidom.parseString(response.text).toprettyxml(indent=' ',newl='')\n", + "md(\"```xml\\n\" + xmlstr + \"\\n```\\n\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "0a755fde", + "metadata": {}, + "source": [ + "```{warning}\n", + "In the previous step, the OSDD could not be retrieved as the URL included in the response is not the one with `short_name`. See also step 5 in chapter 5 \"Outline\" with the workaround to fix that.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "af400462", + "metadata": {}, + "source": [ + "## Retrieve Granules via OpenSearch" + ] + }, + { + "cell_type": "markdown", + "id": "c7985450", + "metadata": {}, + "source": [ + "## Available Granule Search Parameters\n", + "\n", + "After retrieving the OSDD endpoint by querying through the IDN OpenSearch, OpenSearch clients\n", + "will sequentially interact with the host remote server for inventory search. The following table\n", + "shows the basic information about the use case of interacting with WGISS Connected Data Assets\n", + "via OpenSearch.\n", + "\n", + "\n", + "TBD" + ] + } + ], + "metadata": { + "description": "This notebook explains the use of the OpenSearch interface with Atom response format to access collection and granule metadata according to the two-step mechanism recommended by CEOS Best Practices. It can be used with the ESA EO-CAT and CEOS FedEO catalogue endpoints.", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + }, + "potentialAction": [ + { + "@type": "InteractAction", + "name": "Launch Binder", + "target": "https://mybinder.org/v2/gh/eovoc/eo-books/main?urlpath=tree/docs/opensearch.ipynb" + }, + { + "@type": "InteractAction", + "name": "Open in Google Colab", + "target": "https://colab.research.google.com/github/eovoc/eo-books/blob/main/docs/opensearch.ipynb" + } + ], + "tags": { + "tags": [ + "EOCAT", + "FedEO", + "OpenSearch", + "Data Access/Retrieval", + "Metadata Handling", + "Service Discovery", + "Data Discovery", + "CDA", + "CEOS", + "OGC", + "ESA" + ] + }, + "title": "OpenSearch with Atom" + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/book/opensearch_8_fedeo.ipynb b/book/opensearch_8_fedeo.ipynb index 1f53880..f4227c4 100644 --- a/book/opensearch_8_fedeo.ipynb +++ b/book/opensearch_8_fedeo.ipynb @@ -6,6 +6,7 @@ "id": "d99fea47", "metadata": {}, "source": [ + "(chapter-fedeo)=\n", "# Use Case - Granule Search (FedEO)\n", "\n", "This chapter provides a comprehensive and detailed process about how to implement a CEOS\n", @@ -128,7 +129,7 @@ "id": "27f7a410", "metadata": {}, "source": [ - "The steps in this section are identical to the steps explained in section 6.2. To fit the end-to-end\n", + "The steps in this section are identical to the steps explained in the section [Retrieve Collections via IDN OpenSearch](section_Retrieve_Collections_via_IDN_OpenSearch). To fit the end-to-end\n", "FedEO use case, the parameter values for the collection search has been selected in such a way\n", "that the granule search is eventually performed through FedEO.\n", "\n", @@ -5617,7 +5618,7 @@ "### Available Granule Search Parameters\n", "\n", "The set of available granule search parameters depends on the actual collection and is not fixed. Please refer to the [OpenAPI description](https://fedeo.ceos.org/api) for the complete list of search parameters that\n", - "may be advertised by a granule search OSDD. The meaning of these parameters is defined in [CEOS-OS-BP],\n", + "may be advertised by a granule search OSDD. The meaning of these parameters is defined in [CEOS-OS-BP](chapter-references),\n", "[OGC 13-026r9](https://docs.ogc.org/is/13-026r9/13-026r9.html) and [OGC 10-032r8](https://portal.ogc.org/files/?artifact_id=56866)." ] }, diff --git a/book/references.md b/book/references.md index d2e1cba..48171dd 100644 --- a/book/references.md +++ b/book/references.md @@ -1,3 +1,4 @@ +(chapter-references)= # References The following documents provide more background and supportive information.