From 7ea8e59e640d083d4d85129959bac905f2f412f8 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 14 Apr 2023 16:30:54 -0500 Subject: [PATCH 1/2] Added demo for interactive browser --- tutorials/interactive-browser.ipynb | 720 ++++++++++++++++++++++++++++ 1 file changed, 720 insertions(+) create mode 100755 tutorials/interactive-browser.ipynb diff --git a/tutorials/interactive-browser.ipynb b/tutorials/interactive-browser.ipynb new file mode 100755 index 00000000..b27194af --- /dev/null +++ b/tutorials/interactive-browser.ipynb @@ -0,0 +1,720 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4a99071f-ea18-4b19-9b62-de8be5c03d72", + "metadata": {}, + "source": [ + "## Interactively browse STAC footprints\n", + "\n", + "STAC items contain information about the spatio-temporal footprint of the data they catalog. Using [Jupyter Widgets](https://ipywidgets.readthedocs.io/en/latest/#), in particular [`ipywidgets.interact`](https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html) and [`ipyleaflet`](https://ipyleaflet.readthedocs.io/en/latest/index.html), we can quickly build an interactive tool for visualizing item footprints. This can be helpful for understanding the path a satellite takes over earth, or debugging strange-looking item footprints.\n", + "\n", + "We'll start by grabbing some Sentinel-2 L2A items from the Planetary Computer's STAC API." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "242551be-9f6d-4cb6-8f55-9dcd2fe77eb3", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import pystac_client\n", + "\n", + "catalog = pystac_client.Client.open(\n", + " \"https://planetarycomputer.microsoft.com/api/stac/v1\"\n", + ")\n", + "\n", + "search = catalog.search(\n", + " collections=[\"sentinel-2-l2a\"],\n", + " datetime=\"2023-04-01\",\n", + " query={\"platform\": {\"eq\": \"Sentinel-2B\"}},\n", + " sortby=\"datetime\",\n", + " max_items=200,\n", + ")\n", + "\n", + "items = search.item_collection()" + ] + }, + { + "cell_type": "markdown", + "id": "d13aea35-99d2-4445-8f44-9d257374abaa", + "metadata": {}, + "source": [ + "Next, we'll build up our tool. We start with our placeholders:\n", + "\n", + "1. An `ipyleaflet.Map` object\n", + "2. An empty `ipyleaflet.GeoJSON` layer, which we add to the map\n", + "\n", + "Then we use `ipywidgets.interact` to browse the list of items. This gives us a dropdown with the list of items, which we can scroll through to select a single item for display.\n", + "The body of the function updates the state of our map to set\n", + "\n", + "1. The center of the map to the center of the selected item\n", + "2. The `data` for the GeoJSON layer, to display the selected item's footprint\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2b5bad41-e5a9-446d-9ad6-a2d4ce52aca0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "795afd00707f42519109e9b58245362e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(Dropdown(description='item', options=(\n", + "" + ] + } + ], + "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.9" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": { + "05afbd624478496fa8acafb97fc360a2": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletTileLayerModel", + "state": { + "_model_module_version": "^0.17", + "_view_module_version": "^0.17", + "attribution": "© OpenStreetMap contributors", + "base": true, + "max_zoom": 19, + "min_zoom": 1, + "name": "OpenStreetMap.Mapnik", + "options": [ + "attribution", + "bounds", + "detect_retina", + "max_native_zoom", + "max_zoom", + "min_native_zoom", + "min_zoom", + "no_wrap", + "tile_size", + "tms", + "zoom_offset" + ], + "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png" + } + }, + "0750b850aaba4f93affa2b88e632aa49": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "132be69b28844b76ab858f92d74d3e24": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "DescriptionStyleModel", + "state": { + "description_width": "" + } + }, + "39599c9a46ca4b16945ea4de5f78a6ba": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletAttributionControlModel", + "state": { + "_model_module_version": "^0.17", + "_view_module_version": "^0.17", + "options": [ + "position", + "prefix" + ], + "position": "bottomright", + "prefix": "ipyleaflet" + } + }, + "3c4373d83d3f42c3a4a3e35f98910bb2": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "width": "600px" + } + }, + "72e04529034c4aadbc8ee000c14498a0": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "795afd00707f42519109e9b58245362e": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "VBoxModel", + "state": { + "_dom_classes": [ + "widget-interact" + ], + "children": [ + "IPY_MODEL_cecfb0ae5d1345d993c80a08a3bcc475", + "IPY_MODEL_cbb7ad77c5de40db9e6eed6953e1087d" + ], + "layout": "IPY_MODEL_0750b850aaba4f93affa2b88e632aa49" + } + }, + "9f75ebb880dd4da8a54049083dcf81c0": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletGeoJSONModel", + "state": { + "_model_module_version": "^0.17", + "_view_module_version": "^0.17", + "data": { + "coordinates": [ + [ + [ + 149.156579, + -1.062179 + ], + [ + 149.1566143, + -1.0620175 + ], + [ + 149.1569676, + -1.0621077 + ], + [ + 149.1574643, + -1.0598367 + ], + [ + 149.3884043, + -1.1234127 + ], + [ + 149.3558375, + -1.2722149 + ], + [ + 149.3233036, + -1.4209901 + ], + [ + 149.3195944, + -1.437957 + ], + [ + 149.2908642, + -1.5690073 + ], + [ + 149.2582501, + -1.7176229 + ], + [ + 149.2256726, + -1.8661824 + ], + [ + 149.2190812, + -1.8962567 + ], + [ + 148.7976723, + -1.8968179 + ], + [ + 148.7969634, + -0.9665262 + ], + [ + 148.9032672, + -0.993601 + ], + [ + 148.9445828, + -1.0041557 + ], + [ + 148.9531019, + -1.0063451 + ], + [ + 148.9528155, + -1.0076522 + ], + [ + 148.9531448, + -1.0077372 + ], + [ + 148.9531199, + -1.0078509 + ], + [ + 148.9532154, + -1.0078757 + ], + [ + 148.9531189, + -1.008315 + ], + [ + 148.9533063, + -1.0083635 + ], + [ + 148.9532136, + -1.0087869 + ], + [ + 148.9533906, + -1.0088326 + ], + [ + 148.9533662, + -1.008944 + ], + [ + 148.9534674, + -1.0089701 + ], + [ + 148.9532066, + -1.010161 + ], + [ + 149.156579, + -1.062179 + ] + ] + ], + "type": "Polygon" + } + } + }, + "a7dd1266ed094e2da6b0caf398647843": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletMapStyleModel", + "state": { + "_model_module_version": "^0.17" + } + }, + "bfeb82a071f64b9f9f3190dfa28a7c4d": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletMapStyleModel", + "state": { + "_model_module_version": "^0.17", + "cursor": "move" + } + }, + "cbb7ad77c5de40db9e6eed6953e1087d": { + "model_module": "@jupyter-widgets/output", + "model_module_version": "1.0.0", + "model_name": "OutputModel", + "state": { + "layout": "IPY_MODEL_72e04529034c4aadbc8ee000c14498a0", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "S2B_MSIL2A_20230401T003709_R059_T55MGU_20230401T043754 2023-04-01T00:37:09.024000+00:00\n" + } + ] + } + }, + "cbddc0bd7fc5460d90a6ee97ee068841": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + }, + "cecfb0ae5d1345d993c80a08a3bcc475": { + "model_module": "@jupyter-widgets/controls", + "model_module_version": "2.0.0", + "model_name": "DropdownModel", + "state": { + "_options_labels": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + "description": "item", + "index": 199, + "layout": "IPY_MODEL_cbddc0bd7fc5460d90a6ee97ee068841", + "style": "IPY_MODEL_132be69b28844b76ab858f92d74d3e24" + } + }, + "d98fca441cc247eab1410fda85e6981b": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletMapModel", + "state": { + "_model_module_version": "^0.17", + "_view_module_version": "^0.17", + "bottom": 1232, + "center": [ + -1.4061088354351594, + 149.06250000000003 + ], + "controls": [ + "IPY_MODEL_de844a3f020f4873b7f5bceeb6f9cc72", + "IPY_MODEL_39599c9a46ca4b16945ea4de5f78a6ba" + ], + "default_style": "IPY_MODEL_a7dd1266ed094e2da6b0caf398647843", + "dragging_style": "IPY_MODEL_bfeb82a071f64b9f9f3190dfa28a7c4d", + "east": 201.79687500000003, + "fullscreen": false, + "interpolation": "bilinear", + "layers": [ + "IPY_MODEL_05afbd624478496fa8acafb97fc360a2", + "IPY_MODEL_9f75ebb880dd4da8a54049083dcf81c0" + ], + "layout": "IPY_MODEL_3c4373d83d3f42c3a4a3e35f98910bb2", + "left": 1572, + "modisdate": "2023-04-13", + "north": 31.952162238024975, + "options": [ + "bounce_at_zoom_limits", + "box_zoom", + "center", + "close_popup_on_click", + "double_click_zoom", + "dragging", + "fullscreen", + "inertia", + "inertia_deceleration", + "inertia_max_speed", + "interpolation", + "keyboard", + "keyboard_pan_offset", + "keyboard_zoom_offset", + "max_zoom", + "min_zoom", + "prefer_canvas", + "scroll_wheel_zoom", + "tap", + "tap_tolerance", + "touch_zoom", + "world_copy_jump", + "zoom", + "zoom_animation_threshold", + "zoom_delta", + "zoom_snap" + ], + "prefer_canvas": false, + "right": 2172, + "south": -34.30714385628803, + "style": "IPY_MODEL_a7dd1266ed094e2da6b0caf398647843", + "top": 832, + "west": 96.32812500000001, + "window_url": "https://pcc-staging.westeurope.cloudapp.azure.com/compute/user/taugspurger@microsoft.com/lab/tree/sentinel-3/interactive-browser.ipynb", + "zoom": 3 + } + }, + "de844a3f020f4873b7f5bceeb6f9cc72": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletZoomControlModel", + "state": { + "_model_module_version": "^0.17", + "_view_module_version": "^0.17", + "options": [ + "position", + "zoom_in_text", + "zoom_in_title", + "zoom_out_text", + "zoom_out_title" + ] + } + }, + "e9f1ece44ab74fcc88223b3082d63ad3": { + "model_module": "jupyter-leaflet", + "model_module_version": "^0.17", + "model_name": "LeafletMapStyleModel", + "state": { + "_model_module_version": "^0.17" + } + } + }, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 4ba46760a7cca42c51f972324808e16775824b01 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 14 Apr 2023 16:33:43 -0500 Subject: [PATCH 2/2] Update interactive-browser.ipynb --- tutorials/interactive-browser.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/interactive-browser.ipynb b/tutorials/interactive-browser.ipynb index b27194af..d6829d10 100755 --- a/tutorials/interactive-browser.ipynb +++ b/tutorials/interactive-browser.ipynb @@ -7,7 +7,7 @@ "source": [ "## Interactively browse STAC footprints\n", "\n", - "STAC items contain information about the spatio-temporal footprint of the data they catalog. Using [Jupyter Widgets](https://ipywidgets.readthedocs.io/en/latest/#), in particular [`ipywidgets.interact`](https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html) and [`ipyleaflet`](https://ipyleaflet.readthedocs.io/en/latest/index.html), we can quickly build an interactive tool for visualizing item footprints. This can be helpful for understanding the path a satellite takes over earth, or debugging strange-looking item footprints.\n", + "STAC items contain information about the spatio-temporal footprint of the data they catalog. Using [Jupyter Widgets](https://ipywidgets.readthedocs.io/en/latest/#), in particular [`ipywidgets.interact`](https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html) and [`ipyleaflet`](https://ipyleaflet.readthedocs.io/en/latest/index.html), we can quickly build an interactive tool for visualizing item footprints. This can be helpful for understanding the path a satellite takes over earth or debugging strange looking item footprints.\n", "\n", "We'll start by grabbing some Sentinel-2 L2A items from the Planetary Computer's STAC API." ]