diff --git a/docs/workshops/G4G_2023.ipynb b/docs/workshops/G4G_2023.ipynb index 1a404bbcd6..eb468863f6 100644 --- a/docs/workshops/G4G_2023.ipynb +++ b/docs/workshops/G4G_2023.ipynb @@ -40,15 +40,16 @@ "\n", "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/workshops/G4G_2023.ipynb)\n", "\n", - "## Change Colab dark theme\n", + "### Change Colab dark theme\n", "\n", - "Currently, ipywidgets does not work well with Colab dark theme. It is recommended that you change Colab to the light theme.\n", + "Currently, ipywidgets does not work well with Colab dark theme. Some of the geemap widgets may not display properly in Colab dark theme.It is recommended that you change Colab to the light theme.\n", "\n", "![](https://i.imgur.com/EJ0GDP8.png)\n", "\n", + "\n", "### Install geemap\n", "\n", - "Uncomment the following line to install geemap if you are running this notebook in Google Colab." + "The geemap package is pre-installed in Google Colab and is updated to the latest minor or major release every few weeks. Some optional dependencies of geemap being used by this notebook are not pre-installed in Colab. Uncomment the following line to install geemap and some optional dependencies." ] }, { @@ -64,7 +65,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Import libraries" + "Note that some geemap features do not work properly with Google Colab. If you are familiar with [Anaconda](https://www.anaconda.com/distribution/#download-section) or [Miniconda](https://docs.conda.io/en/latest/miniconda.html), it is recommended to create a new conda environment to install geemap and its optional dependencies on your local computer. \n", + "\n", + "```bash\n", + "conda create -n gee python=3.11\n", + "conda activate gee\n", + "conda install -c conda-forge mamba\n", + "mamba install -c conda-forge geemap pygis\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import libraries\n", + "\n", + "Import the earthengine-api and geemap." ] }, { @@ -92,7 +109,16 @@ "metadata": {}, "outputs": [], "source": [ - "geemap.ee_initialize()" + "ee.Authenticate()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ee.Initialize()" ] }, { @@ -755,6 +781,13 @@ "m" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set plotting options for Landsat." + ] + }, { "cell_type": "code", "execution_count": null, @@ -764,6 +797,22 @@ "m.set_plot_options(add_marker_cluster=True, overlay=True)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set plotting options for Hyperion." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m.set_plot_options(add_marker_cluster=True, plot_type=\"bar\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -999,7 +1048,7 @@ "\n", "### Split-panel maps\n", "\n", - "Create a split map with basemaps." + "Create a split map with basemaps. Note that ipyleaflet has a bug with the SplitControl. You can't pan the map, which should be resolved in the next ipyleaflet release." ] }, { @@ -1044,7 +1093,7 @@ "source": [ "### Linked maps\n", "\n", - "Create a 2x2 linked map for visualizing Sentinel-2 imagery with different band combinations." + "Create a 2x2 linked map for visualizing Sentinel-2 imagery with different band combinations. Note that this feature does not work properly with Colab. Panning one map would not pan other maps. " ] }, { @@ -1115,7 +1164,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a timeseries inspector for NLCD." + "Create a timeseries inspector for NLCD. Note that ipyleaflet has a bug with the SplitControl. You can't pan the map, which should be resolved in the next ipyleaflet release." ] }, { @@ -1142,6 +1191,8 @@ "source": [ "#### Time slider\n", "\n", + "Note that this feature may not work properly with Colab. Restart Colab runtime if the time slider does not work.\n", + "\n", "Create a map for visualizing MODIS vegetation data." ] }, @@ -1834,7 +1885,6 @@ "if roi is None:\n", " roi = ee.Geometry.BBox(-112.8089, 33.7306, -88.5951, 46.6244)\n", " m.add_layer(roi, {}, 'ROI')\n", - " m.user_roi = None\n", "\n", "m.center_object(roi)" ] diff --git a/examples/workshops/.jupytext.toml b/examples/workshops/.jupytext.toml deleted file mode 100644 index 9e8db5e8ff..0000000000 --- a/examples/workshops/.jupytext.toml +++ /dev/null @@ -1,14 +0,0 @@ -# Install jupytext using: conda install jupytext -c conda-forge -# Always pair ipynb notebooks to md files. -# formats = "ipynb,md" -formats = "ipynb,myst" - -# jupytext --to ipynb *.md # convert all .md files to notebooks with no outputs -# jupytext --to ipynb --execute *.md # convert all .md files to notebooks and execute them -# jupytext --set-formats ipynb,md --execute *.md # convert all .md files to paired notebooks and execute them -# jupytext --to md *.ipynb # convert all .ipynb files to .md files -# jupytext --to myst *.ipynb # convert all .ipynb files to myst files - -# convert notebooks to rst https://nbconvert.readthedocs.io/en/latest/usage.html#convert-rst -# jupyter nbconvert *.ipynb --to rst -# convert md to rst: m2r *.md diff --git a/examples/workshops/G4G_2023.ipynb b/examples/workshops/G4G_2023.ipynb index 1a404bbcd6..eb468863f6 100644 --- a/examples/workshops/G4G_2023.ipynb +++ b/examples/workshops/G4G_2023.ipynb @@ -40,15 +40,16 @@ "\n", "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/workshops/G4G_2023.ipynb)\n", "\n", - "## Change Colab dark theme\n", + "### Change Colab dark theme\n", "\n", - "Currently, ipywidgets does not work well with Colab dark theme. It is recommended that you change Colab to the light theme.\n", + "Currently, ipywidgets does not work well with Colab dark theme. Some of the geemap widgets may not display properly in Colab dark theme.It is recommended that you change Colab to the light theme.\n", "\n", "![](https://i.imgur.com/EJ0GDP8.png)\n", "\n", + "\n", "### Install geemap\n", "\n", - "Uncomment the following line to install geemap if you are running this notebook in Google Colab." + "The geemap package is pre-installed in Google Colab and is updated to the latest minor or major release every few weeks. Some optional dependencies of geemap being used by this notebook are not pre-installed in Colab. Uncomment the following line to install geemap and some optional dependencies." ] }, { @@ -64,7 +65,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Import libraries" + "Note that some geemap features do not work properly with Google Colab. If you are familiar with [Anaconda](https://www.anaconda.com/distribution/#download-section) or [Miniconda](https://docs.conda.io/en/latest/miniconda.html), it is recommended to create a new conda environment to install geemap and its optional dependencies on your local computer. \n", + "\n", + "```bash\n", + "conda create -n gee python=3.11\n", + "conda activate gee\n", + "conda install -c conda-forge mamba\n", + "mamba install -c conda-forge geemap pygis\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import libraries\n", + "\n", + "Import the earthengine-api and geemap." ] }, { @@ -92,7 +109,16 @@ "metadata": {}, "outputs": [], "source": [ - "geemap.ee_initialize()" + "ee.Authenticate()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ee.Initialize()" ] }, { @@ -755,6 +781,13 @@ "m" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set plotting options for Landsat." + ] + }, { "cell_type": "code", "execution_count": null, @@ -764,6 +797,22 @@ "m.set_plot_options(add_marker_cluster=True, overlay=True)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set plotting options for Hyperion." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "m.set_plot_options(add_marker_cluster=True, plot_type=\"bar\")" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -999,7 +1048,7 @@ "\n", "### Split-panel maps\n", "\n", - "Create a split map with basemaps." + "Create a split map with basemaps. Note that ipyleaflet has a bug with the SplitControl. You can't pan the map, which should be resolved in the next ipyleaflet release." ] }, { @@ -1044,7 +1093,7 @@ "source": [ "### Linked maps\n", "\n", - "Create a 2x2 linked map for visualizing Sentinel-2 imagery with different band combinations." + "Create a 2x2 linked map for visualizing Sentinel-2 imagery with different band combinations. Note that this feature does not work properly with Colab. Panning one map would not pan other maps. " ] }, { @@ -1115,7 +1164,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a timeseries inspector for NLCD." + "Create a timeseries inspector for NLCD. Note that ipyleaflet has a bug with the SplitControl. You can't pan the map, which should be resolved in the next ipyleaflet release." ] }, { @@ -1142,6 +1191,8 @@ "source": [ "#### Time slider\n", "\n", + "Note that this feature may not work properly with Colab. Restart Colab runtime if the time slider does not work.\n", + "\n", "Create a map for visualizing MODIS vegetation data." ] }, @@ -1834,7 +1885,6 @@ "if roi is None:\n", " roi = ee.Geometry.BBox(-112.8089, 33.7306, -88.5951, 46.6244)\n", " m.add_layer(roi, {}, 'ROI')\n", - " m.user_roi = None\n", "\n", "m.center_object(roi)" ] diff --git a/geemap/map_widgets.py b/geemap/map_widgets.py index 61ae8293a8..0598930836 100644 --- a/geemap/map_widgets.py +++ b/geemap/map_widgets.py @@ -856,7 +856,17 @@ def _on_layer_visibility_changed(self, change, layer): attachment = layer_dict.get(attachment_name, None) attachment_on_map = attachment in self._host_map.controls if change["new"] and not attachment_on_map: - self._host_map.add(attachment) + try: + self._host_map.add(attachment) + except: + from ipyleaflet import WidgetControl + widget = attachment.widget + position = attachment.position + control = WidgetControl(widget=widget, position=position) + self._host_map.add(control) + layer_dict["colorbar"] = control + + elif not change["new"] and attachment_on_map: self._host_map.remove_control(attachment) diff --git a/geemap/toolbar.py b/geemap/toolbar.py index 701fb9126e..d839dc1fb4 100644 --- a/geemap/toolbar.py +++ b/geemap/toolbar.py @@ -728,7 +728,7 @@ def generate_chart(dict_values, chart_point): del plot_options["title"] m.default_style = {"cursor": "crosshair"} except Exception as e: - if not hasattr(map, "_plot_widget"): + if not hasattr(m, "_plot_widget"): m._plot_widget = None if m._plot_widget is not None: with m._plot_widget: @@ -755,15 +755,24 @@ def handle_interaction(**kwargs): plot_options["sample_scale"] is not None ): sample_scale = plot_options["sample_scale"] - dict_values_tmp = ( - ee_object.sample(xy, scale=sample_scale) - .first() - .toDictionary() - .getInfo() - ) - b_names = ee_object.bandNames().getInfo() - dict_values = dict(zip(b_names, [dict_values_tmp[b] for b in b_names])) - generate_chart(dict_values, latlon) + try: + dict_values_tmp = ( + ee_object.sample(xy, scale=sample_scale) + .first() + .toDictionary() + .getInfo() + ) + b_names = ee_object.bandNames().getInfo() + dict_values = dict(zip(b_names, [dict_values_tmp[b] for b in b_names])) + generate_chart(dict_values, latlon) + except Exception as e: + if hasattr(m, "_plot_widget"): + m._plot_widget.clear_output() + with m._plot_widget: + print("No data for the clicked location.") + else: + pass + m.default_style = {"cursor": "crosshair"} m.on_interaction(handle_interaction) @@ -824,10 +833,8 @@ def close_click(change): @map_widgets.Theme.apply class SearchDataGUI(widgets.HBox): - def __init__(self, m, **kwargs): - - # Adds search button and search box + # Adds search button and search box from .conversion import js_snippet_to_py @@ -840,7 +847,9 @@ def __init__(self, m, **kwargs): value=False, tooltip="Search location/data", icon="globe", - layout=widgets.Layout(width="28px", height="28px", padding="0px 0px 0px 4px"), + layout=widgets.Layout( + width="28px", height="28px", padding="0px 0px 0px 4px" + ), ) search_type = widgets.ToggleButtons( @@ -888,7 +897,9 @@ def get_ee_example(asset_id): pkg_dir = os.path.dirname( pkg_resources.resource_filename("geemap", "geemap.py") ) - with open(os.path.join(pkg_dir, "data/gee_f.json"), encoding="utf-8") as f: + with open( + os.path.join(pkg_dir, "data/gee_f.json"), encoding="utf-8" + ) as f: functions = json.load(f) details = [ dataset["code"]