{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/opengeos/solara-geemap/blob/main/notebooks/06_timeseries.ipynb)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# %pip install -U geemap solara" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import geemap\n", "import ipywidgets as widgets\n", "import solara\n", "from geemap import get_current_year, jslink_slider_label\n", "\n", "\n", "class Map(geemap.Map):\n", " def __init__(self, **kwargs):\n", " super().__init__(**kwargs)\n", " self.add_basemap(\"Esri.WorldImagery\")\n", " self.add_ts_gui(position=\"topright\")\n", "\n", " def clean_up(self):\n", " if hasattr(self, \"slider_ctrl\") and self.slider_ctrl is not None:\n", " self.remove(self.slider_ctrl)\n", " delattr(self, \"slider_ctrl\")\n", "\n", " layer = self.find_layer(\"Time series\")\n", " if layer is not None:\n", " self.remove(layer)\n", " layer = self.find_layer(\"Image X\")\n", " if layer is not None:\n", " self.remove(layer)\n", "\n", " draw_layer = self.find_layer(\"Drawn Features\")\n", " if draw_layer is not None:\n", " self.remove(draw_layer)\n", "\n", " def add_ts_gui(self, position=\"topright\", **kwargs):\n", "\n", " widget_width = \"350px\"\n", " padding = \"0px 0px 0px 5px\" # upper, right, bottom, left\n", " style = {\"description_width\": \"initial\"}\n", " current_year = get_current_year()\n", "\n", " collection = widgets.Dropdown(\n", " options=[\n", " \"Landsat TM-ETM-OLI Surface Reflectance\",\n", " ],\n", " value=\"Landsat TM-ETM-OLI Surface Reflectance\",\n", " description=\"Collection:\",\n", " layout=widgets.Layout(width=widget_width, padding=padding),\n", " style=style,\n", " )\n", " bands = widgets.Dropdown(\n", " description=\"Bands:\",\n", " options=[\n", " \"Red/Green/Blue\",\n", " \"NIR/Red/Green\",\n", " \"SWIR2/SWIR1/NIR\",\n", " \"NIR/SWIR1/Red\",\n", " \"SWIR2/NIR/Red\",\n", " \"SWIR2/SWIR1/Red\",\n", " \"SWIR1/NIR/Blue\",\n", " \"NIR/SWIR1/Blue\",\n", " \"SWIR2/NIR/Green\",\n", " \"SWIR1/NIR/Red\",\n", " ],\n", " value=\"SWIR1/NIR/Red\",\n", " style=style,\n", " layout=widgets.Layout(width=\"195px\", padding=padding),\n", " )\n", "\n", " frequency = widgets.Dropdown(\n", " description=\"Frequency:\",\n", " options=[\"year\", \"quarter\", \"month\"],\n", " value=\"year\",\n", " style=style,\n", " layout=widgets.Layout(width=\"150px\", padding=padding),\n", " )\n", "\n", " start_year = widgets.IntSlider(\n", " description=\"Start Year:\",\n", " value=1984,\n", " min=1984,\n", " max=current_year,\n", " readout=False,\n", " style=style,\n", " layout=widgets.Layout(width=\"138px\", padding=padding),\n", " )\n", "\n", " start_year_label = widgets.Label(\"1984\")\n", " jslink_slider_label(start_year, start_year_label)\n", "\n", " end_year = widgets.IntSlider(\n", " description=\"End Year:\",\n", " value=current_year,\n", " min=1984,\n", " max=current_year,\n", " readout=False,\n", " style=style,\n", " layout=widgets.Layout(width=\"138px\", padding=padding),\n", " )\n", " end_year_label = widgets.Label(str(current_year))\n", " jslink_slider_label(end_year, end_year_label)\n", "\n", " start_month = widgets.IntSlider(\n", " description=\"Start Month:\",\n", " value=5,\n", " min=1,\n", " max=12,\n", " readout=False,\n", " style=style,\n", " layout=widgets.Layout(width=\"145px\", padding=padding),\n", " )\n", "\n", " start_month_label = widgets.Label(\n", " \"5\",\n", " layout=widgets.Layout(width=\"20px\", padding=padding),\n", " )\n", " jslink_slider_label(start_month, start_month_label)\n", "\n", " end_month = widgets.IntSlider(\n", " description=\"End Month:\",\n", " value=10,\n", " min=1,\n", " max=12,\n", " readout=False,\n", " style=style,\n", " layout=widgets.Layout(width=\"155px\", padding=padding),\n", " )\n", "\n", " end_month_label = widgets.Label(\"10\")\n", " jslink_slider_label(end_month, end_month_label)\n", "\n", " output = widgets.Output()\n", "\n", " button_width = \"113px\"\n", " apply_btn = widgets.Button(\n", " description=\"Time slider\",\n", " button_style=\"primary\",\n", " tooltip=\"Click to create timeseries\",\n", " style=style,\n", " layout=widgets.Layout(padding=\"0px\", width=button_width),\n", " )\n", "\n", " split_btn = widgets.Button(\n", " description=\"Split map\",\n", " button_style=\"primary\",\n", " tooltip=\"Click to create timeseries\",\n", " style=style,\n", " layout=widgets.Layout(padding=\"0px\", width=button_width),\n", " )\n", "\n", " reset_btn = widgets.Button(\n", " description=\"Reset\",\n", " button_style=\"primary\",\n", " style=style,\n", " layout=widgets.Layout(padding=\"0px\", width=button_width),\n", " )\n", "\n", " vbox = widgets.VBox(\n", " [\n", " collection,\n", " widgets.HBox([bands, frequency]),\n", " widgets.HBox([start_year, start_year_label, end_year, end_year_label]),\n", " widgets.HBox(\n", " [start_month, start_month_label, end_month, end_month_label]\n", " ),\n", " widgets.HBox([apply_btn, split_btn, reset_btn]),\n", " output,\n", " ]\n", " )\n", " self.add_widget(vbox, position=position, add_header=True)\n", "\n", " def apply_btn_click(change):\n", "\n", " if hasattr(self, \"slider_ctrl\") and self.slider_ctrl is not None:\n", " self.remove(self.slider_ctrl)\n", " delattr(self, \"slider_ctrl\")\n", "\n", " with output:\n", " output.clear_output()\n", " if self.user_roi is None:\n", " output.append_stdout(\"Please draw a ROI first.\")\n", " else:\n", " output.append_stdout(\"Creating time series...\")\n", " collection = geemap.landsat_timeseries(\n", " roi=self.user_roi,\n", " start_year=start_year.value,\n", " end_year=end_year.value,\n", " start_date=str(start_month.value).zfill(2) + \"-01\",\n", " end_date=str(end_month.value).zfill(2) + \"-01\",\n", " frequency=frequency.value,\n", " )\n", " vis_params = {\n", " \"bands\": bands.value.split(\"/\"),\n", " \"min\": 0,\n", " \"max\": 0.4,\n", " }\n", "\n", " if frequency.value == \"year\":\n", " date_format = \"YYYY\"\n", " elif frequency.value == \"quarter\":\n", " date_format = \"YYYY-MM\"\n", " elif frequency.value == \"month\":\n", " date_format = \"YYYY-MM\"\n", "\n", " self.add_time_slider(\n", " collection,\n", " region=self.user_roi,\n", " vis_params=vis_params,\n", " date_format=date_format,\n", " )\n", " self._draw_control.clear()\n", " draw_layer = self.find_layer(\"Drawn Features\")\n", " if draw_layer is not None:\n", " self.remove(draw_layer)\n", " output.clear_output()\n", "\n", " apply_btn.on_click(apply_btn_click)\n", "\n", " def split_btn_click(change):\n", "\n", " if hasattr(self, \"slider_ctrl\") and self.slider_ctrl is not None:\n", " self.remove(self.slider_ctrl)\n", " delattr(self, \"slider_ctrl\")\n", "\n", " with output:\n", " output.clear_output()\n", " if self.user_roi is None:\n", " output.append_stdout(\"Please draw a ROI first.\")\n", " else:\n", " output.append_stdout(\"Creating time series...\")\n", " collection = geemap.landsat_timeseries(\n", " roi=self.user_roi,\n", " start_year=start_year.value,\n", " end_year=end_year.value,\n", " start_date=str(start_month.value).zfill(2) + \"-01\",\n", " end_date=str(end_month.value).zfill(2) + \"-01\",\n", " frequency=frequency.value,\n", " )\n", " vis_params = {\n", " \"bands\": bands.value.split(\"/\"),\n", " \"min\": 0,\n", " \"max\": 0.4,\n", " }\n", "\n", " if frequency.value == \"year\":\n", " date_format = \"YYYY\"\n", " dates = geemap.image_dates(collection, date_format).getInfo()\n", " elif frequency.value == \"quarter\":\n", " date_format = \"YYYY-MM\"\n", " dates = geemap.image_dates(collection, date_format).getInfo()\n", " elif frequency.value == \"month\":\n", " date_format = \"YYYY-MM\"\n", " dates = geemap.image_dates(collection, date_format).getInfo()\n", "\n", " self.ts_inspector(\n", " collection,\n", " left_names=dates,\n", " left_vis=vis_params,\n", " add_close_button=True,\n", " )\n", " output.clear_output()\n", "\n", " try:\n", " self._draw_control.clear()\n", " draw_layer = self.find_layer(\"Drawn Features\")\n", " if draw_layer is not None:\n", " self.remove(draw_layer)\n", " except Exception as e:\n", " print(e)\n", "\n", " split_btn.on_click(split_btn_click)\n", "\n", " def reset_btn_click(change):\n", " output.clear_output()\n", " self.clean_up()\n", "\n", " reset_btn.on_click(reset_btn_click)\n", "\n", "\n", "@solara.component\n", "def Page():\n", " with solara.Column(style={\"min-width\": \"500px\"}):\n", " Map.element(\n", " center=[20, -0],\n", " zoom=2,\n", " height=\"750px\",\n", " zoom_ctrl=False,\n", " measure_ctrl=False,\n", " )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Page()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "geo", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.8" } }, "nbformat": 4, "nbformat_minor": 2 }