Created
November 3, 2023 12:04
-
-
Save emileten/6409461a6a3ce157f6b7a680fd15b928 to your computer and use it in GitHub Desktop.
tiling.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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