diff --git a/examples/basic_examples.ipynb b/examples/basic_landsat_examples.ipynb similarity index 94% rename from examples/basic_examples.ipynb rename to examples/basic_landsat_examples.ipynb index 0707a49..9cd22d7 100644 --- a/examples/basic_examples.ipynb +++ b/examples/basic_landsat_examples.ipynb @@ -37,15 +37,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -122,15 +122,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -251,7 +251,7 @@ "}" ], "text/plain": [ - "" + "" ] }, "execution_count": 3, @@ -283,15 +283,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -308,9 +308,9 @@ { "data": { "text/plain": [ - "(,\n", - " ,\n", - " )" + "(,\n", + " ,\n", + " )" ] }, "execution_count": 4, @@ -341,15 +341,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -366,7 +366,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6d931b8020b741b0bf4d1a31b80cf5b9", + "model_id": "876ae80393234221b686d74956eb9ad8", "version_major": 2, "version_minor": 0 }, @@ -410,15 +410,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -435,7 +435,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f4273ab5c9584a98b1ac596b2b92be98", + "model_id": "9d33f984edde476eaee0728a9988aabe", "version_major": 2, "version_minor": 0 }, @@ -463,7 +463,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "12caa989-73dd-4e4f-a6d6-d5dcf8b6e18c", "metadata": {}, "outputs": [ @@ -479,15 +479,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -504,7 +504,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d58c8355b8e846dfbd0a06c349560019", + "model_id": "d687896da54e47c78aef25e3723428bb", "version_major": 2, "version_minor": 0 }, @@ -532,7 +532,7 @@ " }\n", "change_image = lt.get_change_map(change_params)\n", "\n", - "palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000'];\n", + "palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000']\n", "yod_vis_params = {\n", " 'min': change_params['years']['start'],\n", " 'max': change_params['years']['end'],\n", @@ -571,15 +571,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -596,7 +596,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "53c5933f42dd4facb423a94b7ce535e2", + "model_id": "6a5ded8c6f0641ef936e7b08bc5f6a3b", "version_major": 2, "version_minor": 0 }, @@ -641,15 +641,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -666,7 +666,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "fd231916a1a74ebba0973cc5efa97c3d", + "model_id": "e61a6e8660f94918984bd87d11fccda4", "version_major": 2, "version_minor": 0 }, @@ -714,15 +714,15 @@ " --jp-layout-color2: #454545;\n", " background-color: #383838;\n", " }\n", - " \n", + "\n", " .geemap-dark .jupyter-button {\n", " --jp-layout-color3: #383838;\n", " }\n", - " \n", + "\n", " .geemap-colab {\n", " background-color: var(--colab-primary-surface-color, white);\n", " }\n", - " \n", + "\n", " .geemap-colab .jupyter-button {\n", " --jp-layout-color3: var(--colab-primary-surface-color, white);\n", " }\n", @@ -739,7 +739,7 @@ { "data": { "text/plain": [ - "'https://earthengine.googleapis.com/v1/projects/ee-myscon/videoThumbnails/400bac2ade6e169c6244a37d1fd69804-a03323e1aae7fa99a2b3138a8257c0b3:getPixels'" + "'https://earthengine.googleapis.com/v1/projects/ee-myscon/videoThumbnails/e0dc8e1f5c12fd0b585a3722d342574a-dac57f3a4651957394c53b1ff8407a84:getPixels'" ] }, "execution_count": 10, @@ -758,19 +758,11 @@ "}\n", "lt_rgb.getVideoThumbURL(vid_params)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6a234bfd-b9c6-4a94-990c-48df53bab242", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "lt-gee-py", "language": "python", "name": "python3" }, @@ -784,7 +776,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.10.14" } }, "nbformat": 4, diff --git a/examples/basic_sentinel_examples.ipynb b/examples/basic_sentinel_examples.ipynb new file mode 100644 index 0000000..296e924 --- /dev/null +++ b/examples/basic_sentinel_examples.ipynb @@ -0,0 +1,943 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "b058a77b-2709-4cb1-be39-6286a5f776aa", + "metadata": {}, + "outputs": [], + "source": [ + "from ltgee import LandTrendr, Sentinel2Composite, LtCollection\n", + "from datetime import date\n", + "import geemap\n", + "import ee\n", + "\n", + "# Authenticate with Google Earth Engine before using. See link below for more information:\n", + "# https://developers.google.com/earth-engine/guides/auth\n", + "\n", + "# add in your own project name\n", + "ee.Initialize()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c8fed3e-8031-4874-8cc2-341c492bb6ab", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Example arguments to pass to the LandTrendr class. See docstring of LandTrendr for more information'\n", + "composite_params = {\n", + " \"start_date\": date(2018, 6,1),\n", + " \"end_date\": date(2024, 9,1),\n", + " \"area_of_interest\": ee.Geometry({\n", + " 'type': 'Polygon',\n", + " 'coordinates': [\n", + " [\n", + " [-122.37202331327023,44.62585686599272],\n", + " [-122.26765319608273,44.62585686599272],\n", + " [-122.26765319608273,44.696185837887384],\n", + " [-122.37202331327023,44.696185837887384],\n", + " [-122.37202331327023,44.62585686599272],\n", + " ]\n", + " ]\n", + " }),\n", + " \"mask_labels\": ['opaque', 'cirrus'],\n", + "}\n", + "lt_collection_params = {\n", + " \"sr_collection\": Sentinel2Composite(**composite_params),\n", + " \"index\": 'NBR',\n", + " \"ftv_list\": ['TCB', 'TCG', 'TCW', 'NBR'],\n", + "}\n", + "lt_params = {\n", + " \"lt_collection\": LtCollection(**lt_collection_params),\n", + " # \"lt_collection\": lt_collection_params, # - you may also just pass in your own collection or the params directly\n", + " \"run_params\": {\n", + " \"maxSegments\": 6,\n", + " \"spikeThreshold\": 0.9,\n", + " \"vertexCountOvershoot\": 3,\n", + " \"preventOneYearRecovery\": True,\n", + " \"recoveryThreshold\": 0.25,\n", + " \"pvalThreshold\": .05,\n", + " \"bestModelProportion\": 0.75,\n", + " \"minObservationsNeeded\": 6,\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "037de620-3cf7-4948-8622-dd1b88b63e51", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
    • type:Image
        • id:LandTrendr
        • crs:EPSG:4326
          • 0:1
          • 1:0
          • 2:0
          • 3:0
          • 4:1
          • 5:0
          • type:PixelType
          • dimensions:2
          • precision:double
        • id:ftv_tcb_fit
        • crs:EPSG:4326
          • 0:1
          • 1:0
          • 2:0
          • 3:0
          • 4:1
          • 5:0
          • type:PixelType
          • dimensions:1
          • precision:double
        • id:ftv_tcg_fit
        • crs:EPSG:4326
          • 0:1
          • 1:0
          • 2:0
          • 3:0
          • 4:1
          • 5:0
          • type:PixelType
          • dimensions:1
          • precision:double
        • id:ftv_tcw_fit
        • crs:EPSG:4326
          • 0:1
          • 1:0
          • 2:0
          • 3:0
          • 4:1
          • 5:0
          • type:PixelType
          • dimensions:1
          • precision:double
        • id:ftv_nbr_fit
        • crs:EPSG:4326
          • 0:1
          • 1:0
          • 2:0
          • 3:0
          • 4:1
          • 5:0
          • type:PixelType
          • dimensions:1
          • precision:double
        • id:rmse
        • crs:EPSG:4326
          • 0:1
          • 1:0
          • 2:0
          • 3:0
          • 4:1
          • 5:0
          • type:PixelType
          • precision:double
" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Instantiating LandTrendr object. Note: the LandTrendr algorithm will be run greedily on GEE (ie the script will immediately request to run the algorithm on GEE as soon as it has all the collections built unless lt.run=False).\n", + "lt = LandTrendr(**lt_params)\n", + "lt" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "fbea54f4-1132-4381-8b0a-8e4cc0e7d6a7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "(,\n", + " )" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# You may access the collections using the properties below\n", + "lt.lt_collection.sr_collection, lt.lt_collection" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e835f99e-0ef0-4b0a-83ef-1d4390783518", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b2d3105bd3cf4b5fa28ac715cacd15e5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[44.661026124368775, -122.31983825467653], controls=(WidgetControl(options=['position', 'transparen…" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example 1: Displaying images from Landtrendr\n", + "\n", + "lt_tcb = lt.select('ftv_nbr_fit').clip(composite_params['area_of_interest'])\n", + "map = geemap.Map()\n", + "map.centerObject(composite_params['area_of_interest'], 13)\n", + "map.addLayer(lt_tcb, {}, 'lt_nbr')\n", + "map.addLayer(composite_params['area_of_interest'], {}, 'area_of_interest')\n", + "map" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f526c669-6e92-4314-a2c0-30f00e731307", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "58ec9c41a7214af3816397c75d33ee99", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[44.661026124368775, -122.31983825467653], controls=(WidgetControl(options=['position', 'transparen…" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "ename": "EEException", + "evalue": "Input must be a scalar number.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mHttpError\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:406\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 405\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum_retries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnum_retries\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\_helpers.py:130\u001b[0m, in \u001b[0;36mpositional..positional_decorator..positional_wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 129\u001b[0m logger\u001b[38;5;241m.\u001b[39mwarning(message)\n\u001b[1;32m--> 130\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapped(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\http.py:938\u001b[0m, in \u001b[0;36mHttpRequest.execute\u001b[1;34m(self, http, num_retries)\u001b[0m\n\u001b[0;32m 937\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mstatus \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m300\u001b[39m:\n\u001b[1;32m--> 938\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HttpError(resp, content, uri\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39muri)\n\u001b[0;32m 939\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpostproc(resp, content)\n", + "\u001b[1;31mHttpError\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mEEException\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[1;34m(self, msg)\u001b[0m\n\u001b[0;32m 771\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[0;32m 772\u001b[0m _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[1;32m--> 773\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[0;32m 776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[1;34m(self, sync_data)\u001b[0m\n\u001b[0;32m 645\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[0;32m 647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[0;32m 648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[0;32m 649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[1;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[0;32m 651\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[0;32m 652\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[1;34m(self, typ, value, traceback)\u001b[0m\n\u001b[0;32m 140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[0;32m 144\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[0;32m 1509\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[1;32m-> 1510\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[1;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1524\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[1;32m-> 1525\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[1;34m(self, event)\u001b[0m\n\u001b[0;32m 1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1566\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget_selection.py:236\u001b[0m, in \u001b[0;36m_Selection._propagate_index\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 234\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlabel \u001b[38;5;241m=\u001b[39m label\n\u001b[0;32m 235\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvalue \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m value:\n\u001b[1;32m--> 236\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m \u001b[38;5;241m=\u001b[39m value\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:716\u001b[0m, in \u001b[0;36mTraitType.__set__\u001b[1;34m(self, obj, value)\u001b[0m\n\u001b[0;32m 714\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_only:\n\u001b[0;32m 715\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m TraitError(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mThe \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m trait is read-only.\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m--> 716\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:706\u001b[0m, in \u001b[0;36mTraitType.set\u001b[1;34m(self, obj, value)\u001b[0m\n\u001b[0;32m 702\u001b[0m silent \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 703\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m silent \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m 704\u001b[0m \u001b[38;5;66;03m# we explicitly compare silent to True just in case the equality\u001b[39;00m\n\u001b[0;32m 705\u001b[0m \u001b[38;5;66;03m# comparison above returns something other than True/False\u001b[39;00m\n\u001b[1;32m--> 706\u001b[0m \u001b[43mobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_trait\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mold_value\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_value\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1513\u001b[0m, in \u001b[0;36mHasTraits._notify_trait\u001b[1;34m(self, name, old_value, new_value)\u001b[0m\n\u001b[0;32m 1512\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_notify_trait\u001b[39m(\u001b[38;5;28mself\u001b[39m, name: \u001b[38;5;28mstr\u001b[39m, old_value: t\u001b[38;5;241m.\u001b[39mAny, new_value: t\u001b[38;5;241m.\u001b[39mAny) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 1513\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1514\u001b[0m \u001b[43m \u001b[49m\u001b[43mBunch\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1515\u001b[0m \u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1516\u001b[0m \u001b[43m \u001b[49m\u001b[43mold\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mold_value\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1517\u001b[0m \u001b[43m \u001b[49m\u001b[43mnew\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnew_value\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1518\u001b[0m \u001b[43m \u001b[49m\u001b[43mowner\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1519\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mchange\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1520\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1521\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[1;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1524\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[1;32m-> 1525\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[1;34m(self, event)\u001b[0m\n\u001b[0;32m 1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1566\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1458\u001b[0m, in \u001b[0;36m_RasterLayerEditor._value_stretch_changed\u001b[1;34m(self, value)\u001b[0m\n\u001b[0;32m 1456\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stretch_button\u001b[38;5;241m.\u001b[39mdisabled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 1457\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_value_range_slider\u001b[38;5;241m.\u001b[39mdisabled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m-> 1458\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_update_stretch\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1459\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 1460\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stretch_button\u001b[38;5;241m.\u001b[39mdisabled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1470\u001b[0m, in \u001b[0;36m_RasterLayerEditor._update_stretch\u001b[1;34m(self, *_)\u001b[0m\n\u001b[0;32m 1468\u001b[0m map_bbox \u001b[38;5;241m=\u001b[39m ee\u001b[38;5;241m.\u001b[39mGeometry\u001b[38;5;241m.\u001b[39mBBox(west\u001b[38;5;241m=\u001b[39mw, south\u001b[38;5;241m=\u001b[39ms, east\u001b[38;5;241m=\u001b[39me, north\u001b[38;5;241m=\u001b[39mn)\n\u001b[0;32m 1469\u001b[0m vis_bands \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mset\u001b[39m((b\u001b[38;5;241m.\u001b[39mvalue \u001b[38;5;28;01mfor\u001b[39;00m b \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bands_hbox\u001b[38;5;241m.\u001b[39mchildren))\n\u001b[1;32m-> 1470\u001b[0m min_val, max_val \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_layer\u001b[38;5;241m.\u001b[39mcalculate_vis_minmax(\n\u001b[0;32m 1471\u001b[0m bounds\u001b[38;5;241m=\u001b[39mmap_bbox, bands\u001b[38;5;241m=\u001b[39mvis_bands, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mstretch_params\n\u001b[0;32m 1472\u001b[0m )\n\u001b[0;32m 1474\u001b[0m \u001b[38;5;66;03m# Update in the correct order to avoid setting an invalid range\u001b[39;00m\n\u001b[0;32m 1475\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m min_val \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_value_range_slider\u001b[38;5;241m.\u001b[39mmax:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:220\u001b[0m, in \u001b[0;36mEELeafletTileLayer.calculate_vis_minmax\u001b[1;34m(self, bounds, bands, percent, sigma)\u001b[0m\n\u001b[0;32m 218\u001b[0m bands \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_object\u001b[38;5;241m.\u001b[39mbandNames() \u001b[38;5;28;01mif\u001b[39;00m bands \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mtuple\u001b[39m(bands)\n\u001b[0;32m 219\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 220\u001b[0m min_val, max_val, std, mean \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate_vis_stats\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 221\u001b[0m \u001b[43m \u001b[49m\u001b[43mbounds\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbounds\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbands\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbands\u001b[49m\n\u001b[0;32m 222\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 223\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[0;32m 224\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m (\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m0\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:188\u001b[0m, in \u001b[0;36mEELeafletTileLayer._calculate_vis_stats\u001b[1;34m(self, bounds, bands)\u001b[0m\n\u001b[0;32m 159\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Calculate stats used for visualization parameters.\u001b[39;00m\n\u001b[0;32m 160\u001b[0m \n\u001b[0;32m 161\u001b[0m \u001b[38;5;124;03mStats are calculated consistently with the Code Editor visualization parameters,\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 170\u001b[0m \u001b[38;5;124;03m specified bands.\u001b[39;00m\n\u001b[0;32m 171\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 172\u001b[0m stat_reducer \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 173\u001b[0m ee\u001b[38;5;241m.\u001b[39mReducer\u001b[38;5;241m.\u001b[39mminMax()\n\u001b[0;32m 174\u001b[0m \u001b[38;5;241m.\u001b[39mcombine(ee\u001b[38;5;241m.\u001b[39mReducer\u001b[38;5;241m.\u001b[39mmean()\u001b[38;5;241m.\u001b[39munweighted(), sharedInputs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 175\u001b[0m \u001b[38;5;241m.\u001b[39mcombine(ee\u001b[38;5;241m.\u001b[39mReducer\u001b[38;5;241m.\u001b[39mstdDev(), sharedInputs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 176\u001b[0m )\n\u001b[0;32m 178\u001b[0m stats \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 179\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ee_object\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbands\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 180\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreduceRegion\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 181\u001b[0m \u001b[43m \u001b[49m\u001b[43mreducer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstat_reducer\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 182\u001b[0m \u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbounds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 183\u001b[0m \u001b[43m \u001b[49m\u001b[43mbestEffort\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 184\u001b[0m \u001b[43m \u001b[49m\u001b[43mmaxPixels\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m10_000\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 185\u001b[0m \u001b[43m \u001b[49m\u001b[43mcrs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSR-ORG:6627\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 186\u001b[0m \u001b[43m \u001b[49m\u001b[43mscale\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 187\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m--> 188\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetInfo\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 189\u001b[0m )\n\u001b[0;32m 191\u001b[0m mins, maxs, stds, means \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m 192\u001b[0m {v \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m stats\u001b[38;5;241m.\u001b[39mitems() \u001b[38;5;28;01mif\u001b[39;00m k\u001b[38;5;241m.\u001b[39mendswith(stat) \u001b[38;5;129;01mand\u001b[39;00m v \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m}\n\u001b[0;32m 193\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m stat \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_min\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_max\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_stdDev\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_mean\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 194\u001b[0m ]\n\u001b[0;32m 195\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28mlen\u001b[39m(vals) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m vals \u001b[38;5;129;01min\u001b[39;00m (mins, maxs, stds, means)):\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\computedobject.py:107\u001b[0m, in \u001b[0;36mComputedObject.getInfo\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 101\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mgetInfo\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Optional[Any]:\n\u001b[0;32m 102\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Fetch and return information about this object.\u001b[39;00m\n\u001b[0;32m 103\u001b[0m \n\u001b[0;32m 104\u001b[0m \u001b[38;5;124;03m Returns:\u001b[39;00m\n\u001b[0;32m 105\u001b[0m \u001b[38;5;124;03m The object can evaluate to anything.\u001b[39;00m\n\u001b[0;32m 106\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 107\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcomputeValue\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:1126\u001b[0m, in \u001b[0;36mcomputeValue\u001b[1;34m(obj)\u001b[0m\n\u001b[0;32m 1123\u001b[0m body \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexpression\u001b[39m\u001b[38;5;124m'\u001b[39m: serializer\u001b[38;5;241m.\u001b[39mencode(obj, for_cloud_api\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)}\n\u001b[0;32m 1124\u001b[0m _maybe_populate_workload_tag(body)\n\u001b[1;32m-> 1126\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_execute_cloud_call\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1127\u001b[0m \u001b[43m \u001b[49m\u001b[43m_get_cloud_projects\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1128\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1129\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mproject\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_get_projects_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprettyPrint\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 1130\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mresult\u001b[39m\u001b[38;5;124m'\u001b[39m]\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:408\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m call\u001b[38;5;241m.\u001b[39mexecute(num_retries\u001b[38;5;241m=\u001b[39mnum_retries)\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 408\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m _translate_cloud_exception(e)\n", + "\u001b[1;31mEEException\u001b[0m: Input must be a scalar number." + ] + } + ], + "source": [ + "# Example 2: Displaying collection to band stack\n", + "\n", + "# Note: lt_collection outside of the class can be passed in\n", + "collection_to_band_stack = lt.collection_to_band_stack(lt.lt_collection, start_date=composite_params[\"start_date\"], end_date=composite_params[\"end_date\"])\n", + "\n", + "map = geemap.Map()\n", + "map.centerObject(composite_params['area_of_interest'], 13)\n", + "map.addLayer(collection_to_band_stack, {\"bands\":[\"2000\"],\"min\":-100,\"max\":1000,\"palette\":[\"ff2f0d\",\"fff825\",\"0ab308\"]})\n", + "map.addLayer(composite_params['area_of_interest'], {}, 'area_of_interest')\n", + "map" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12caa989-73dd-4e4f-a6d6-d5dcf8b6e18c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "031939a36c2f435b9b0b6c1b618f7bfb", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[44.661026124368775, -122.31983825467653], controls=(WidgetControl(options=['position', 'transparen…" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example 3: Displaying change data\n", + "# Note: Change params does not require all keys to be present and will only process what is passed in.\n", + "\n", + "change_params = {\n", + " 'delta': 'loss',\n", + " 'sort': 'greatest',\n", + " 'years': {'start': composite_params[\"start_date\"].year + 1, 'end': composite_params[\"end_date\"].year},\n", + " 'mag': {'value': 200, 'operator': '>' },\n", + " 'dur': {'value': 4, 'operator': '<'},\n", + " 'preval': {'value': 300, 'operator': '>'},\n", + " 'mmu': {'value': 5}\n", + " }\n", + "change_image = lt.get_change_map(change_params)\n", + "\n", + "palette = ['#9400D3', '#4B0082', '#0000FF', '#00FF00', '#FFFF00', '#FF7F00', '#FF0000'];\n", + "yod_vis_params = {\n", + " 'min': change_params['years']['start'],\n", + " 'max': change_params['years']['end'],\n", + " 'palette': palette\n", + "}\n", + "mag_vis_params = {\n", + " 'min': 200,\n", + " 'max': 800,\n", + " 'palette': palette\n", + "}\n", + "\n", + "\n", + "map = geemap.Map()\n", + "map.centerObject(composite_params['area_of_interest'], 13)\n", + "map.addLayer(change_image.select(['mag']), yod_vis_params, 'Magnitude of Change')\n", + "map.addLayer(change_image.select(['yod']), mag_vis_params, 'Year of Detection')\n", + "map.addLayer(composite_params['area_of_interest'], {}, 'area_of_interest')\n", + "map" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92f250c9-d408-440f-a0f1-67e23c002a5e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d1b5a1ba077e4c8794d841022c3bad71", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[44.661026124368775, -122.31983825467653], controls=(WidgetControl(options=['position', 'transparen…" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "ename": "EEException", + "evalue": "Input must be a scalar number.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mHttpError\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:406\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 405\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum_retries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnum_retries\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\_helpers.py:130\u001b[0m, in \u001b[0;36mpositional..positional_decorator..positional_wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 129\u001b[0m logger\u001b[38;5;241m.\u001b[39mwarning(message)\n\u001b[1;32m--> 130\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapped(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\http.py:938\u001b[0m, in \u001b[0;36mHttpRequest.execute\u001b[1;34m(self, http, num_retries)\u001b[0m\n\u001b[0;32m 937\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mstatus \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m300\u001b[39m:\n\u001b[1;32m--> 938\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HttpError(resp, content, uri\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39muri)\n\u001b[0;32m 939\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpostproc(resp, content)\n", + "\u001b[1;31mHttpError\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mEEException\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[1;34m(self, msg)\u001b[0m\n\u001b[0;32m 771\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[0;32m 772\u001b[0m _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[1;32m--> 773\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[0;32m 776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[1;34m(self, sync_data)\u001b[0m\n\u001b[0;32m 645\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[0;32m 647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[0;32m 648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[0;32m 649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[1;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[0;32m 651\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[0;32m 652\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[1;34m(self, typ, value, traceback)\u001b[0m\n\u001b[0;32m 140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 141\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 142\u001b[0m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 143\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[0;32m 144\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[0;32m 1509\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[1;32m-> 1510\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[1;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1524\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[1;32m-> 1525\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[1;34m(self, event)\u001b[0m\n\u001b[0;32m 1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1566\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget_selection.py:236\u001b[0m, in \u001b[0;36m_Selection._propagate_index\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 234\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlabel \u001b[38;5;241m=\u001b[39m label\n\u001b[0;32m 235\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvalue \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m value:\n\u001b[1;32m--> 236\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m \u001b[38;5;241m=\u001b[39m value\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:716\u001b[0m, in \u001b[0;36mTraitType.__set__\u001b[1;34m(self, obj, value)\u001b[0m\n\u001b[0;32m 714\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_only:\n\u001b[0;32m 715\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m TraitError(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mThe \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m trait is read-only.\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m--> 716\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:706\u001b[0m, in \u001b[0;36mTraitType.set\u001b[1;34m(self, obj, value)\u001b[0m\n\u001b[0;32m 702\u001b[0m silent \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 703\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m silent \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m 704\u001b[0m \u001b[38;5;66;03m# we explicitly compare silent to True just in case the equality\u001b[39;00m\n\u001b[0;32m 705\u001b[0m \u001b[38;5;66;03m# comparison above returns something other than True/False\u001b[39;00m\n\u001b[1;32m--> 706\u001b[0m \u001b[43mobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_trait\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mold_value\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnew_value\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1513\u001b[0m, in \u001b[0;36mHasTraits._notify_trait\u001b[1;34m(self, name, old_value, new_value)\u001b[0m\n\u001b[0;32m 1512\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_notify_trait\u001b[39m(\u001b[38;5;28mself\u001b[39m, name: \u001b[38;5;28mstr\u001b[39m, old_value: t\u001b[38;5;241m.\u001b[39mAny, new_value: t\u001b[38;5;241m.\u001b[39mAny) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 1513\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1514\u001b[0m \u001b[43m \u001b[49m\u001b[43mBunch\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1515\u001b[0m \u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1516\u001b[0m \u001b[43m \u001b[49m\u001b[43mold\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mold_value\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1517\u001b[0m \u001b[43m \u001b[49m\u001b[43mnew\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnew_value\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1518\u001b[0m \u001b[43m \u001b[49m\u001b[43mowner\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1519\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mchange\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1520\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1521\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ipywidgets\\widgets\\widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[1;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[1;34m(self, change)\u001b[0m\n\u001b[0;32m 1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1524\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[1;32m-> 1525\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\traitlets\\traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[1;34m(self, event)\u001b[0m\n\u001b[0;32m 1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 1566\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[1;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1458\u001b[0m, in \u001b[0;36m_RasterLayerEditor._value_stretch_changed\u001b[1;34m(self, value)\u001b[0m\n\u001b[0;32m 1456\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stretch_button\u001b[38;5;241m.\u001b[39mdisabled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 1457\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_value_range_slider\u001b[38;5;241m.\u001b[39mdisabled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m-> 1458\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_update_stretch\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1459\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 1460\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stretch_button\u001b[38;5;241m.\u001b[39mdisabled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1470\u001b[0m, in \u001b[0;36m_RasterLayerEditor._update_stretch\u001b[1;34m(self, *_)\u001b[0m\n\u001b[0;32m 1468\u001b[0m map_bbox \u001b[38;5;241m=\u001b[39m ee\u001b[38;5;241m.\u001b[39mGeometry\u001b[38;5;241m.\u001b[39mBBox(west\u001b[38;5;241m=\u001b[39mw, south\u001b[38;5;241m=\u001b[39ms, east\u001b[38;5;241m=\u001b[39me, north\u001b[38;5;241m=\u001b[39mn)\n\u001b[0;32m 1469\u001b[0m vis_bands \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mset\u001b[39m((b\u001b[38;5;241m.\u001b[39mvalue \u001b[38;5;28;01mfor\u001b[39;00m b \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bands_hbox\u001b[38;5;241m.\u001b[39mchildren))\n\u001b[1;32m-> 1470\u001b[0m min_val, max_val \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_layer\u001b[38;5;241m.\u001b[39mcalculate_vis_minmax(\n\u001b[0;32m 1471\u001b[0m bounds\u001b[38;5;241m=\u001b[39mmap_bbox, bands\u001b[38;5;241m=\u001b[39mvis_bands, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mstretch_params\n\u001b[0;32m 1472\u001b[0m )\n\u001b[0;32m 1474\u001b[0m \u001b[38;5;66;03m# Update in the correct order to avoid setting an invalid range\u001b[39;00m\n\u001b[0;32m 1475\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m min_val \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_value_range_slider\u001b[38;5;241m.\u001b[39mmax:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:220\u001b[0m, in \u001b[0;36mEELeafletTileLayer.calculate_vis_minmax\u001b[1;34m(self, bounds, bands, percent, sigma)\u001b[0m\n\u001b[0;32m 218\u001b[0m bands \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_object\u001b[38;5;241m.\u001b[39mbandNames() \u001b[38;5;28;01mif\u001b[39;00m bands \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mtuple\u001b[39m(bands)\n\u001b[0;32m 219\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 220\u001b[0m min_val, max_val, std, mean \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_calculate_vis_stats\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 221\u001b[0m \u001b[43m \u001b[49m\u001b[43mbounds\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbounds\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbands\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbands\u001b[49m\n\u001b[0;32m 222\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 223\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[0;32m 224\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m (\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m0\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:188\u001b[0m, in \u001b[0;36mEELeafletTileLayer._calculate_vis_stats\u001b[1;34m(self, bounds, bands)\u001b[0m\n\u001b[0;32m 159\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Calculate stats used for visualization parameters.\u001b[39;00m\n\u001b[0;32m 160\u001b[0m \n\u001b[0;32m 161\u001b[0m \u001b[38;5;124;03mStats are calculated consistently with the Code Editor visualization parameters,\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 170\u001b[0m \u001b[38;5;124;03m specified bands.\u001b[39;00m\n\u001b[0;32m 171\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 172\u001b[0m stat_reducer \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 173\u001b[0m ee\u001b[38;5;241m.\u001b[39mReducer\u001b[38;5;241m.\u001b[39mminMax()\n\u001b[0;32m 174\u001b[0m \u001b[38;5;241m.\u001b[39mcombine(ee\u001b[38;5;241m.\u001b[39mReducer\u001b[38;5;241m.\u001b[39mmean()\u001b[38;5;241m.\u001b[39munweighted(), sharedInputs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 175\u001b[0m \u001b[38;5;241m.\u001b[39mcombine(ee\u001b[38;5;241m.\u001b[39mReducer\u001b[38;5;241m.\u001b[39mstdDev(), sharedInputs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[0;32m 176\u001b[0m )\n\u001b[0;32m 178\u001b[0m stats \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m 179\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ee_object\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mselect\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbands\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 180\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreduceRegion\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 181\u001b[0m \u001b[43m \u001b[49m\u001b[43mreducer\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstat_reducer\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 182\u001b[0m \u001b[43m \u001b[49m\u001b[43mgeometry\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbounds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 183\u001b[0m \u001b[43m \u001b[49m\u001b[43mbestEffort\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 184\u001b[0m \u001b[43m \u001b[49m\u001b[43mmaxPixels\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m10_000\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 185\u001b[0m \u001b[43m \u001b[49m\u001b[43mcrs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mSR-ORG:6627\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 186\u001b[0m \u001b[43m \u001b[49m\u001b[43mscale\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 187\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m--> 188\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetInfo\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 189\u001b[0m )\n\u001b[0;32m 191\u001b[0m mins, maxs, stds, means \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m 192\u001b[0m {v \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m stats\u001b[38;5;241m.\u001b[39mitems() \u001b[38;5;28;01mif\u001b[39;00m k\u001b[38;5;241m.\u001b[39mendswith(stat) \u001b[38;5;129;01mand\u001b[39;00m v \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m}\n\u001b[0;32m 193\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m stat \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_min\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_max\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_stdDev\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_mean\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 194\u001b[0m ]\n\u001b[0;32m 195\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28many\u001b[39m(\u001b[38;5;28mlen\u001b[39m(vals) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m vals \u001b[38;5;129;01min\u001b[39;00m (mins, maxs, stds, means)):\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\computedobject.py:107\u001b[0m, in \u001b[0;36mComputedObject.getInfo\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 101\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mgetInfo\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Optional[Any]:\n\u001b[0;32m 102\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Fetch and return information about this object.\u001b[39;00m\n\u001b[0;32m 103\u001b[0m \n\u001b[0;32m 104\u001b[0m \u001b[38;5;124;03m Returns:\u001b[39;00m\n\u001b[0;32m 105\u001b[0m \u001b[38;5;124;03m The object can evaluate to anything.\u001b[39;00m\n\u001b[0;32m 106\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[1;32m--> 107\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcomputeValue\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:1126\u001b[0m, in \u001b[0;36mcomputeValue\u001b[1;34m(obj)\u001b[0m\n\u001b[0;32m 1123\u001b[0m body \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mexpression\u001b[39m\u001b[38;5;124m'\u001b[39m: serializer\u001b[38;5;241m.\u001b[39mencode(obj, for_cloud_api\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)}\n\u001b[0;32m 1124\u001b[0m _maybe_populate_workload_tag(body)\n\u001b[1;32m-> 1126\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_execute_cloud_call\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1127\u001b[0m \u001b[43m \u001b[49m\u001b[43m_get_cloud_projects\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1128\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1129\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mproject\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_get_projects_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprettyPrint\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 1130\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mresult\u001b[39m\u001b[38;5;124m'\u001b[39m]\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:408\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m call\u001b[38;5;241m.\u001b[39mexecute(num_retries\u001b[38;5;241m=\u001b[39mnum_retries)\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 408\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m _translate_cloud_exception(e)\n", + "\u001b[1;31mEEException\u001b[0m: Input must be a scalar number." + ] + }, + { + "ename": "EEException", + "evalue": "Image.visualize: Attempt to use array input on non array algorithm.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mHttpError\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:406\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 405\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum_retries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnum_retries\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\_helpers.py:130\u001b[0m, in \u001b[0;36mpositional..positional_decorator..positional_wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 129\u001b[0m logger\u001b[38;5;241m.\u001b[39mwarning(message)\n\u001b[1;32m--> 130\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapped(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\http.py:938\u001b[0m, in \u001b[0;36mHttpRequest.execute\u001b[1;34m(self, http, num_retries)\u001b[0m\n\u001b[0;32m 937\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mstatus \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m300\u001b[39m:\n\u001b[1;32m--> 938\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HttpError(resp, content, uri\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39muri)\n\u001b[0;32m 939\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpostproc(resp, content)\n", + "\u001b[1;31mHttpError\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mEEException\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1119\u001b[0m, in \u001b[0;36mLayerEditor._on_apply_click\u001b[1;34m(self, _)\u001b[0m\n\u001b[0;32m 1118\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_on_apply_click\u001b[39m(\u001b[38;5;28mself\u001b[39m, _):\n\u001b[1;32m-> 1119\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_embedded_widget\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mon_apply_click\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1680\u001b[0m, in \u001b[0;36m_RasterLayerEditor.on_apply_click\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1678\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mon_apply_click\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 1679\u001b[0m vis \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_vis_params_from_selection()\n\u001b[1;32m-> 1680\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_host_map\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd_layer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1681\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_layer_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_opacity_slider\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m\n\u001b[0;32m 1682\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1683\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_layer\u001b[38;5;241m.\u001b[39mvisible \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 1685\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_legend_checkbox\u001b[38;5;241m.\u001b[39mvalue:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\core.py:796\u001b[0m, in \u001b[0;36mMap.add_layer\u001b[1;34m(self, ee_object, vis_params, name, shown, opacity)\u001b[0m\n\u001b[0;32m 794\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ee_object, ee\u001b[38;5;241m.\u001b[39mImageCollection):\n\u001b[0;32m 795\u001b[0m ee_object \u001b[38;5;241m=\u001b[39m ee_object\u001b[38;5;241m.\u001b[39mmosaic()\n\u001b[1;32m--> 796\u001b[0m tile_layer \u001b[38;5;241m=\u001b[39m \u001b[43mee_tile_layers\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mEELeafletTileLayer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 797\u001b[0m \u001b[43m \u001b[49m\u001b[43mee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mshown\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopacity\u001b[49m\n\u001b[0;32m 798\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 800\u001b[0m \u001b[38;5;66;03m# Remove the layer if it already exists.\u001b[39;00m\n\u001b[0;32m 801\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mremove(name)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:144\u001b[0m, in \u001b[0;36mEELeafletTileLayer.__init__\u001b[1;34m(self, ee_object, vis_params, name, shown, opacity, **kwargs)\u001b[0m\n\u001b[0;32m 134\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Initialize the ipyleaflet tile layer.\u001b[39;00m\n\u001b[0;32m 135\u001b[0m \n\u001b[0;32m 136\u001b[0m \u001b[38;5;124;03mArgs:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 141\u001b[0m \u001b[38;5;124;03m opacity (float, optional): The layer's opacity represented as a number between 0 and 1. Defaults to 1.\u001b[39;00m\n\u001b[0;32m 142\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 143\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_object \u001b[38;5;241m=\u001b[39m ee_object\n\u001b[1;32m--> 144\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl_format \u001b[38;5;241m=\u001b[39m \u001b[43m_get_tile_url_format\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 145\u001b[0m \u001b[43m \u001b[49m\u001b[43mee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_validate_vis_params\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 146\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 147\u001b[0m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__init__\u001b[39m(\n\u001b[0;32m 148\u001b[0m url\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl_format,\n\u001b[0;32m 149\u001b[0m attribution\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGoogle Earth Engine\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 154\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 155\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:19\u001b[0m, in \u001b[0;36m_get_tile_url_format\u001b[1;34m(ee_object, vis_params)\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_get_tile_url_format\u001b[39m(ee_object, vis_params):\n\u001b[0;32m 18\u001b[0m image \u001b[38;5;241m=\u001b[39m _ee_object_to_image(ee_object, vis_params)\n\u001b[1;32m---> 19\u001b[0m map_id_dict \u001b[38;5;241m=\u001b[39m \u001b[43mee\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mImage\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetMapId\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m map_id_dict[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtile_fetcher\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39murl_format\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\image.py:156\u001b[0m, in \u001b[0;36mImage.getMapId\u001b[1;34m(self, vis_params)\u001b[0m\n\u001b[0;32m 154\u001b[0m vis_image, request \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_apply_visualization(vis_params)\n\u001b[0;32m 155\u001b[0m request[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m vis_image\n\u001b[1;32m--> 156\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetMapId\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 157\u001b[0m response[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n\u001b[0;32m 158\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:748\u001b[0m, in \u001b[0;36mgetMapId\u001b[1;34m(params)\u001b[0m\n\u001b[0;32m 743\u001b[0m queryParams \u001b[38;5;241m=\u001b[39m {\n\u001b[0;32m 744\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfields\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m 745\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbody\u001b[39m\u001b[38;5;124m'\u001b[39m: request,\n\u001b[0;32m 746\u001b[0m }\n\u001b[0;32m 747\u001b[0m _maybe_populate_workload_tag(queryParams)\n\u001b[1;32m--> 748\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43m_execute_cloud_call\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 749\u001b[0m \u001b[43m \u001b[49m\u001b[43m_get_cloud_projects\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 750\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmaps\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 751\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mparent\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_get_projects_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mqueryParams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 752\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 753\u001b[0m map_name \u001b[38;5;241m=\u001b[39m result[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m 754\u001b[0m url_format \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/tiles/\u001b[39m\u001b[38;5;132;01m{z}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{x}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{y}\u001b[39;00m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m (\n\u001b[0;32m 755\u001b[0m _tile_base_url, _cloud_api_utils\u001b[38;5;241m.\u001b[39mVERSION, map_name)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:408\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m call\u001b[38;5;241m.\u001b[39mexecute(num_retries\u001b[38;5;241m=\u001b[39mnum_retries)\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 408\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m _translate_cloud_exception(e)\n", + "\u001b[1;31mEEException\u001b[0m: Image.visualize: Attempt to use array input on non array algorithm." + ] + }, + { + "ename": "EEException", + "evalue": "Image.visualize: Attempt to use array input on non array algorithm.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mHttpError\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:406\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 405\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum_retries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnum_retries\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\_helpers.py:130\u001b[0m, in \u001b[0;36mpositional..positional_decorator..positional_wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 129\u001b[0m logger\u001b[38;5;241m.\u001b[39mwarning(message)\n\u001b[1;32m--> 130\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapped(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\http.py:938\u001b[0m, in \u001b[0;36mHttpRequest.execute\u001b[1;34m(self, http, num_retries)\u001b[0m\n\u001b[0;32m 937\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mstatus \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m300\u001b[39m:\n\u001b[1;32m--> 938\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HttpError(resp, content, uri\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39muri)\n\u001b[0;32m 939\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpostproc(resp, content)\n", + "\u001b[1;31mHttpError\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mEEException\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1119\u001b[0m, in \u001b[0;36mLayerEditor._on_apply_click\u001b[1;34m(self, _)\u001b[0m\n\u001b[0;32m 1118\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_on_apply_click\u001b[39m(\u001b[38;5;28mself\u001b[39m, _):\n\u001b[1;32m-> 1119\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_embedded_widget\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mon_apply_click\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1680\u001b[0m, in \u001b[0;36m_RasterLayerEditor.on_apply_click\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1678\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mon_apply_click\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 1679\u001b[0m vis \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_vis_params_from_selection()\n\u001b[1;32m-> 1680\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_host_map\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd_layer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1681\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_layer_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_opacity_slider\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m\n\u001b[0;32m 1682\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1683\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_layer\u001b[38;5;241m.\u001b[39mvisible \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 1685\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_legend_checkbox\u001b[38;5;241m.\u001b[39mvalue:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\core.py:796\u001b[0m, in \u001b[0;36mMap.add_layer\u001b[1;34m(self, ee_object, vis_params, name, shown, opacity)\u001b[0m\n\u001b[0;32m 794\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ee_object, ee\u001b[38;5;241m.\u001b[39mImageCollection):\n\u001b[0;32m 795\u001b[0m ee_object \u001b[38;5;241m=\u001b[39m ee_object\u001b[38;5;241m.\u001b[39mmosaic()\n\u001b[1;32m--> 796\u001b[0m tile_layer \u001b[38;5;241m=\u001b[39m \u001b[43mee_tile_layers\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mEELeafletTileLayer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 797\u001b[0m \u001b[43m \u001b[49m\u001b[43mee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mshown\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopacity\u001b[49m\n\u001b[0;32m 798\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 800\u001b[0m \u001b[38;5;66;03m# Remove the layer if it already exists.\u001b[39;00m\n\u001b[0;32m 801\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mremove(name)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:144\u001b[0m, in \u001b[0;36mEELeafletTileLayer.__init__\u001b[1;34m(self, ee_object, vis_params, name, shown, opacity, **kwargs)\u001b[0m\n\u001b[0;32m 134\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Initialize the ipyleaflet tile layer.\u001b[39;00m\n\u001b[0;32m 135\u001b[0m \n\u001b[0;32m 136\u001b[0m \u001b[38;5;124;03mArgs:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 141\u001b[0m \u001b[38;5;124;03m opacity (float, optional): The layer's opacity represented as a number between 0 and 1. Defaults to 1.\u001b[39;00m\n\u001b[0;32m 142\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 143\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_object \u001b[38;5;241m=\u001b[39m ee_object\n\u001b[1;32m--> 144\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl_format \u001b[38;5;241m=\u001b[39m \u001b[43m_get_tile_url_format\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 145\u001b[0m \u001b[43m \u001b[49m\u001b[43mee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_validate_vis_params\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 146\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 147\u001b[0m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__init__\u001b[39m(\n\u001b[0;32m 148\u001b[0m url\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl_format,\n\u001b[0;32m 149\u001b[0m attribution\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGoogle Earth Engine\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 154\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 155\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:19\u001b[0m, in \u001b[0;36m_get_tile_url_format\u001b[1;34m(ee_object, vis_params)\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_get_tile_url_format\u001b[39m(ee_object, vis_params):\n\u001b[0;32m 18\u001b[0m image \u001b[38;5;241m=\u001b[39m _ee_object_to_image(ee_object, vis_params)\n\u001b[1;32m---> 19\u001b[0m map_id_dict \u001b[38;5;241m=\u001b[39m \u001b[43mee\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mImage\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetMapId\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m map_id_dict[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtile_fetcher\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39murl_format\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\image.py:156\u001b[0m, in \u001b[0;36mImage.getMapId\u001b[1;34m(self, vis_params)\u001b[0m\n\u001b[0;32m 154\u001b[0m vis_image, request \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_apply_visualization(vis_params)\n\u001b[0;32m 155\u001b[0m request[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m vis_image\n\u001b[1;32m--> 156\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetMapId\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 157\u001b[0m response[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n\u001b[0;32m 158\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:748\u001b[0m, in \u001b[0;36mgetMapId\u001b[1;34m(params)\u001b[0m\n\u001b[0;32m 743\u001b[0m queryParams \u001b[38;5;241m=\u001b[39m {\n\u001b[0;32m 744\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfields\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m 745\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbody\u001b[39m\u001b[38;5;124m'\u001b[39m: request,\n\u001b[0;32m 746\u001b[0m }\n\u001b[0;32m 747\u001b[0m _maybe_populate_workload_tag(queryParams)\n\u001b[1;32m--> 748\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43m_execute_cloud_call\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 749\u001b[0m \u001b[43m \u001b[49m\u001b[43m_get_cloud_projects\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 750\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmaps\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 751\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mparent\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_get_projects_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mqueryParams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 752\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 753\u001b[0m map_name \u001b[38;5;241m=\u001b[39m result[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m 754\u001b[0m url_format \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/tiles/\u001b[39m\u001b[38;5;132;01m{z}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{x}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{y}\u001b[39;00m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m (\n\u001b[0;32m 755\u001b[0m _tile_base_url, _cloud_api_utils\u001b[38;5;241m.\u001b[39mVERSION, map_name)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:408\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m call\u001b[38;5;241m.\u001b[39mexecute(num_retries\u001b[38;5;241m=\u001b[39mnum_retries)\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 408\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m _translate_cloud_exception(e)\n", + "\u001b[1;31mEEException\u001b[0m: Image.visualize: Attempt to use array input on non array algorithm." + ] + }, + { + "ename": "EEException", + "evalue": "Image.visualize: Attempt to use array input on non array algorithm.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mHttpError\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:406\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 405\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum_retries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnum_retries\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\_helpers.py:130\u001b[0m, in \u001b[0;36mpositional..positional_decorator..positional_wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 129\u001b[0m logger\u001b[38;5;241m.\u001b[39mwarning(message)\n\u001b[1;32m--> 130\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapped(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\googleapiclient\\http.py:938\u001b[0m, in \u001b[0;36mHttpRequest.execute\u001b[1;34m(self, http, num_retries)\u001b[0m\n\u001b[0;32m 937\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resp\u001b[38;5;241m.\u001b[39mstatus \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m300\u001b[39m:\n\u001b[1;32m--> 938\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HttpError(resp, content, uri\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39muri)\n\u001b[0;32m 939\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpostproc(resp, content)\n", + "\u001b[1;31mHttpError\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[1;31mEEException\u001b[0m Traceback (most recent call last)", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1119\u001b[0m, in \u001b[0;36mLayerEditor._on_apply_click\u001b[1;34m(self, _)\u001b[0m\n\u001b[0;32m 1118\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_on_apply_click\u001b[39m(\u001b[38;5;28mself\u001b[39m, _):\n\u001b[1;32m-> 1119\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_embedded_widget\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mon_apply_click\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\map_widgets.py:1680\u001b[0m, in \u001b[0;36m_RasterLayerEditor.on_apply_click\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1678\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mon_apply_click\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 1679\u001b[0m vis \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_vis_params_from_selection()\n\u001b[1;32m-> 1680\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_host_map\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd_layer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1681\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_ee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_layer_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_opacity_slider\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalue\u001b[49m\n\u001b[0;32m 1682\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1683\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_layer\u001b[38;5;241m.\u001b[39mvisible \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 1685\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_legend_checkbox\u001b[38;5;241m.\u001b[39mvalue:\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\core.py:796\u001b[0m, in \u001b[0;36mMap.add_layer\u001b[1;34m(self, ee_object, vis_params, name, shown, opacity)\u001b[0m\n\u001b[0;32m 794\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ee_object, ee\u001b[38;5;241m.\u001b[39mImageCollection):\n\u001b[0;32m 795\u001b[0m ee_object \u001b[38;5;241m=\u001b[39m ee_object\u001b[38;5;241m.\u001b[39mmosaic()\n\u001b[1;32m--> 796\u001b[0m tile_layer \u001b[38;5;241m=\u001b[39m \u001b[43mee_tile_layers\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mEELeafletTileLayer\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 797\u001b[0m \u001b[43m \u001b[49m\u001b[43mee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mshown\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopacity\u001b[49m\n\u001b[0;32m 798\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 800\u001b[0m \u001b[38;5;66;03m# Remove the layer if it already exists.\u001b[39;00m\n\u001b[0;32m 801\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mremove(name)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:144\u001b[0m, in \u001b[0;36mEELeafletTileLayer.__init__\u001b[1;34m(self, ee_object, vis_params, name, shown, opacity, **kwargs)\u001b[0m\n\u001b[0;32m 134\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Initialize the ipyleaflet tile layer.\u001b[39;00m\n\u001b[0;32m 135\u001b[0m \n\u001b[0;32m 136\u001b[0m \u001b[38;5;124;03mArgs:\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 141\u001b[0m \u001b[38;5;124;03m opacity (float, optional): The layer's opacity represented as a number between 0 and 1. Defaults to 1.\u001b[39;00m\n\u001b[0;32m 142\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 143\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ee_object \u001b[38;5;241m=\u001b[39m ee_object\n\u001b[1;32m--> 144\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl_format \u001b[38;5;241m=\u001b[39m \u001b[43m_get_tile_url_format\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 145\u001b[0m \u001b[43m \u001b[49m\u001b[43mee_object\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_validate_vis_params\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 146\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 147\u001b[0m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__init__\u001b[39m(\n\u001b[0;32m 148\u001b[0m url\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39murl_format,\n\u001b[0;32m 149\u001b[0m attribution\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGoogle Earth Engine\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 154\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m 155\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\geemap\\ee_tile_layers.py:19\u001b[0m, in \u001b[0;36m_get_tile_url_format\u001b[1;34m(ee_object, vis_params)\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_get_tile_url_format\u001b[39m(ee_object, vis_params):\n\u001b[0;32m 18\u001b[0m image \u001b[38;5;241m=\u001b[39m _ee_object_to_image(ee_object, vis_params)\n\u001b[1;32m---> 19\u001b[0m map_id_dict \u001b[38;5;241m=\u001b[39m \u001b[43mee\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mImage\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetMapId\u001b[49m\u001b[43m(\u001b[49m\u001b[43mvis_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 20\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m map_id_dict[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtile_fetcher\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39murl_format\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\image.py:156\u001b[0m, in \u001b[0;36mImage.getMapId\u001b[1;34m(self, vis_params)\u001b[0m\n\u001b[0;32m 154\u001b[0m vis_image, request \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_apply_visualization(vis_params)\n\u001b[0;32m 155\u001b[0m request[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m vis_image\n\u001b[1;32m--> 156\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mdata\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetMapId\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 157\u001b[0m response[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mimage\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n\u001b[0;32m 158\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:748\u001b[0m, in \u001b[0;36mgetMapId\u001b[1;34m(params)\u001b[0m\n\u001b[0;32m 743\u001b[0m queryParams \u001b[38;5;241m=\u001b[39m {\n\u001b[0;32m 744\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfields\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[0;32m 745\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbody\u001b[39m\u001b[38;5;124m'\u001b[39m: request,\n\u001b[0;32m 746\u001b[0m }\n\u001b[0;32m 747\u001b[0m _maybe_populate_workload_tag(queryParams)\n\u001b[1;32m--> 748\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43m_execute_cloud_call\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 749\u001b[0m \u001b[43m \u001b[49m\u001b[43m_get_cloud_projects\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 750\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmaps\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 751\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mparent\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_get_projects_path\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mqueryParams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 752\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 753\u001b[0m map_name \u001b[38;5;241m=\u001b[39m result[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[0;32m 754\u001b[0m url_format \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m/tiles/\u001b[39m\u001b[38;5;132;01m{z}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{x}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{y}\u001b[39;00m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m (\n\u001b[0;32m 755\u001b[0m _tile_base_url, _cloud_api_utils\u001b[38;5;241m.\u001b[39mVERSION, map_name)\n", + "File \u001b[1;32mc:\\Users\\scone\\miniconda3\\envs\\lt-gee-py\\lib\\site-packages\\ee\\data.py:408\u001b[0m, in \u001b[0;36m_execute_cloud_call\u001b[1;34m(call, num_retries)\u001b[0m\n\u001b[0;32m 406\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m call\u001b[38;5;241m.\u001b[39mexecute(num_retries\u001b[38;5;241m=\u001b[39mnum_retries)\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m googleapiclient\u001b[38;5;241m.\u001b[39merrors\u001b[38;5;241m.\u001b[39mHttpError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m--> 408\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m _translate_cloud_exception(e)\n", + "\u001b[1;31mEEException\u001b[0m: Image.visualize: Attempt to use array input on non array algorithm." + ] + } + ], + "source": [ + "# Example 4: Displaying segment data\n", + "# In the top right corner hover over the wrench and click the 'i' to use the inspector. Click any point in the aoi to see values.\n", + "\n", + "seg_info = lt.get_segment_data('all', index_flip=True).clip(composite_params['area_of_interest'])\n", + "map = geemap.Map()\n", + "map.centerObject(composite_params['area_of_interest'], 13)\n", + "map.addLayer(seg_info, {}, 'seg_info')\n", + "map.addLayer(composite_params['area_of_interest'], {}, 'area_of_interest')\n", + "map" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af16e2e6-8944-41d4-8f75-1d4fc2a90b43", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1599f3bd1b044e7da3c7aba505ba2056", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[44.661026124368775, -122.31983825467653], controls=(WidgetControl(options=['position', 'transparen…" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example 5: Displaying rgb image\n", + "\n", + "vis_params = {\n", + " 'min': [604, -49, -2245],\n", + " 'max': [5592, 3147, 843],\n", + " 'gamma': [1, 1, 1]\n", + "}\n", + "\n", + "lt_rgb = lt.get_fitted_rgb_col(['TCB', 'TCG', 'TCW'], vis_params, composite_params[\"start_date\"], composite_params[\"end_date\"])\n", + "map = geemap.Map()\n", + "map.centerObject(composite_params['area_of_interest'], 13)\n", + "map.addLayer(lt_rgb, {}, 'lt_rgb')\n", + "map.addLayer(composite_params['area_of_interest'], {}, 'area_of_interest')\n", + "map" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "77fda100-3cab-4c86-966f-6d1e622f47cd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'https://earthengine.googleapis.com/v1/projects/ee-myscon/videoThumbnails/a05254000cc4e90c2d23faed3b712ce7-8da4cbb2519f2e9d172dd16b02d33f51:getPixels'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Example 6: Creating a gif using data from landtrendr\n", + "\n", + "vid_params = {\n", + " 'crs': 'EPSG:3857',\n", + " 'dimensions': 300,\n", + " 'region': composite_params['area_of_interest'],\n", + " 'framesPerSecond': 8\n", + "}\n", + "lt_rgb.getVideoThumbURL(vid_params)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a234bfd-b9c6-4a94-990c-48df53bab242", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "207c73e3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "lt-gee-py", + "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.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/ltgee/landtrendr.py b/src/ltgee/landtrendr.py index 9c2cc0d..6f29195 100644 --- a/src/ltgee/landtrendr.py +++ b/src/ltgee/landtrendr.py @@ -17,6 +17,195 @@ standardize_collection) +class Sentinel2Composite(ee.ImageCollection): + """ + SentinelComposite class for building a cloud-masked Sentinel-2 surface reflectance composite. + + Args: + area_of_interest (ee.Geometry): Area of interest. + start_date (datetime): Start date for the image collection. + end_date (datetime): End date for the image collection. + cloud_filter (int): Max cloud cover percentage allowed in images. + cloud_prb_thresh (int): Cloud probability threshold for masking. + nir_drk_thresh (float): NIR reflectance threshold for cloud shadows. + cloud_prj_dist (float): Max distance (in km) to project cloud shadows. + buffer (int): Buffer distance (in meters) for cloud edge. + exclude (dict): Dictionary for exluding images in the compositing + """ + _sr_band_scale = 1e4 + + def __init__(self, + area_of_interest: ee.Geometry, + start_date: datetime, + end_date: datetime, + cloud_filter: int = 20, + cloud_prb_thresh: int = 65, + nir_drk_thresh: float = 0.2, + cloud_prj_dist: float = 1.5, + buffer: int = 50, + exclude: dict = {}): + self.area_of_interest = area_of_interest + self.start_date = start_date + self.end_date = end_date + self.cloud_filter = cloud_filter + self.cloud_prb_thresh = cloud_prb_thresh + self.nir_drk_thresh = nir_drk_thresh + self.cloud_prj_dist = cloud_prj_dist + self.buffer = buffer + self.exclude = exclude + super().__init__(self._build_sr_collection()) + + # TODO: assertion checks on thresholds + def _build_sr_collection(self, debug: Optional[bool] = False): + """ + Builds a medoid composite of Landsat surface reflectance TM-equivalent bands 1,2,3,4,5,7 from Sentinel 2 Harmonized + This collection can be useful outside of use by LandTrendr, but is also the base for creating the input collection for LandTrendr. + + Returns: + ee.ImageCollection: A collection where each image represents the medoid of observations per TM-equivalent surface reflectance bands 1-5 and 7, for a given year. There will be as many images as there are years in the range inclusive of the start year and end year. + """ + dummy_collection = ee.ImageCollection( + [ee.Image([0, 0, 0, 0, 0, 0]).mask(ee.Image(0))]) + return ee.ImageCollection( + [self._build_medoid_mosaic(year, dummy_collection, debug) for year in range(self.start_date.year, self.end_date.year + 1)]) + + def _build_medoid_mosaic(self, + year: int, + dummy_collection: ee.ImageCollection, + debug: Optional[bool] = False): + collection = self._get_combined_sr_collection(year) + collection = collection.select(['B2', 'B3', 'B4', 'B8', 'B11', 'B12']) + + image_count = collection.size() + final_collection = ee.ImageCollection(ee.Algorithms.If(image_count.gt(0), collection, dummy_collection)) + + median = final_collection.median() + med_diff_collection = final_collection.map( + lambda image: calculate_median_diff(image, median)) + + # TODO: selection based on actual names + medoid_image = med_diff_collection.reduce(ee.Reducer.min(7)) + medoid_image = medoid_image.select([1, 2, 3, 4, 5, 6], + LandsatComposite._band_names) + + return medoid_image\ + .set('system:time_start', ee.Date.fromYMD(year, self.start_date.month, self.start_date.day).millis())\ + .toUint16() + + def _get_combined_sr_collection(self, year: int): + return self._get_sr_collection(year) + + def _get_sr_collection(self, year: int): + if self.start_date.month > self.end_date.month: + start_date = ee.Date.fromYMD( + year - 1, self.start_date.month, self.start_date.day) + end_date = ee.Date.fromYMD( + year, self.end_date.month, self.end_date.day) + else: + start_date = ee.Date.fromYMD( + year, self.start_date.month, self.start_date.day) + end_date = ee.Date.fromYMD( + year, self.end_date.month, self.end_date.day) + + s2_sr = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')\ + .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', self.cloud_filter))\ + .filterBounds(self.area_of_interest)\ + .filterDate(start_date, end_date) + + s2_cloud_prob = ee.ImageCollection('COPERNICUS/S2_CLOUD_PROBABILITY')\ + .filterBounds(self.area_of_interest)\ + .filterDate(start_date, end_date) + + + # Join collections to attach cloud probability to each SR image + collection = self._index_join(s2_sr, s2_cloud_prob, 's2cloudless')\ + .map(self._preprocess_image)\ + .set("system:time_start", start_date.millis()) + + return self._remove_images(collection) + + def _preprocess_image(self, image: int): + image = self._add_cloud_shdw_mask(image) + image = self._apply_cloud_shdw_mask(image) + return image + + def _remove_images(self, collection: ee.ImageCollection): + """ + Removes images from a collection based on the given exclude criteria. + + Args: + collection (ee.ImageCollection): The image collection to remove images from. + + Returns: + ee.ImageCollection: The updated image collection with images removed. + """ + if 'imageIds' in self.exclude: + exclude_list = self.exclude['imageIds'] + for image_id in exclude_list: + collection = collection.filter(ee.Filter.neq( + 'system:index', image_id.split('/')[-1])) + return collection + + def _index_join(self, collectionA, collectionB, property_name): + """ + Joins two collections on the system:index property and attaches the second collection to the first as a band. + """ + joined = ee.ImageCollection(ee.Join.saveFirst(property_name).apply( + primary=collectionA, + secondary=collectionB, + condition=ee.Filter.equals( + leftField='system:index', rightField='system:index' + ) + )) + return joined.map(lambda image: image.addBands(ee.Image(image.get(property_name)))) + + def _add_cloud_bands(self, image): + """ + Adds cloud bands to the image based on cloud probability and cloud mask. + """ + cloud_prb = ee.Image(image.get('s2cloudless')).select('probability') + is_cloud = cloud_prb.gt(self.cloud_prb_thresh).rename('clouds') + return image.addBands(ee.Image([cloud_prb, is_cloud])) + + def _add_shadow_bands(self, image): + """ + Adds shadow bands to the image to mask cloud shadows. + """ + not_water = image.select('SCL').neq(6) + dark_pixels = image.select('B8').lt(self.nir_drk_thresh * self._sr_band_scale).multiply(not_water).rename('dark_pixels') + + shadow_azimuth = ee.Number(90).subtract(ee.Number(image.get('MEAN_SOLAR_AZIMUTH_ANGLE'))) + cloud_proj = (image.select('clouds').directionalDistanceTransform(shadow_azimuth, self.cloud_prj_dist * 10) + .reproject(crs=image.select(0).projection(), scale=100) + .select('distance') + .mask() + .rename('cloud_transform')) + + shadows = cloud_proj.multiply(dark_pixels).rename('shadows') + return image.addBands(ee.Image([dark_pixels, cloud_proj, shadows])) + + def _add_cloud_shdw_mask(self, image): + """ + Adds a combined cloud and shadow mask to the image. + """ + image = self._add_cloud_bands(image) + image = self._add_shadow_bands(image) + + is_cloud_shdw = image.select('clouds').add(image.select('shadows')).gt(0) + is_cloud_shdw = (is_cloud_shdw.focalMin(2).focalMax(self.buffer * 2 / 20) + .reproject(crs=image.select([0]).projection(), scale=20) + .rename('cloudmask')) + + return image.addBands(is_cloud_shdw) + + def _apply_cloud_shdw_mask(self, image): + """ + Applies the cloud and shadow mask to the image, leaving only clear areas. + """ + not_cloud_shdw = image.select('cloudmask').Not() + return image.select('B.*').updateMask(not_cloud_shdw) + + class LandsatComposite(ee.ImageCollection): """ ### LandsatComposite class for building a Landsat surface reflectance composite for use in LandTrendr. @@ -228,8 +417,7 @@ def index(self): @index.setter def index(self, index: str): assert index in self._valid_indices or index in self._valid_indices_alt, \ - f"Index must be one of {self._valid_indices} or { - self._valid_indices_alt}" + f"Index must be one of {self._valid_indices} or {self._valid_indices_alt}" self._index = index @property