Skip to content

Instantly share code, notes, and snippets.

@emileten
Created November 3, 2023 12:04
Show Gist options
  • Save emileten/6409461a6a3ce157f6b7a680fd15b928 to your computer and use it in GitHub Desktop.
Save emileten/6409461a6a3ce157f6b7a680fd15b928 to your computer and use it in GitHub Desktop.
tiling.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "e91fe3e6-66e5-452e-a8be-95186d1c67fd",
"metadata": {},
"source": [
"In this notebook, we try to visualize items and a mosaic of these items based off of this STAC collection https://stac.dit.maap-project.org/collections/tri_seasonal_s1_sar_composites.\n",
"\n",
"This notebook has two sections : \n",
"\n",
"- the first visualizes a single item (the VH band), based on `item_id` set up below.\n",
"- the second visualizes a small set of several items (just the VH band), based on the bounding box set up below\n",
"\n",
"The first part works fine, the second does not. First, I tried to scale at 200-300 items, and nothing was rendered. It's either a performance issue in the backend or the way I am doing things. With a smaller set, corresponding to the current bounding box, something gets rendered but not properly."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "971482ff-4c3c-4f42-b9b5-688c8a649633",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from pystac_client import Client\n",
"import httpx\n",
"import requests\n",
"import json\n",
"import ipyleaflet\n",
"import pprint"
]
},
{
"cell_type": "markdown",
"id": "47c0b097-e2a3-4b68-9190-dc76c543570a",
"metadata": {},
"source": [
"## Parameters"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "310d152d-1765-4544-9935-f86174635eec",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"stac_endpoint = 'https://stac.dit.maap-project.org' # STAC test (\"dit\") catalog\n",
"raster_endpoint = 'https://titiler-pgstac.dit.maap-project.org' # Raster (\"Tiler\") URL to return images of single items or groups (mosaics) of items\n",
"item_id = 's1_vv_vh_gamma_2018_pwr_tile26-subtile000657_summer' # Example item to map\n",
"collection_id = 'tri_seasonal_s1_sar_composites' # Collection name in the catalog\n",
"bbox = [164.92713344724163, 66.19477557086134, 165.5038251819586, 66.42160323944826] # bbox for the mosaic. "
]
},
{
"cell_type": "markdown",
"id": "727ab9a3-47bc-4f42-a809-8aafa0f9a673",
"metadata": {},
"source": [
"### Load the example item"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "5636bc56-1e85-4901-9fee-c17207b3fc0c",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"s1_vv_vh_gamma_2018_pwr_tile26-subtile000657_summer\n"
]
}
],
"source": [
"item = json.loads(httpx.get(f\"{stac_endpoint}/collections/{collection_id}/items/{item_id}\").text)\n",
"print(item['id'])"
]
},
{
"cell_type": "markdown",
"id": "838ffc88-ea7c-46d9-9efe-6cdc61fab5db",
"metadata": {},
"source": [
"### Get the \"tilejson\" for this item, which provides its bounds, and the URL to use to get the image of the asset"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "db02953b-0ea3-45a6-8764-ba4cd8a7d23d",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'tilejson': '2.2.0', 'version': '1.0.0', 'scheme': 'xyz', 'tiles': ['https://titiler-pgstac.dit.maap-project.org/collections/tri_seasonal_s1_sar_composites/items/s1_vv_vh_gamma_2018_pwr_tile26-subtile000657_summer/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?assets=VH'], 'minzoom': 8, 'maxzoom': 11, 'bounds': [164.92713344724163, 66.19477557086134, 165.5038251819586, 66.42160323944826], 'center': [165.21547931460012, 66.30818940515479, 8]}\n"
]
}
],
"source": [
"tilejson = httpx.get(\n",
" f\"{raster_endpoint}/collections/{collection_id}/items/{item_id}/tilejson.json\",\n",
" params = (\n",
" (\"assets\", \"VH\"), \n",
" (\"minzoom\", 8), # the minimum zoom level at which the data will be displayed on the map\n",
" (\"maxzoom\", 11), # the maximum zoom level at which the data will be displayed on the map\n",
" )\n",
").json()\n",
"print(tilejson)"
]
},
{
"cell_type": "markdown",
"id": "23879dd3-7eda-42d1-ae14-cb281adf1650",
"metadata": {},
"source": [
"### Create a background map with ipyleaflet, centered around the bounds of the item, with a layer showing the location of the item and a layer displaying the image"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5d09c2f0-1a5e-4a27-92a1-7c03a54b3321",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "eeafd2f129ea46d8afb6ab52cd86d3f0",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Map(center=[66.30818940515479, 165.21547931460012], controls=(ZoomControl(options=['position', 'zoom_in_text',…"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# this is the base map\n",
"bounds = tilejson[\"bounds\"]\n",
"m = ipyleaflet.leaflet.Map(\n",
" center=((bounds[1] + bounds[3]) / 2,(bounds[0] + bounds[2]) / 2),\n",
" zoom=8\n",
")\n",
"\n",
"# add a layer that draws a polygon showing the item boundaries\n",
"geo_json = ipyleaflet.leaflet.GeoJSON(\n",
" data=item,\n",
" style={\n",
" 'opacity': 1, 'dashArray': '9', 'fillOpacity': 0., 'weight': 4\n",
" }\n",
")\n",
"m.add_layer(geo_json)\n",
"\n",
"\n",
"# add the image with the tile URL from the \"tilejson\"\n",
"\n",
"tiles = ipyleaflet.leaflet.TileLayer(\n",
" url=tilejson[\"tiles\"][0],\n",
" min_zoom=tilejson[\"minzoom\"],\n",
" max_zoom=tilejson[\"maxzoom\"],\n",
" bounds=[\n",
" [bounds[1], bounds[0]],\n",
" [bounds[3], bounds[2]],\n",
"\n",
" ],\n",
")\n",
"\n",
"m.add_layer(tiles)\n",
"\n",
"\n",
"# show the map\n",
"m"
]
},
{
"cell_type": "markdown",
"id": "e1f24361-c30f-4ba8-bdc6-e934cfc68c50",
"metadata": {},
"source": [
"## Plot a mosaic of all the items in the specified bounding box"
]
},
{
"cell_type": "markdown",
"id": "ec8c9ded-3194-4e58-b15e-fe78c1247967",
"metadata": {},
"source": [
"### Counting the number of items in this bbox"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "1fae1d27-9e1e-4532-b5b8-ffbe457ddc93",
"metadata": {},
"outputs": [],
"source": [
"from pystac_client import Client\n",
"\n",
"catalog = Client.open(stac_endpoint)\n",
"\n",
"results = catalog.search(\n",
" bbox=bbox,\n",
" collections=[collection_id],\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "68831de3-76d0-4f3c-9e0c-f16eccf839b4",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"items = []\n",
"for item in results.items():\n",
" items.append(item.to_dict())"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "12568e4e-3aef-4958-adde-1dce70062123",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"9\n"
]
}
],
"source": [
"print(len(items))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "76f1464f-6860-49f0-8edd-0ef740294aa5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"search_request = {\n",
" # Filter collection\n",
" \"collections\": [collection_id],\n",
" \"bbox\": bbox,\n",
" \"filter-lang\": \"cql2-json\",\n",
" \"limit\":10\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "752634f2-7f9c-413e-9fa9-1af77415b1aa",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"mosaic = httpx.post(\n",
" f\"{raster_endpoint}/mosaic/register\",\n",
" data=json.dumps(\n",
" search_request\n",
" ),\n",
" timeout=60\n",
").json()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "cb71dbd5-a3d0-44d3-ad9d-76e77bcb83f0",
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/plain": [
"{'searchid': '2ec2c70120d867281399a6b09101af7d',\n",
" 'links': [{'rel': 'metadata',\n",
" 'type': 'application/json',\n",
" 'href': 'https://titiler-pgstac.dit.maap-project.org/mosaic/2ec2c70120d867281399a6b09101af7d/info'},\n",
" {'rel': 'tilejson',\n",
" 'type': 'application/json',\n",
" 'href': 'https://titiler-pgstac.dit.maap-project.org/mosaic/2ec2c70120d867281399a6b09101af7d/tilejson.json'}]}"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mosaic"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "cc77cf8f-ee84-40e0-8c5c-be634eb5b92d",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"mosaic_id = mosaic['searchid']"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "6be26a47-22bd-41c4-bbd2-a218d5c50df9",
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'tilejson': '2.2.0', 'name': '2ec2c70120d867281399a6b09101af7d', 'version': '1.0.0', 'scheme': 'xyz', 'tiles': ['https://titiler-pgstac.dit.maap-project.org/mosaic/2ec2c70120d867281399a6b09101af7d/tiles/WebMercatorQuad/{z}/{x}/{y}?assets=VH'], 'minzoom': 2, 'maxzoom': 11, 'bounds': [164.92713344724163, 66.19477557086134, 165.5038251819586, 66.42160323944826], 'center': [165.21547931460012, 66.30818940515479, 2]}\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "51bd4efbd7bf472d9eb669d5a8b78488",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Map(center=[66.30818940515479, 165.21547931460012], controls=(ZoomControl(options=['position', 'zoom_in_text',…"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tilejson_mosaic = httpx.get(\n",
" f\"{raster_endpoint}/mosaic/{mosaic_id}/tilejson.json\",\n",
" params = (\n",
" (\"assets\", \"VH\"), # THIS IS MANDATORY\n",
" (\"minzoom\", 2),\n",
" (\"maxzoom\", 11), \n",
" )\n",
").json()\n",
"print(tilejson_mosaic)\n",
"\n",
"bounds = tilejson_mosaic[\"bounds\"]\n",
"m = ipyleaflet.leaflet.Map(\n",
" center=((bounds[1] + bounds[3]) / 2,(bounds[0] + bounds[2]) / 2),\n",
" zoom=2\n",
")\n",
"\n",
"geo_json = ipyleaflet.leaflet.GeoJSON(\n",
" data={\"type\": \"FeatureCollection\", \"features\": items}, \n",
" style={\n",
" 'opacity': 1, 'dashArray': '9', 'fillOpacity': 0., 'weight': 4\n",
" },\n",
")\n",
"m.add_layer(geo_json)\n",
"\n",
"tiles = ipyleaflet.leaflet.TileLayer(\n",
" url=tilejson_mosaic[\"tiles\"][0],\n",
" min_zoom=tilejson_mosaic[\"minzoom\"],\n",
" max_zoom=tilejson_mosaic[\"maxzoom\"],\n",
" bounds=[\n",
" [bbox[1], bbox[0]],\n",
" [bbox[3], bbox[2]],\n",
"\n",
" ],\n",
")\n",
"\n",
"m.add_layer(tiles)\n",
"m"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f8ce292a-5ebd-4a3f-acab-158caaa523c7",
"metadata": {},
"outputs": [],
"source": []
}
],
"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.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment