Skip to content

Commit

Permalink
Merge pull request #232 from stac-utils/pv/intersects-examples
Browse files Browse the repository at this point in the history
add tutorial about using __geo_interface__ objects for search intersects
  • Loading branch information
Phil Varner authored Jun 8, 2022
2 parents ccc9052 + aa85231 commit e4b3bd3
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- lru_cache to several methods [#167](https://github.com/stac-utils/pystac-client/pull/167)
- Direct item GET via ogcapi-features, if conformant [#166](https://github.com/stac-utils/pystac-client/pull/166)
- `py.typed` for downstream type checking [#163](https://github.com/stac-utils/pystac-client/pull/163)
- Added tutorial for using various geometry objects (e.g., shapely, geojson) as an Item Search intersects argument [#232](https://github.com/stac-utils/pystac-client/pull/232)

### Changed

Expand Down
10 changes: 10 additions & 0 deletions docs/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ CQL2 Filtering
This tutorial gives an introduction to using CQL2-JSON filtering in searches to
search by arbitrary STAC Item properties.

Item Search with Intersects
-----------------------------------------------------

- :tutorial:`GitHub version <item-search-intersects.ipynb>`
- :ref:`Docs version </tutorials/item-search-intersects.ipynb>`

This tutorial demonstrates the use of different Python library
object types that can be used for the `intersects`
search parameter.

Calculating Coverage Percentage of the AOI by an Item
-----------------------------------------------------

Expand Down
257 changes: 257 additions & 0 deletions docs/tutorials/item-search-intersects.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "e06a27bf",
"metadata": {},
"source": [
"# Item Search with Intersects\n",
"\n",
"This notebook shows the use of pystac-client to perform item search with the `intersects` parameter, to restrict the results to an Area of Interest (AOI)."
]
},
{
"cell_type": "markdown",
"id": "1e16077c",
"metadata": {},
"source": [
"# Client\n",
"\n",
"We first connect to an API by retrieving the root catalog, or landing page, of the API with the `Client.open` function."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "98942e75",
"metadata": {},
"outputs": [],
"source": [
"from pystac_client import Client\n",
"from typing import Any, Dict\n",
"import json\n",
"\n",
"# STAC API root URL\n",
"URL = 'https://planetarycomputer.microsoft.com/api/stac/v1'\n",
"\n",
"client = Client.open(URL)"
]
},
{
"cell_type": "markdown",
"id": "62e26114",
"metadata": {},
"source": [
"# Item Search\n",
"\n",
"When the Catalog is a STAC API, we have the ability to search for items based on spatio-temporal properties.\n",
"\n",
"The STAC API endpoint `/search` accepts a parameter `intersects` that is a GeoJSON Geometry representing the AOI of the search.\n",
"\n",
"The `search` method of the pystac_client `Client` class accepts several different types of objects:\n",
"\n",
"1. a string representing a GeoJSON geometry\n",
"2. a dictionary representing a GeoJSON geometry\n",
"3. any object that implements a ``__geo_interface__`` property, [an informal specification](https://gist.github.com/sgillies/2217756) \n",
" supported by several libraries for generating a GeoJSON representation from an object. Several prominent libraries support this\n",
" protocol for their objects that represent geometries, including [Shapely](https://shapely.readthedocs.io), [ArcPy](https://pro.arcgis.com/en/pro-app/2.8/arcpy/get-started/what-is-arcpy-.htm), [PySAL](https://pysal.org/), [geojson](https://github.com/jazzband/geojson), [pyshp](https://pypi.org/project/pyshp/), [descartes](https://docs.descarteslabs.com/), and [pygeoif](https://github.com/cleder/pygeoif)"
]
},
{
"cell_type": "markdown",
"id": "0d27fabf",
"metadata": {},
"source": [
"## Item Search with AOI as a Dictionary"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d8af6334",
"metadata": {},
"outputs": [],
"source": [
"# AOI around Delfzijl, in northern Netherlands\n",
"aoi_as_dict: Dict[str, Any] = {\n",
" \"type\": \"Polygon\",\n",
" \"coordinates\": [\n",
" [\n",
" [\n",
" 6,\n",
" 53\n",
" ],\n",
" [\n",
" 7,\n",
" 53\n",
" ],\n",
" [\n",
" 7,\n",
" 54\n",
" ],\n",
" [\n",
" 6,\n",
" 54\n",
" ],\n",
" [\n",
" 6,\n",
" 53\n",
" ]\n",
" ]\n",
" ]\n",
"}\n",
"\n",
"search = client.search(\n",
" max_items = 25,\n",
" collections = \"aster-l1t\",\n",
" intersects = aoi_as_dict,\n",
")\n",
"\n",
"print(f\"AOI as dictionary, found {len(list(search.items()))} items\")"
]
},
{
"cell_type": "markdown",
"id": "9da4956b",
"metadata": {},
"source": [
"## Item Search with AOI as a String"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a7c9336",
"metadata": {},
"outputs": [],
"source": [
"aoi_as_str: str = json.dumps(aoi_as_dict)\n",
"\n",
"search = client.search(\n",
" max_items = 25,\n",
" collections = \"aster-l1t\",\n",
" intersects = aoi_as_str,\n",
")\n",
"\n",
"print(f\"AOI as string, found {len(list(search.items()))} items\")"
]
},
{
"cell_type": "markdown",
"id": "9da4956b",
"metadata": {},
"source": [
"## Item Search with AOI as a Shapely Geometry Object"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a7c9336",
"metadata": {},
"outputs": [],
"source": [
"import shapely.geometry\n",
"\n",
"aoi_as_shapely_shape = shapely.geometry.shape(aoi_as_dict)\n",
"\n",
"search = client.search(\n",
" max_items = 25,\n",
" collections = \"aster-l1t\",\n",
" intersects = aoi_as_shapely_shape,\n",
")\n",
"\n",
"print(f\"AOI as Shapely Geometry object from shape(), found {len(list(search.items()))} items\")\n",
"\n",
"aoi_as_shapely_polygon = shapely.geometry.Polygon(aoi_as_dict[\"coordinates\"][0])\n",
"\n",
"search = client.search(\n",
" max_items = 25,\n",
" collections = \"aster-l1t\",\n",
" intersects = aoi_as_shapely_polygon,\n",
")\n",
"\n",
"print(f\"AOI as Shapely Geometry object with Polygon, found {len(list(search.items()))} items\")"
]
},
{
"cell_type": "markdown",
"id": "9da4956b",
"metadata": {},
"source": [
"## Item Search with AOI as a \"geojson\" library object"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a7c9336",
"metadata": {},
"outputs": [],
"source": [
"import geojson\n",
"\n",
"aoi_as_geojson_polygon = geojson.Polygon(aoi_as_dict[\"coordinates\"])\n",
"\n",
"search = client.search(\n",
" max_items = 25,\n",
" collections = \"aster-l1t\",\n",
" intersects = aoi_as_geojson_polygon,\n",
")\n",
"\n",
"print(f\"AOI as geojson Polygon, found {len(list(search.items()))} items\")"
]
},
{
"cell_type": "markdown",
"id": "9da4956b",
"metadata": {},
"source": [
"## Item Search with AOI as a pygeoif Object"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a27dcb72",
"metadata": {},
"outputs": [],
"source": [
"import pygeoif\n",
"aoi_as_pygeoif_polygon = pygeoif.geometry.Polygon(aoi_as_dict[\"coordinates\"])\n",
"\n",
"search = client.search(\n",
" max_items = 25,\n",
" collections = \"aster-l1t\",\n",
" intersects = aoi_as_pygeoif_polygon,\n",
")\n",
"\n",
"print(f\"AOI as pygeoif Polygon, found {len(list(search.items()))} items\")"
]
}
],
"metadata": {
"interpreter": {
"hash": "6b6313dbab648ff537330b996f33bf845c0da10ea77ae70864d6ca8e2699c7ea"
},
"kernelspec": {
"display_name": "Python 3.9.11 ('.venv': venv)",
"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.9.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
4 changes: 3 additions & 1 deletion requirements-docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ nbsphinx~=0.8
jinja2<4.0
geopandas~=0.10.2
hvplot~=0.8.0
matplotlib~=3.5.2
matplotlib~=3.5.2
geojson~=2.5.0
pygeoif~=0.7

0 comments on commit e4b3bd3

Please sign in to comment.