From 19c4b71d0b5a2924be3d10cf0e291d10a927b61f Mon Sep 17 00:00:00 2001 From: Qiusheng Wu Date: Wed, 25 Oct 2023 13:18:48 -0400 Subject: [PATCH] Add notebook 138 for using draw control (#1798) * Add notebook 138 for using draw control * Add notebook 138 to docs --- docs/notebooks/138_draw_control.ipynb | 173 ++++++++++++++++++++++ docs/tutorials.md | 1 + examples/README.md | 1 + examples/notebooks/138_draw_control.ipynb | 173 ++++++++++++++++++++++ 4 files changed, 348 insertions(+) create mode 100644 docs/notebooks/138_draw_control.ipynb create mode 100644 examples/notebooks/138_draw_control.ipynb diff --git a/docs/notebooks/138_draw_control.ipynb b/docs/notebooks/138_draw_control.ipynb new file mode 100644 index 0000000000..64ecdd51cb --- /dev/null +++ b/docs/notebooks/138_draw_control.ipynb @@ -0,0 +1,173 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Open\n", + "\n", + "**Clip Earth Engine images interactively with the Draw Control**\n", + "\n", + "Uncomment the following line to install [geemap](https://geemap.org) if needed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install -U geemap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ee\n", + "import geemap\n", + "import ipywidgets as widgets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add some Earth Engine data to the map, then you can use the draw control and a button widget to clip the Earth Engine data by the drawn polygons. \n", + "\n", + "The drawn geometries can be retrieved as either an ee.Geometry object (`m.user_roi`) or ee.FeatureCollection (`m._user_rois`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "self = geemap.Map(center=[0, 9.31], zoom=3)\n", + "image = ee.Image('USGS/SRTMGL1_003')\n", + "vis_params = {\n", + " 'min': 0,\n", + " 'max': 6000,\n", + " 'palette': 'terrain',\n", + "}\n", + "self.add_layer(image, vis_params, 'SRTM')\n", + "\n", + "clip_btn = widgets.Button(description='Clip Image')\n", + "reset_btn = widgets.Button(description='Reset')\n", + "\n", + "def on_clip_btn_clicked(b):\n", + " if self.user_roi is not None:\n", + " try:\n", + " clipped_image = image.clip(self.user_roi)\n", + " self.add_layer(clipped_image, vis_params, 'Clipped Image')\n", + " self.find_layer('SRTM').visible = False\n", + " except:\n", + " pass\n", + "\n", + "clip_btn.on_click(on_clip_btn_clicked)\n", + "\n", + "def on_reset_btn_clicked(b):\n", + " self._draw_control.clear()\n", + " self.find_layer('SRTM').visible = True\n", + " self.layers = self.layers[:3]\n", + "\n", + "reset_btn.on_click(on_reset_btn_clicked)\n", + "\n", + "widget = widgets.VBox([clip_btn, reset_btn])\n", + "self.add_widget(widget, position='bottomright')\n", + "self" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a solara web app." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ee\n", + "import geemap\n", + "import solara\n", + "import ipywidgets as widgets\n", + "\n", + "\n", + "class Map(geemap.Map):\n", + " def __init__(self, **kwargs):\n", + " super().__init__(**kwargs)\n", + "\n", + " image = ee.Image('USGS/SRTMGL1_003')\n", + " vis_params = {\n", + " 'min': 0,\n", + " 'max': 6000,\n", + " 'palette': 'terrain',\n", + " }\n", + " self.add_layer(image, vis_params, 'SRTM')\n", + "\n", + " clip_btn = widgets.Button(description='Clip Image')\n", + " reset_btn = widgets.Button(description='Reset')\n", + "\n", + " def on_clip_btn_clicked(b):\n", + " if self.user_roi is not None:\n", + " try:\n", + " clipped_image = image.clip(self.user_roi)\n", + " self.add_layer(clipped_image, vis_params, 'Clipped Image')\n", + " self.find_layer('SRTM').visible = False\n", + " except:\n", + " pass\n", + "\n", + " clip_btn.on_click(on_clip_btn_clicked)\n", + "\n", + " def on_reset_btn_clicked(b):\n", + " self._draw_control.clear()\n", + " self.find_layer('SRTM').visible = True\n", + " self.layers = self.layers[:3]\n", + "\n", + " reset_btn.on_click(on_reset_btn_clicked)\n", + "\n", + " widget = widgets.VBox([clip_btn, reset_btn])\n", + " self.add_widget(widget, position='bottomright')\n", + "\n", + "\n", + "@solara.component\n", + "def Page():\n", + " with solara.Column(style={\"min-width\": \"500px\"}):\n", + " Map.element(\n", + " center=[0, 9.31],\n", + " zoom=3,\n", + " height=\"600px\",\n", + " )\n", + "Page()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/tutorials.md b/docs/tutorials.md index 717a720001..2df77703c9 100644 --- a/docs/tutorials.md +++ b/docs/tutorials.md @@ -149,3 +149,4 @@ More video tutorials for geemap and Earth Engine are available on my [YouTube ch 135. Earth Engine Image Segmentation with the Segment Anything Model ([notebook](https://geemap.org/notebooks/135_segmentation)) 136. Downloading Earth Engine images in parallel ([notebook](https://geemap.org/notebooks/136_download_parallel)) 137. Creating a rectangular grid covering a region of interest for computing zonal statistics ([notebook](https://geemap.org/notebooks/137_create_grid)) +138. Clipping Earth Engine images interactively with the Draw Control ([notebook](https://geemap.org/notebooks/138_draw_control)) diff --git a/examples/README.md b/examples/README.md index 9dcdce7885..ebcc1190dd 100644 --- a/examples/README.md +++ b/examples/README.md @@ -154,6 +154,7 @@ More video tutorials for geemap and Earth Engine are available on my [YouTube ch 135. Earth Engine Image Segmentation with the Segment Anything Model ([notebook](https://geemap.org/notebooks/135_segmentation)) 136. Downloading Earth Engine images in parallel ([notebook](https://geemap.org/notebooks/136_download_parallel)) 137. Creating a rectangular grid covering a region of interest for computing zonal statistics ([notebook](https://geemap.org/notebooks/137_create_grid)) +138. Clipping Earth Engine images interactively with the Draw Control ([notebook](https://geemap.org/notebooks/138_draw_control)) ### 1. Introducing the geemap Python package for interactive mapping with Google Earth Engine diff --git a/examples/notebooks/138_draw_control.ipynb b/examples/notebooks/138_draw_control.ipynb new file mode 100644 index 0000000000..64ecdd51cb --- /dev/null +++ b/examples/notebooks/138_draw_control.ipynb @@ -0,0 +1,173 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\"Open\n", + "\n", + "**Clip Earth Engine images interactively with the Draw Control**\n", + "\n", + "Uncomment the following line to install [geemap](https://geemap.org) if needed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install -U geemap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ee\n", + "import geemap\n", + "import ipywidgets as widgets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add some Earth Engine data to the map, then you can use the draw control and a button widget to clip the Earth Engine data by the drawn polygons. \n", + "\n", + "The drawn geometries can be retrieved as either an ee.Geometry object (`m.user_roi`) or ee.FeatureCollection (`m._user_rois`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "self = geemap.Map(center=[0, 9.31], zoom=3)\n", + "image = ee.Image('USGS/SRTMGL1_003')\n", + "vis_params = {\n", + " 'min': 0,\n", + " 'max': 6000,\n", + " 'palette': 'terrain',\n", + "}\n", + "self.add_layer(image, vis_params, 'SRTM')\n", + "\n", + "clip_btn = widgets.Button(description='Clip Image')\n", + "reset_btn = widgets.Button(description='Reset')\n", + "\n", + "def on_clip_btn_clicked(b):\n", + " if self.user_roi is not None:\n", + " try:\n", + " clipped_image = image.clip(self.user_roi)\n", + " self.add_layer(clipped_image, vis_params, 'Clipped Image')\n", + " self.find_layer('SRTM').visible = False\n", + " except:\n", + " pass\n", + "\n", + "clip_btn.on_click(on_clip_btn_clicked)\n", + "\n", + "def on_reset_btn_clicked(b):\n", + " self._draw_control.clear()\n", + " self.find_layer('SRTM').visible = True\n", + " self.layers = self.layers[:3]\n", + "\n", + "reset_btn.on_click(on_reset_btn_clicked)\n", + "\n", + "widget = widgets.VBox([clip_btn, reset_btn])\n", + "self.add_widget(widget, position='bottomright')\n", + "self" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a solara web app." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ee\n", + "import geemap\n", + "import solara\n", + "import ipywidgets as widgets\n", + "\n", + "\n", + "class Map(geemap.Map):\n", + " def __init__(self, **kwargs):\n", + " super().__init__(**kwargs)\n", + "\n", + " image = ee.Image('USGS/SRTMGL1_003')\n", + " vis_params = {\n", + " 'min': 0,\n", + " 'max': 6000,\n", + " 'palette': 'terrain',\n", + " }\n", + " self.add_layer(image, vis_params, 'SRTM')\n", + "\n", + " clip_btn = widgets.Button(description='Clip Image')\n", + " reset_btn = widgets.Button(description='Reset')\n", + "\n", + " def on_clip_btn_clicked(b):\n", + " if self.user_roi is not None:\n", + " try:\n", + " clipped_image = image.clip(self.user_roi)\n", + " self.add_layer(clipped_image, vis_params, 'Clipped Image')\n", + " self.find_layer('SRTM').visible = False\n", + " except:\n", + " pass\n", + "\n", + " clip_btn.on_click(on_clip_btn_clicked)\n", + "\n", + " def on_reset_btn_clicked(b):\n", + " self._draw_control.clear()\n", + " self.find_layer('SRTM').visible = True\n", + " self.layers = self.layers[:3]\n", + "\n", + " reset_btn.on_click(on_reset_btn_clicked)\n", + "\n", + " widget = widgets.VBox([clip_btn, reset_btn])\n", + " self.add_widget(widget, position='bottomright')\n", + "\n", + "\n", + "@solara.component\n", + "def Page():\n", + " with solara.Column(style={\"min-width\": \"500px\"}):\n", + " Map.element(\n", + " center=[0, 9.31],\n", + " zoom=3,\n", + " height=\"600px\",\n", + " )\n", + "Page()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}