{ "cells": [ { "cell_type": "markdown", "id": "23374c2d-0b01-496c-8171-3abf13dc77d4", "metadata": {}, "source": [ "## Reading Data from the STAC API\n", "\n", "The Planetary Computer catalogs the datasets we host using the [STAC](http://stacspec.org/) (SpatioTemporal Asset Catalog) specification. We provide a [STAC API](https://github.com/radiantearth/stac-api-spec) endpoint for searching our datasets by space, time, and more. This quickstart will show you how to search for data using our STAC API and open-source Python libraries. To use our STAC API from R, see [Reading data from the STAC API with R](https://planetarycomputer.microsoft.com/docs/quickstarts/reading-stac-r/).\n", "\n", "To get started you'll need the [pystac-client](https://github.com/stac-utils/pystac-client) library installed. You can install it via pip:\n", "\n", "```\n", "> python -m pip install pystac-client\n", "```\n", "\n", "To access the data, we'll create a `pystac_client.Client`. We'll explain the `modifier` part later on, but it's what lets us download the data assets Azure Blob Storage." ] }, { "cell_type": "code", "execution_count": 1, "id": "fda5e533-84b8-4051-9198-2df74338ae71", "metadata": { "tags": [] }, "outputs": [], "source": [ "import pystac_client\n", "import planetary_computer\n", "\n", "catalog = pystac_client.Client.open(\n", " \"https://planetarycomputer.microsoft.com/api/stac/v1\",\n", " modifier=planetary_computer.sign_inplace,\n", ")" ] }, { "cell_type": "markdown", "id": "b1f7ef57-45db-49ef-9065-4515157d23fb", "metadata": {}, "source": [ "### Searching\n", "\n", "We can use the STAC API to search for assets meeting some criteria. This might include the date and time the asset covers, is spatial extent, or any other property captured in the STAC item's metadata.\n", "\n", "In this example we'll search for imagery from [Landsat Collection 2 Level-2](https://planetarycomputer.microsoft.com/dataset/landsat-c2-l2) area around Microsoft's main campus in December of 2020." ] }, { "cell_type": "code", "execution_count": 2, "id": "2ec73f94-3989-49cf-920a-fde66c7946b8", "metadata": { "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/srv/conda/envs/notebook/lib/python3.11/site-packages/pystac_client/item_search.py:841: FutureWarning: get_all_items() is deprecated, use item_collection() instead.\n", " warnings.warn(\n" ] }, { "data": { "text/plain": [ "8" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "time_range = \"2020-12-01/2020-12-31\"\n", "bbox = [-122.2751, 47.5469, -121.9613, 47.7458]\n", "\n", "search = catalog.search(collections=[\"landsat-c2-l2\"], bbox=bbox, datetime=time_range)\n", "items = search.get_all_items()\n", "len(items)" ] }, { "cell_type": "markdown", "id": "84143827-ff63-4946-a995-ebc101f18d52", "metadata": {}, "source": [ "In that example our spatial query used a bounding box with a `bbox`. Alternatively, you can pass a GeoJSON object as `intersects`\n", "\n", "```python\n", "area_of_interest = {\n", " \"type\": \"Polygon\",\n", " \"coordinates\": [\n", " [\n", " [-122.2751, 47.5469],\n", " [-121.9613, 47.9613],\n", " [-121.9613, 47.9613],\n", " [-122.2751, 47.9613],\n", " [-122.2751, 47.5469],\n", " ]\n", " ],\n", "}\n", "\n", "time_range = \"2020-12-01/2020-12-31\"\n", "\n", "search = catalog.search(\n", " collections=[\"landsat-c2-l2\"], intersects=area_of_interest, datetime=time_range\n", ")\n", "```" ] }, { "cell_type": "markdown", "id": "aedaf9f7-1ba2-472d-85e1-5838e7df9ffb", "metadata": {}, "source": [ "`items` is a [`pystac.ItemCollection`](https://pystac.readthedocs.io/en/stable/api/item_collection.html#pystac-item-collection). We can see that 4 items matched our search criteria." ] }, { "cell_type": "code", "execution_count": 3, "id": "c62e1ca1-0be3-45a6-bb8a-5fd048a5478c", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(items)" ] }, { "cell_type": "markdown", "id": "6b36c181-a163-4e40-9ad0-3accacc82010", "metadata": {}, "source": [ "Each [`pystac.Item`](https://pystac.readthedocs.io/en/stable/api/pystac.html#pystac.Item) in this `ItemCollection` includes all the metadata for that scene. [STAC Items](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md) are GeoJSON features, and so can be loaded by libraries like [geopandas](http://geopandas.readthedocs.io/)." ] }, { "cell_type": "code", "execution_count": 4, "id": "b95c28ed-0ab1-4d4c-aa0f-a0382f694238", "metadata": { "tags": [] }, "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", " \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", " \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", " \n", " \n", " \n", "
geometrygsdcreatedsci:doidatetimeplatformproj:epsgproj:shapedescriptioninstruments...landsat:wrs_rowlandsat:scene_idlandsat:wrs_pathlandsat:wrs_typeview:sun_azimuthlandsat:correctionview:sun_elevationlandsat:cloud_cover_landlandsat:collection_numberlandsat:collection_category
0POLYGON ((-122.72549 48.50884, -120.29248 48.0...302022-05-06T18:04:17.126358Z10.5066/P9OGBGM62020-12-29T18:55:56.738265Zlandsat-832610[7881, 7781]Landsat Collection 2 Level-2[oli, tirs]...027LC80460272020364LGN000462162.253231L2SP17.458298100.0002T2
1POLYGON ((-124.52046 48.44245, -121.93932 48.0...302022-05-06T17:25:29.626986Z10.5066/P9C7I13B2020-12-28T18:20:32.609164Zlandsat-732610[7361, 8341]Landsat Collection 2 Level-2[etm+]...027LE70470272020363EDC000472152.689113L2SP14.67888032.0002T1
2POLYGON ((-122.96802 48.44547, -120.39024 48.0...302022-05-06T18:01:04.319403Z10.5066/P9C7I13B2020-12-21T18:14:50.812768Zlandsat-732610[7251, 8251]Landsat Collection 2 Level-2[etm+]...027LE70460272020356EDC000462153.649177L2SP14.77961224.0002T2
3POLYGON ((-124.27547 48.50831, -121.84167 48.0...302022-05-06T17:46:22.246696Z10.5066/P9OGBGM62020-12-20T19:02:09.878796Zlandsat-832610[7971, 7861]Landsat Collection 2 Level-2[oli, tirs]...027LC80470272020355LGN000472163.360118L2SP17.414441100.0002T2
4POLYGON ((-122.72996 48.50858, -120.29690 48.0...302022-05-06T18:04:16.935800Z10.5066/P9OGBGM62020-12-13T18:56:00.096447Zlandsat-832610[7881, 7781]Landsat Collection 2 Level-2[oli, tirs]...027LC80460272020348LGN000462164.126188L2SP17.79974498.6402T2
5POLYGON ((-124.51935 48.44597, -121.93965 48.0...302022-05-06T17:25:29.412798Z10.5066/P9C7I13B2020-12-12T18:21:42.991249Zlandsat-732610[7361, 8341]Landsat Collection 2 Level-2[etm+]...027LE70470272020347EDC000472154.692691L2SP15.42742212.0002T1
6POLYGON ((-122.98709 48.44790, -120.40945 48.0...302022-05-06T18:01:04.178839Z10.5066/P9C7I13B2020-12-05T18:16:03.755599Zlandsat-732610[7281, 8251]Landsat Collection 2 Level-2[etm+]...027LE70460272020340EDC000462155.308739L2SP16.3135702.0002T1
7POLYGON ((-124.27385 48.50833, -121.83965 48.0...302022-05-06T17:46:22.097338Z10.5066/P9OGBGM62020-12-04T19:02:11.194486Zlandsat-832610[7971, 7861]Landsat Collection 2 Level-2[oli, tirs]...027LC80470272020339LGN000472164.914060L2SP18.8072301.9002T1
\n", "

8 rows × 23 columns

\n", "
" ], "text/plain": [ " geometry gsd \\\n", "0 POLYGON ((-122.72549 48.50884, -120.29248 48.0... 30 \n", "1 POLYGON ((-124.52046 48.44245, -121.93932 48.0... 30 \n", "2 POLYGON ((-122.96802 48.44547, -120.39024 48.0... 30 \n", "3 POLYGON ((-124.27547 48.50831, -121.84167 48.0... 30 \n", "4 POLYGON ((-122.72996 48.50858, -120.29690 48.0... 30 \n", "5 POLYGON ((-124.51935 48.44597, -121.93965 48.0... 30 \n", "6 POLYGON ((-122.98709 48.44790, -120.40945 48.0... 30 \n", "7 POLYGON ((-124.27385 48.50833, -121.83965 48.0... 30 \n", "\n", " created sci:doi datetime \\\n", "0 2022-05-06T18:04:17.126358Z 10.5066/P9OGBGM6 2020-12-29T18:55:56.738265Z \n", "1 2022-05-06T17:25:29.626986Z 10.5066/P9C7I13B 2020-12-28T18:20:32.609164Z \n", "2 2022-05-06T18:01:04.319403Z 10.5066/P9C7I13B 2020-12-21T18:14:50.812768Z \n", "3 2022-05-06T17:46:22.246696Z 10.5066/P9OGBGM6 2020-12-20T19:02:09.878796Z \n", "4 2022-05-06T18:04:16.935800Z 10.5066/P9OGBGM6 2020-12-13T18:56:00.096447Z \n", "5 2022-05-06T17:25:29.412798Z 10.5066/P9C7I13B 2020-12-12T18:21:42.991249Z \n", "6 2022-05-06T18:01:04.178839Z 10.5066/P9C7I13B 2020-12-05T18:16:03.755599Z \n", "7 2022-05-06T17:46:22.097338Z 10.5066/P9OGBGM6 2020-12-04T19:02:11.194486Z \n", "\n", " platform proj:epsg proj:shape description \\\n", "0 landsat-8 32610 [7881, 7781] Landsat Collection 2 Level-2 \n", "1 landsat-7 32610 [7361, 8341] Landsat Collection 2 Level-2 \n", "2 landsat-7 32610 [7251, 8251] Landsat Collection 2 Level-2 \n", "3 landsat-8 32610 [7971, 7861] Landsat Collection 2 Level-2 \n", "4 landsat-8 32610 [7881, 7781] Landsat Collection 2 Level-2 \n", "5 landsat-7 32610 [7361, 8341] Landsat Collection 2 Level-2 \n", "6 landsat-7 32610 [7281, 8251] Landsat Collection 2 Level-2 \n", "7 landsat-8 32610 [7971, 7861] Landsat Collection 2 Level-2 \n", "\n", " instruments ... landsat:wrs_row landsat:scene_id landsat:wrs_path \\\n", "0 [oli, tirs] ... 027 LC80460272020364LGN00 046 \n", "1 [etm+] ... 027 LE70470272020363EDC00 047 \n", "2 [etm+] ... 027 LE70460272020356EDC00 046 \n", "3 [oli, tirs] ... 027 LC80470272020355LGN00 047 \n", "4 [oli, tirs] ... 027 LC80460272020348LGN00 046 \n", "5 [etm+] ... 027 LE70470272020347EDC00 047 \n", "6 [etm+] ... 027 LE70460272020340EDC00 046 \n", "7 [oli, tirs] ... 027 LC80470272020339LGN00 047 \n", "\n", " landsat:wrs_type view:sun_azimuth landsat:correction view:sun_elevation \\\n", "0 2 162.253231 L2SP 17.458298 \n", "1 2 152.689113 L2SP 14.678880 \n", "2 2 153.649177 L2SP 14.779612 \n", "3 2 163.360118 L2SP 17.414441 \n", "4 2 164.126188 L2SP 17.799744 \n", "5 2 154.692691 L2SP 15.427422 \n", "6 2 155.308739 L2SP 16.313570 \n", "7 2 164.914060 L2SP 18.807230 \n", "\n", " landsat:cloud_cover_land landsat:collection_number \\\n", "0 100.00 02 \n", "1 32.00 02 \n", "2 24.00 02 \n", "3 100.00 02 \n", "4 98.64 02 \n", "5 12.00 02 \n", "6 2.00 02 \n", "7 1.90 02 \n", "\n", " landsat:collection_category \n", "0 T2 \n", "1 T1 \n", "2 T2 \n", "3 T2 \n", "4 T2 \n", "5 T1 \n", "6 T1 \n", "7 T1 \n", "\n", "[8 rows x 23 columns]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import geopandas\n", "\n", "df = geopandas.GeoDataFrame.from_features(items.to_dict(), crs=\"epsg:4326\")\n", "df" ] }, { "cell_type": "markdown", "id": "e88bc7eb-fd2f-48b1-a3d7-dc96d8b7635c", "metadata": {}, "source": [ "Some collections implement the `eo` extension, which we can use to sort the items by cloudiness. We'll grab an item with low cloudiness:" ] }, { "cell_type": "code", "execution_count": 5, "id": "c60accc9-4126-4609-8a65-406719b5485b", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "selected_item = min(items, key=lambda item: item.properties[\"eo:cloud_cover\"])\n", "print(selected_item)" ] }, { "cell_type": "markdown", "id": "9be696c5-c9b9-4dcb-a876-a645d384fa83", "metadata": {}, "source": [ "Each STAC item has one or more [Assets](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md#asset-object), which include links to the actual files." ] }, { "cell_type": "code", "execution_count": 6, "id": "f507b45d-5985-4f10-9850-c1b3947c9908", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃ Asset Key         Description                                                          ┃\n",
       "┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│ qa               │ Surface Temperature Quality Assessment Band                          │\n",
       "│ ang              │ Angle Coefficients File                                              │\n",
       "│ red              │ Red Band                                                             │\n",
       "│ blue             │ Blue Band                                                            │\n",
       "│ drad             │ Downwelled Radiance Band                                             │\n",
       "│ emis             │ Emissivity Band                                                      │\n",
       "│ emsd             │ Emissivity Standard Deviation Band                                   │\n",
       "│ trad             │ Thermal Radiance Band                                                │\n",
       "│ urad             │ Upwelled Radiance Band                                               │\n",
       "│ atran            │ Atmospheric Transmittance Band                                       │\n",
       "│ cdist            │ Cloud Distance Band                                                  │\n",
       "│ green            │ Green Band                                                           │\n",
       "│ nir08            │ Near Infrared Band 0.8                                               │\n",
       "│ lwir11           │ Surface Temperature Band                                             │\n",
       "│ swir16           │ Short-wave Infrared Band 1.6                                         │\n",
       "│ swir22           │ Short-wave Infrared Band 2.2                                         │\n",
       "│ coastal          │ Coastal/Aerosol Band                                                 │\n",
       "│ mtl.txt          │ Product Metadata File (txt)                                          │\n",
       "│ mtl.xml          │ Product Metadata File (xml)                                          │\n",
       "│ mtl.json         │ Product Metadata File (json)                                         │\n",
       "│ qa_pixel         │ Pixel Quality Assessment Band                                        │\n",
       "│ qa_radsat        │ Radiometric Saturation and Terrain Occlusion Quality Assessment Band │\n",
       "│ qa_aerosol       │ Aerosol Quality Assessment Band                                      │\n",
       "│ tilejson         │ TileJSON with default rendering                                      │\n",
       "│ rendered_preview │ Rendered preview                                                     │\n",
       "└──────────────────┴──────────────────────────────────────────────────────────────────────┘\n",
       "
\n" ], "text/plain": [ "┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mAsset Key \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mDescription \u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", "│ qa │ Surface Temperature Quality Assessment Band │\n", "│ ang │ Angle Coefficients File │\n", "│ red │ Red Band │\n", "│ blue │ Blue Band │\n", "│ drad │ Downwelled Radiance Band │\n", "│ emis │ Emissivity Band │\n", "│ emsd │ Emissivity Standard Deviation Band │\n", "│ trad │ Thermal Radiance Band │\n", "│ urad │ Upwelled Radiance Band │\n", "│ atran │ Atmospheric Transmittance Band │\n", "│ cdist │ Cloud Distance Band │\n", "│ green │ Green Band │\n", "│ nir08 │ Near Infrared Band 0.8 │\n", "│ lwir11 │ Surface Temperature Band │\n", "│ swir16 │ Short-wave Infrared Band 1.6 │\n", "│ swir22 │ Short-wave Infrared Band 2.2 │\n", "│ coastal │ Coastal/Aerosol Band │\n", "│ mtl.txt │ Product Metadata File (txt) │\n", "│ mtl.xml │ Product Metadata File (xml) │\n", "│ mtl.json │ Product Metadata File (json) │\n", "│ qa_pixel │ Pixel Quality Assessment Band │\n", "│ qa_radsat │ Radiometric Saturation and Terrain Occlusion Quality Assessment Band │\n", "│ qa_aerosol │ Aerosol Quality Assessment Band │\n", "│ tilejson │ TileJSON with default rendering │\n", "│ rendered_preview │ Rendered preview │\n", "└──────────────────┴──────────────────────────────────────────────────────────────────────┘\n" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import rich.table\n", "\n", "table = rich.table.Table(\"Asset Key\", \"Description\")\n", "for asset_key, asset in selected_item.assets.items():\n", " table.add_row(asset_key, asset.title)\n", "\n", "table" ] }, { "cell_type": "markdown", "id": "fe4053e4-6c1e-46b7-947d-79811a2877e4", "metadata": {}, "source": [ "Here, we'll inspect the `rendered_preview` asset." ] }, { "cell_type": "code", "execution_count": 7, "id": "f175aa10-8f97-4ea3-8fda-c6fe4469baea", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "{'href': 'https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=landsat-c2-l2&item=LC08_L2SP_047027_20201204_02_T1&assets=red&assets=green&assets=blue&color_formula=gamma+RGB+2.7%2C+saturation+1.5%2C+sigmoidal+RGB+15+0.55&format=png',\n", " 'type': 'image/png',\n", " 'title': 'Rendered preview',\n", " 'rel': 'preview',\n", " 'roles': ['overview']}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "selected_item.assets[\"rendered_preview\"].to_dict()" ] }, { "cell_type": "code", "execution_count": 8, "id": "50535606-4891-40d4-9e52-7d0056583681", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "\n", "Image(url=selected_item.assets[\"rendered_preview\"].href, width=500)" ] }, { "cell_type": "markdown", "id": "5abf7884-00c5-49fd-b27f-a57a23c00af5", "metadata": {}, "source": [ "That `rendered_preview` asset is generated dynamically from the raw data using the Planetary Computer's [data API](http://planetarycomputer.microsoft.com/api/data/v1/). We can access the raw data, stored as Cloud Optimzied GeoTIFFs in Azure Blob Storage, using one of the other assets.\n", "\n", "The actual data assets are in *private* [Azure Blob Storage containers](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction#containers). If forget to pass `modifier=planetary_computer.sign_inplace` or manually sign the item, then you'll get a 404 when trying to access the asset.\n", "\n", "That's why we included the `modifier=planetary_computer.sign_inplace` when we created the `pystac_client.Client` earlier. With that, the results returned by pystac-client are automatically signed, so that a token granting access to the file is included in the URL." ] }, { "cell_type": "code", "execution_count": 9, "id": "d43f7c1b-4463-4802-a112-aa466d6791c8", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'https://landsateuwest.blob.core.windows.net/landsat-c2/level-2/standard/oli-tirs/2020/047/027/LC08_L2SP_047027_20201204_20210313_02_T1/LC08_L2SP_047027_20201204_20210313_02_T1_SR_B2.TIF?st=2023-11-06T12%3A35%3A44Z&se=2023-11-14T12%3A35%3A44Z&sp=rl&sv'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "selected_item.assets[\"blue\"].href[:250]" ] }, { "cell_type": "markdown", "id": "3779e4dc-72d0-4a77-8d83-b49f67e16a5c", "metadata": {}, "source": [ " Everything after the `?` in that URL is a [SAS token](https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview) grants access to the data. See https://planetarycomputer.microsoft.com/docs/concepts/sas/ for more on using tokens to access data." ] }, { "cell_type": "code", "execution_count": 10, "id": "aefcb71d-31ba-4211-b7a5-7966c13304ef", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "200" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import requests\n", "\n", "requests.head(selected_item.assets[\"blue\"].href).status_code" ] }, { "cell_type": "markdown", "id": "65686af5-414e-4482-af27-fb680b179930", "metadata": {}, "source": [ "The `200` status code indicates that we were able to successfully access the data using the \"signed\" URL with the SAS token included." ] }, { "cell_type": "markdown", "id": "29feea6d-400d-4573-82ba-835918adb701", "metadata": {}, "source": [ "We can load up that single COG using libraries like [rioxarray](https://corteva.github.io/rioxarray/html/rioxarray.html) or [rasterio](https://rasterio.readthedocs.io/en/latest/)" ] }, { "cell_type": "code", "execution_count": 11, "id": "58481f78-40b5-486d-bf36-ab333206bdb4", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# import xarray as xr\n", "import rioxarray\n", "\n", "ds = rioxarray.open_rasterio(\n", " selected_item.assets[\"blue\"].href, overview_level=4\n", ").squeeze()\n", "img = ds.plot(cmap=\"Blues\", add_colorbar=False)\n", "img.axes.set_axis_off();" ] }, { "cell_type": "markdown", "id": "d3c08641-fbb6-425f-a3ca-975ca1d425a4", "metadata": {}, "source": [ "If you wish to work with multiple STAC items as a datacube, you can use libraries like [stackstac](https://stackstac.readthedocs.io/) or [odc-stac](https://odc-stac.readthedocs.io/en/latest/index.html)." ] }, { "cell_type": "code", "execution_count": 12, "id": "d4a749a5-4a05-405b-8c81-9c10317c9e33", "metadata": { "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/srv/conda/envs/notebook/lib/python3.11/site-packages/stackstac/prepare.py:363: UserWarning: The argument 'infer_datetime_format' is deprecated and will be removed in a future version. A strict version of it is now the default, see https://pandas.pydata.org/pdeps/0004-consistent-to-datetime-parsing.html. You can safely remove this argument.\n", " times = pd.to_datetime(\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'stackstac-58124a3f2aeb9e86fe45c8d5489954e7' (time: 8,\n",
       "                                                                band: 22,\n",
       "                                                                y: 7972,\n",
       "                                                                x: 12372)>\n",
       "dask.array<fetch_raster_window, shape=(8, 22, 7972, 12372), dtype=float64, chunksize=(1, 1, 1024, 1024), chunktype=numpy.ndarray>\n",
       "Coordinates: (12/31)\n",
       "  * time                         (time) datetime64[ns] 2020-12-04T19:02:11.19...\n",
       "    id                           (time) <U31 'LC08_L2SP_047027_20201204_02_T1...\n",
       "  * band                         (band) <U13 'qa' 'red' ... 'atmos_opacity'\n",
       "  * x                            (x) float64 3.339e+05 3.339e+05 ... 7.05e+05\n",
       "  * y                            (y) float64 5.374e+06 5.374e+06 ... 5.135e+06\n",
       "    landsat:wrs_type             <U1 '2'\n",
       "    ...                           ...\n",
       "    title                        (band) object 'Surface Temperature Quality A...\n",
       "    classification:bitfields     (band) object None None ... None\n",
       "    common_name                  (band) object None None None ... None None\n",
       "    center_wavelength            (band) object None None None ... None None\n",
       "    full_width_half_max          (band) object None None None ... 2.05 None None\n",
       "    epsg                         int64 32610\n",
       "Attributes:\n",
       "    spec:        RasterSpec(epsg=32610, bounds=(333870.0, 5135070.0, 705030.0...\n",
       "    crs:         epsg:32610\n",
       "    transform:   | 30.00, 0.00, 333870.00|\\n| 0.00,-30.00, 5374230.00|\\n| 0.0...\n",
       "    resolution:  30.0
" ], "text/plain": [ "\n", "dask.array\n", "Coordinates: (12/31)\n", " * time (time) datetime64[ns] 2020-12-04T19:02:11.19...\n", " id (time) " ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import contextily\n", "\n", "search = catalog.search(\n", " collections=[\"sentinel-2-l2a\"],\n", " bbox=[-124.2751, 45.5469, -110.9613, 47.7458],\n", " datetime=\"2020-12-26/2020-12-31\",\n", ")\n", "items = search.item_collection()\n", "\n", "df = geopandas.GeoDataFrame.from_features(items.to_dict(), crs=\"epsg:4326\")\n", "\n", "ax = df[[\"geometry\", \"datetime\", \"s2:mgrs_tile\", \"eo:cloud_cover\"]].plot(\n", " facecolor=\"none\", figsize=(12, 6)\n", ")\n", "contextily.add_basemap(\n", " ax, crs=df.crs.to_string(), source=contextily.providers.Esri.NatGeoWorldMap\n", ");" ] }, { "cell_type": "markdown", "id": "debaa186-f987-49c0-a476-98835207fd1f", "metadata": {}, "source": [ "Or we can plot cloudiness of a region over time." ] }, { "cell_type": "code", "execution_count": 16, "id": "548b344f-4c5e-41a7-bc27-9fe5d3bf3845", "metadata": { "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/srv/conda/envs/notebook/lib/python3.11/site-packages/pystac_client/item_search.py:841: FutureWarning: get_all_items() is deprecated, use item_collection() instead.\n", " warnings.warn(\n" ] }, { "data": { "text/html": [ "" ], "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "\n", "search = catalog.search(\n", " collections=[\"sentinel-2-l2a\"],\n", " bbox=[-124.2751, 45.5469, -123.9613, 45.7458],\n", " datetime=\"2020-01-01/2020-12-31\",\n", ")\n", "items = search.get_all_items()\n", "df = geopandas.GeoDataFrame.from_features(items.to_dict())\n", "df[\"datetime\"] = pd.to_datetime(df[\"datetime\"])\n", "\n", "ts = df.set_index(\"datetime\").sort_index()[\"eo:cloud_cover\"].rolling(7).mean()\n", "ts.plot(title=\"eo:cloud-cover (7-scene rolling average)\");" ] }, { "cell_type": "markdown", "id": "13669344-a6c2-4684-ba78-69b7907e37e1", "metadata": {}, "source": [ "### Working with STAC Catalogs and Collections\n", "\n", "Our `catalog` is a [STAC Catalog](https://github.com/radiantearth/stac-spec/blob/master/catalog-spec/catalog-spec.md) that we can crawl or search. The Catalog contains [STAC Collections](https://github.com/radiantearth/stac-spec/blob/master/collection-spec/collection-spec.md) for each dataset we have indexed (which is not the yet the entirety of data hosted by the Planetary Computer).\n", "\n", "Collections have information about the [STAC Items](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md) they contain. For instance, here we look at the [Bands](https://github.com/stac-extensions/eo#band-object) available for [Landsat 8 Collection 2 Level 2](https://planetarycomputer.microsoft.com/dataset/landsat-c2-l2) data:" ] }, { "cell_type": "code", "execution_count": 17, "id": "8da11d26-3658-4b9e-b790-f84a2aded3e8", "metadata": { "tags": [] }, "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", " \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", " \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", "
namecommon_namedescriptioncenter_wavelengthfull_width_half_max
0TM_B1blueVisible blue (Thematic Mapper)0.490.07
1TM_B2greenVisible green (Thematic Mapper)0.560.08
2TM_B3redVisible red (Thematic Mapper)0.660.06
3TM_B4nir08Near infrared (Thematic Mapper)0.830.14
4TM_B5swir16Short-wave infrared (Thematic Mapper)1.650.20
5TM_B6lwirLong-wave infrared (Thematic Mapper)11.452.10
6TM_B7swir22Short-wave infrared (Thematic Mapper)2.220.27
7ETM_B1blueVisible blue (Enhanced Thematic Mapper Plus)0.480.07
8ETM_B2greenVisible green (Enhanced Thematic Mapper Plus)0.560.08
9ETM_B3redVisible red (Enhanced Thematic Mapper Plus)0.660.06
10ETM_B4nir08Near infrared (Enhanced Thematic Mapper Plus)0.840.13
11ETM_B5swir16Short-wave infrared (Enhanced Thematic Mapper ...1.650.20
12ETM_B6lwirLong-wave infrared (Enhanced Thematic Mapper P...11.342.05
13ETM_B7swir22Short-wave infrared (Enhanced Thematic Mapper ...2.200.28
14OLI_B1coastalCoastal/Aerosol (Operational Land Imager)0.440.02
15OLI_B2blueVisible blue (Operational Land Imager)0.480.06
16OLI_B3greenVisible green (Operational Land Imager)0.560.06
17OLI_B4redVisible red (Operational Land Imager)0.650.04
18OLI_B5nir08Near infrared (Operational Land Imager)0.870.03
19OLI_B6swir16Short-wave infrared (Operational Land Imager)1.610.09
20OLI_B7swir22Short-wave infrared (Operational Land Imager)2.200.19
21TIRS_B10lwir11Long-wave infrared (Thermal Infrared Sensor)10.900.59
\n", "
" ], "text/plain": [ " name common_name description \\\n", "0 TM_B1 blue Visible blue (Thematic Mapper) \n", "1 TM_B2 green Visible green (Thematic Mapper) \n", "2 TM_B3 red Visible red (Thematic Mapper) \n", "3 TM_B4 nir08 Near infrared (Thematic Mapper) \n", "4 TM_B5 swir16 Short-wave infrared (Thematic Mapper) \n", "5 TM_B6 lwir Long-wave infrared (Thematic Mapper) \n", "6 TM_B7 swir22 Short-wave infrared (Thematic Mapper) \n", "7 ETM_B1 blue Visible blue (Enhanced Thematic Mapper Plus) \n", "8 ETM_B2 green Visible green (Enhanced Thematic Mapper Plus) \n", "9 ETM_B3 red Visible red (Enhanced Thematic Mapper Plus) \n", "10 ETM_B4 nir08 Near infrared (Enhanced Thematic Mapper Plus) \n", "11 ETM_B5 swir16 Short-wave infrared (Enhanced Thematic Mapper ... \n", "12 ETM_B6 lwir Long-wave infrared (Enhanced Thematic Mapper P... \n", "13 ETM_B7 swir22 Short-wave infrared (Enhanced Thematic Mapper ... \n", "14 OLI_B1 coastal Coastal/Aerosol (Operational Land Imager) \n", "15 OLI_B2 blue Visible blue (Operational Land Imager) \n", "16 OLI_B3 green Visible green (Operational Land Imager) \n", "17 OLI_B4 red Visible red (Operational Land Imager) \n", "18 OLI_B5 nir08 Near infrared (Operational Land Imager) \n", "19 OLI_B6 swir16 Short-wave infrared (Operational Land Imager) \n", "20 OLI_B7 swir22 Short-wave infrared (Operational Land Imager) \n", "21 TIRS_B10 lwir11 Long-wave infrared (Thermal Infrared Sensor) \n", "\n", " center_wavelength full_width_half_max \n", "0 0.49 0.07 \n", "1 0.56 0.08 \n", "2 0.66 0.06 \n", "3 0.83 0.14 \n", "4 1.65 0.20 \n", "5 11.45 2.10 \n", "6 2.22 0.27 \n", "7 0.48 0.07 \n", "8 0.56 0.08 \n", "9 0.66 0.06 \n", "10 0.84 0.13 \n", "11 1.65 0.20 \n", "12 11.34 2.05 \n", "13 2.20 0.28 \n", "14 0.44 0.02 \n", "15 0.48 0.06 \n", "16 0.56 0.06 \n", "17 0.65 0.04 \n", "18 0.87 0.03 \n", "19 1.61 0.09 \n", "20 2.20 0.19 \n", "21 10.90 0.59 " ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "\n", "landsat = catalog.get_collection(\"landsat-c2-l2\")\n", "\n", "pd.DataFrame(landsat.summaries.get_list(\"eo:bands\"))" ] }, { "cell_type": "markdown", "id": "4ae651c0", "metadata": {}, "source": [ "We can see what [Assets](https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md#asset-object) are available on our item with:" ] }, { "cell_type": "code", "execution_count": 18, "id": "4bb2b985-f18d-4161-9331-b4b259814f34", "metadata": { "tags": [] }, "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", " \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", " \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", "
titledescriptiongsd
qaSurface Temperature Quality Assessment BandCollection 2 Level-2 Quality Assessment Band (...NaN
angAngle Coefficients FileCollection 2 Level-1 Angle Coefficients FileNaN
redRed BandNaNNaN
blueBlue BandNaNNaN
dradDownwelled Radiance BandCollection 2 Level-2 Downwelled Radiance Band ...NaN
emisEmissivity BandCollection 2 Level-2 Emissivity Band (ST_EMIS)...NaN
emsdEmissivity Standard Deviation BandCollection 2 Level-2 Emissivity Standard Devia...NaN
lwirSurface Temperature BandCollection 2 Level-2 Thermal Infrared Band (ST...NaN
tradThermal Radiance BandCollection 2 Level-2 Thermal Radiance Band (ST...NaN
uradUpwelled Radiance BandCollection 2 Level-2 Upwelled Radiance Band (S...NaN
atranAtmospheric Transmittance BandCollection 2 Level-2 Atmospheric Transmittance...NaN
cdistCloud Distance BandCollection 2 Level-2 Cloud Distance Band (ST_C...NaN
greenGreen BandNaNNaN
nir08Near Infrared Band 0.8NaNNaN
lwir11Surface Temperature BandCollection 2 Level-2 Thermal Infrared Band (ST...100.0
swir16Short-wave Infrared Band 1.6NaNNaN
swir22Short-wave Infrared Band 2.2Collection 2 Level-2 Short-wave Infrared Band ...NaN
coastalCoastal/Aerosol BandCollection 2 Level-2 Coastal/Aerosol Band (SR_...NaN
mtl.txtProduct Metadata File (txt)Collection 2 Level-2 Product Metadata File (txt)NaN
mtl.xmlProduct Metadata File (xml)Collection 2 Level-2 Product Metadata File (xml)NaN
cloud_qaCloud Quality Assessment BandCollection 2 Level-2 Cloud Quality Assessment ...NaN
mtl.jsonProduct Metadata File (json)Collection 2 Level-2 Product Metadata File (json)NaN
qa_pixelPixel Quality Assessment BandCollection 2 Level-1 Pixel Quality Assessment ...NaN
qa_radsatNaNNaNNaN
qa_aerosolAerosol Quality Assessment BandCollection 2 Level-2 Aerosol Quality Assessmen...NaN
atmos_opacityAtmospheric Opacity BandCollection 2 Level-2 Atmospheric Opacity Band ...NaN
\n", "
" ], "text/plain": [ " title \\\n", "qa Surface Temperature Quality Assessment Band \n", "ang Angle Coefficients File \n", "red Red Band \n", "blue Blue Band \n", "drad Downwelled Radiance Band \n", "emis Emissivity Band \n", "emsd Emissivity Standard Deviation Band \n", "lwir Surface Temperature Band \n", "trad Thermal Radiance Band \n", "urad Upwelled Radiance Band \n", "atran Atmospheric Transmittance Band \n", "cdist Cloud Distance Band \n", "green Green Band \n", "nir08 Near Infrared Band 0.8 \n", "lwir11 Surface Temperature Band \n", "swir16 Short-wave Infrared Band 1.6 \n", "swir22 Short-wave Infrared Band 2.2 \n", "coastal Coastal/Aerosol Band \n", "mtl.txt Product Metadata File (txt) \n", "mtl.xml Product Metadata File (xml) \n", "cloud_qa Cloud Quality Assessment Band \n", "mtl.json Product Metadata File (json) \n", "qa_pixel Pixel Quality Assessment Band \n", "qa_radsat NaN \n", "qa_aerosol Aerosol Quality Assessment Band \n", "atmos_opacity Atmospheric Opacity Band \n", "\n", " description gsd \n", "qa Collection 2 Level-2 Quality Assessment Band (... NaN \n", "ang Collection 2 Level-1 Angle Coefficients File NaN \n", "red NaN NaN \n", "blue NaN NaN \n", "drad Collection 2 Level-2 Downwelled Radiance Band ... NaN \n", "emis Collection 2 Level-2 Emissivity Band (ST_EMIS)... NaN \n", "emsd Collection 2 Level-2 Emissivity Standard Devia... NaN \n", "lwir Collection 2 Level-2 Thermal Infrared Band (ST... NaN \n", "trad Collection 2 Level-2 Thermal Radiance Band (ST... NaN \n", "urad Collection 2 Level-2 Upwelled Radiance Band (S... NaN \n", "atran Collection 2 Level-2 Atmospheric Transmittance... NaN \n", "cdist Collection 2 Level-2 Cloud Distance Band (ST_C... NaN \n", "green NaN NaN \n", "nir08 NaN NaN \n", "lwir11 Collection 2 Level-2 Thermal Infrared Band (ST... 100.0 \n", "swir16 NaN NaN \n", "swir22 Collection 2 Level-2 Short-wave Infrared Band ... NaN \n", "coastal Collection 2 Level-2 Coastal/Aerosol Band (SR_... NaN \n", "mtl.txt Collection 2 Level-2 Product Metadata File (txt) NaN \n", "mtl.xml Collection 2 Level-2 Product Metadata File (xml) NaN \n", "cloud_qa Collection 2 Level-2 Cloud Quality Assessment ... NaN \n", "mtl.json Collection 2 Level-2 Product Metadata File (json) NaN \n", "qa_pixel Collection 2 Level-1 Pixel Quality Assessment ... NaN \n", "qa_radsat NaN NaN \n", "qa_aerosol Collection 2 Level-2 Aerosol Quality Assessmen... NaN \n", "atmos_opacity Collection 2 Level-2 Atmospheric Opacity Band ... NaN " ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.DataFrame.from_dict(landsat.extra_fields[\"item_assets\"], orient=\"index\")[\n", " [\"title\", \"description\", \"gsd\"]\n", "]" ] }, { "cell_type": "markdown", "id": "d951c06c-8d3a-47e7-8067-47fe4e9d4ccf", "metadata": {}, "source": [ "Some collections, like [Daymet](https://planetarycomputer.microsoft.com/dataset/daymet-daily-na) include collection-level assets. You can use the `.assets` property to access those assets." ] }, { "cell_type": "code", "execution_count": 19, "id": "c2ffb4ee-2714-4bf0-8445-5d90fcc2520c", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "collection = catalog.get_collection(\"daymet-daily-na\")\n", "print(collection)" ] }, { "cell_type": "markdown", "id": "520e7e3f-b189-4ce3-b5f1-11211e474d1b", "metadata": {}, "source": [ "Just like assets on items, these assets include links to data in Azure Blob Storage." ] }, { "cell_type": "code", "execution_count": 20, "id": "08b95491-3994-4cc5-8b24-ba113874835f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "asset = collection.assets[\"zarr-abfs\"]\n", "print(asset)" ] }, { "cell_type": "code", "execution_count": 21, "id": "58b7f436-d739-40d8-93bc-631a2295709a", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:                  (time: 14965, y: 8075, x: 7814, nv: 2)\n",
       "Coordinates:\n",
       "    lat                      (y, x) float32 dask.array<chunksize=(284, 584), meta=np.ndarray>\n",
       "    lon                      (y, x) float32 dask.array<chunksize=(284, 584), meta=np.ndarray>\n",
       "  * time                     (time) datetime64[ns] 1980-01-01T12:00:00 ... 20...\n",
       "  * x                        (x) float32 -4.56e+06 -4.559e+06 ... 3.253e+06\n",
       "  * y                        (y) float32 4.984e+06 4.983e+06 ... -3.09e+06\n",
       "Dimensions without coordinates: nv\n",
       "Data variables:\n",
       "    dayl                     (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    lambert_conformal_conic  int16 ...\n",
       "    prcp                     (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    srad                     (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    swe                      (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    time_bnds                (time, nv) datetime64[ns] dask.array<chunksize=(365, 2), meta=np.ndarray>\n",
       "    tmax                     (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    tmin                     (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    vp                       (time, y, x) float32 dask.array<chunksize=(365, 284, 584), meta=np.ndarray>\n",
       "    yearday                  (time) int16 dask.array<chunksize=(365,), meta=np.ndarray>\n",
       "Attributes:\n",
       "    Conventions:       CF-1.6\n",
       "    Version_data:      Daymet Data Version 4.0\n",
       "    Version_software:  Daymet Software Version 4.0\n",
       "    citation:          Please see http://daymet.ornl.gov/ for current Daymet ...\n",
       "    references:        Please see http://daymet.ornl.gov/ for current informa...\n",
       "    source:            Daymet Software Version 4.0\n",
       "    start_year:        1980
" ], "text/plain": [ "\n", "Dimensions: (time: 14965, y: 8075, x: 7814, nv: 2)\n", "Coordinates:\n", " lat (y, x) float32 dask.array\n", " lon (y, x) float32 dask.array\n", " * time (time) datetime64[ns] 1980-01-01T12:00:00 ... 20...\n", " * x (x) float32 -4.56e+06 -4.559e+06 ... 3.253e+06\n", " * y (y) float32 4.984e+06 4.983e+06 ... -3.09e+06\n", "Dimensions without coordinates: nv\n", "Data variables:\n", " dayl (time, y, x) float32 dask.array\n", " lambert_conformal_conic int16 ...\n", " prcp (time, y, x) float32 dask.array\n", " srad (time, y, x) float32 dask.array\n", " swe (time, y, x) float32 dask.array\n", " time_bnds (time, nv) datetime64[ns] dask.array\n", " tmax (time, y, x) float32 dask.array\n", " tmin (time, y, x) float32 dask.array\n", " vp (time, y, x) float32 dask.array\n", " yearday (time) int16 dask.array\n", "Attributes:\n", " Conventions: CF-1.6\n", " Version_data: Daymet Data Version 4.0\n", " Version_software: Daymet Software Version 4.0\n", " citation: Please see http://daymet.ornl.gov/ for current Daymet ...\n", " references: Please see http://daymet.ornl.gov/ for current informa...\n", " source: Daymet Software Version 4.0\n", " start_year: 1980" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import xarray as xr\n", "\n", "ds = xr.open_zarr(\n", " asset.href,\n", " **asset.extra_fields[\"xarray:open_kwargs\"],\n", " storage_options=asset.extra_fields[\"xarray:storage_options\"],\n", ")\n", "ds" ] }, { "cell_type": "markdown", "id": "59c4ec09-548c-42d2-805e-16b1d7875448", "metadata": {}, "source": [ "### Manually signing assets\n", "\n", "Earlier on, when we created our `pystac_client.Client`, we specified `modifier=planetary_computer.sign_inplace`. That `modifier` will automatically \"sign\" the STAC metadata, so that the assets can be accessed.\n", "\n", "Alternatively, you can manually sign the items." ] }, { "cell_type": "code", "execution_count": 22, "id": "825926df-eb00-420b-9cad-fe238a77c163", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "200" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pystac\n", "\n", "item = pystac.read_file(selected_item.get_self_href())\n", "signed_item = planetary_computer.sign(item) # these assets can be accessed\n", "requests.head(signed_item.assets[\"blue\"].href).status_code" ] }, { "cell_type": "markdown", "id": "9eb85e6d-daf5-46ad-a95c-0b542a1e6aa7", "metadata": {}, "source": [ "Internally, that `planetary_computer.sign` method is making a request to the Planetary Computer's [SAS API](http://planetarycomputer.microsoft.com/api/sas/v1/docs) to get a signed HREF for each asset. You could do that manually yourself." ] }, { "cell_type": "code", "execution_count": 23, "id": "d0759d76-453a-48a0-adac-a72d66e63dd2", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "200" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "collection = item.get_collection()\n", "storage_account = collection.extra_fields[\"msft:storage_account\"]\n", "container = collection.extra_fields[\"msft:container\"]\n", "\n", "response = requests.get(\n", " f\"https://planetarycomputer.microsoft.com/api/sas/v1/token/{collection.id}\"\n", ")\n", "\n", "signed_url = item.assets[\"blue\"].href + \"?\" + response.json()[\"token\"]\n", "\n", "requests.head(signed_url).status_code" ] }, { "cell_type": "markdown", "id": "6ea8409b-7438-4483-818f-149cafaf10df", "metadata": {}, "source": [ "See https://planetarycomputer.microsoft.com/docs/concepts/sas/ for more on how to manually sign assets." ] } ], "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.11.4" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "440fd8565ac14167ad8f04fe503e393f": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {} }, "cf3a2c0607c0407aa9b9126e344dc37a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "VBoxModel", "state": { "layout": "IPY_MODEL_440fd8565ac14167ad8f04fe503e393f" } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }