Skip to content

Instantly share code, notes, and snippets.

@betolink
Created May 6, 2025 19:53
Show Gist options
  • Select an option

  • Save betolink/903580f2f8166524d85ae674b8f0f14f to your computer and use it in GitHub Desktop.

Select an option

Save betolink/903580f2f8166524d85ae674b8f0f14f to your computer and use it in GitHub Desktop.
ITS_LIVE STAC search
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "f9e94f1a-1194-4220-88e8-3d8fe7665516",
"metadata": {},
"source": [
"# ITS_LIVE STAC catalog search\n",
"\n",
"This is a sample to search velocity granules using the all new ITS_LIVE STAC catalog."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ebc908f3-069a-4c41-b057-8083a5a942c4",
"metadata": {},
"outputs": [],
"source": [
"from pystac_client import Client\n",
"import time\n",
"\n",
"def search_stac(stac_catalog, page_size=100, filter_list=[], **kwargs):\n",
" \"\"\"\n",
" Returns only the url to the data asset, for ITS_LIVE a netcdf file.\n",
" \"\"\"\n",
" catalog = Client.open(stac_catalog)\n",
" search_kwargs = {\n",
" \"collections\": [\"itslive-granules\"],\n",
" \"limit\": page_size,\n",
" **kwargs\n",
" }\n",
"\n",
" def build_cql2_filter(filters_list):\n",
" if not filters_list:\n",
" return None\n",
" return filters_list[0] if len(filters_list) == 1 else {\"op\": \"and\", \"args\": filters_list}\n",
" if filter_list:\n",
" filters = build_cql2_filter(filter_list)\n",
" search_kwargs[\"filter\"] = build_cql2_filter(filters)\n",
" search_kwargs[\"filter_lang\"] = \"cql2-json\"\n",
"\n",
" search = catalog.search(**search_kwargs)\n",
" print(search.get_parameters())\n",
" \n",
" hrefs = []\n",
" pages_count = 0\n",
" proj_matches = 0\n",
" for page in search.pages():\n",
" pages_count += 1\n",
" for item in page:\n",
" if kwargs.get(\"debug\"):\n",
" print(f\"fetching page {page_count}\")\n",
" for asset in item.assets.values():\n",
" if \"data\" in asset.roles and asset.href.endswith(\".nc\"):\n",
" hrefs.append(asset.href)\n",
" time.sleep(0.1) # we can remove this one, just to avoid overwhelming the server\n",
" print(f\"Requested pages: {pages_count}\")\n",
" return hrefs"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c12faaee-d738-4182-a680-f74bfa80742d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'limit': 2000, 'datetime': '2010-06-01T00:00:00Z/2023-06-30T23:59:59Z', 'collections': ('itslive-granules',), 'intersects': {'type': 'Polygon', 'coordinates': [[[-35.11660324172296, 71.70932130492467], [-32.56940542707364, 71.70932130492467], [-32.56940542707364, 72.26734859624985], [-35.11660324172296, 72.26734859624985], [-35.11660324172296, 71.70932130492467]]]}, 'filter': {'op': 'and', 'args': {'op': 'and', 'args': [{'op': '>=', 'args': [{'property': 'percent_valid_pixels'}, 50]}, {'op': '<=', 'args': [{'property': 'dt_days'}, 8]}, {'op': '=', 'args': [{'property': 'sat:orbit_state'}, 'ascending']}]}}, 'filter-lang': 'cql2-json'}\n",
"Requested pages: 1\n",
"CPU times: user 27.5 ms, sys: 5.67 ms, total: 33.2 ms\n",
"Wall time: 1.37 s\n"
]
},
{
"data": {
"text/plain": [
"110"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"\n",
"roi = {\n",
" \"type\": \"Polygon\",\n",
" \"coordinates\": [[\n",
" [\n",
" -35.11660324172296,\n",
" 71.70932130492467\n",
" ],\n",
" [\n",
" -32.56940542707364,\n",
" 71.70932130492467\n",
" ],\n",
" [\n",
" -32.56940542707364,\n",
" 72.26734859624985\n",
" ],\n",
" [\n",
" -35.11660324172296,\n",
" 72.26734859624985\n",
" ],\n",
" [\n",
" -35.11660324172296,\n",
" 71.70932130492467\n",
" ]\n",
" ]\n",
" ]\n",
"}\n",
"\n",
"# Full list of properties can be found by inspecting a STAC item from the collection\n",
"# e.g. https://stac.itslive.cloud/collections/itslive-granules/items/S2B_MSIL1C_20250410T133729_N0511_R067_T33XXK_20250410T171508_X_S2A_MSIL1C_20250417T133731_N0511_R067_T33XXK_20250417T205237_G0120V02_P054\n",
"\n",
"filters = [\n",
" {\"op\": \">=\", \"args\": [{\"property\": \"percent_valid_pixels\"}, 50]},\n",
" {\"op\": \"<=\", \"args\": [{\"property\": \"dt_days\"}, 8]},\n",
" {\"op\": \"=\", \"args\": [{\"property\": \"sat:orbit_state\"}, \"ascending\"]},\n",
"]\n",
"\n",
"items = search_stac(\"https://stac.itslive.cloud\",\n",
" datetime=\"2010-06-01/2023-06-30\",\n",
" intersects=roi,\n",
" filter_list=filters,\n",
" page_size=2000)\n",
"len(items)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "966c9a3f-3fd6-48db-81c9-82248f413e50",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'https://its-live-data.s3.amazonaws.com/velocity_image_pair/sentinel1/v02/N70W030/S1B_IW_SLC__1SDH_20211221T195756_20211221T195823_030128_0398FA_581A_X_S1A_IW_SLC__1SDH_20211227T195838_20211227T195905_041199_04E552_387F_G0120V02_P099.nc'"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"items[0]"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.13.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment