Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time series web mapping with leaf map draft notebook #986

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
286 changes: 286 additions & 0 deletions Frequently_used_code/Time_series_web_mapping.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interactive time-series geospatial data on a web map <img align=\"right\" src=\"../Supplementary_data/dea_logo.jpg\">\n",
"\n",
"* [**Sign up to the DEA Sandbox**](https://docs.dea.ga.gov.au/setup/sandbox.html) to run this notebook interactively from a browser\n",
"* **Compatibility:** Notebook currently compatible with both the `NCI` and `DEA Sandbox` environments\n",
"* **Products used:** \n",
"[ga_ls_fc_3](https://explorer.sandbox.dea.ga.gov.au/products/ga_ls_fc_3)\n",
"\n",
"## Background\n",
"\n",
"[Leaflet](https://leafletjs.com/) is the leading open-source JavaScript library for mobile-friendly interactive maps.\n",
"This notebook additionally uses [Leafmap](leafmap.org) to expose this functionality within the jupyter environment\n",
"This library enables interactive maps in the Jupyter notebook/JupyterLab environment.\n",
"\n",
"## Description\n",
"\n",
"This notebook demonstrates how to visualise timeseries data in an interactive manner\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Getting started\n",
"To run this analysis, run all the cells in the notebook, starting with the \"Load packages\" cell."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Load packages"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import numpy as np\n",
"from ipywidgets import widgets as w\n",
"from IPython.display import display\n",
"import leafmap\n",
"import datacube\n",
"import odc.ui\n",
"import pandas as pd\n",
"import odc.geo.xr\n",
"from ipyleaflet import ImageOverlay"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Connect to the datacube"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"dc = datacube.Datacube(app='Imagery_on_web_map')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def da_to_timeseries_imageoverlay(data):\n",
" \"\"\"\n",
" Converts a xarray.DataArray into a dictionary with times as keys and ipyleaflet ImageOverlays as values.\n",
" \n",
" Parameters\n",
" ----------\n",
" da : xarray dataarray or a numpy ndarray \n",
" \n",
" Returns\n",
" -------\n",
" out : dictionary\n",
" bounds: bounds of input da\n",
" \n",
" \"\"\"\n",
" out = {}\n",
" for time in data.time.values:\n",
" date = str(pd.to_datetime(time).date())\n",
" print('\\r', 'Opening:', date, end='')\n",
" single = data.sel(time=time)\n",
" vmin, vmax = np.nanpercentile(data.data, [2, 98])\n",
" rgba = single.odc.colorize(vmin=vmin, vmax=vmax)\n",
" data_url = rgba.odc.compress(as_data_url=True)\n",
" (x1, y1), _, (x2, y2) = rgba.odc.geobox.extent.exterior.to_crs(\"epsg:4326\").points[:3]\n",
" bounds = [[y1, x1], [y2, x2]]\n",
" raster = ImageOverlay(url=data_url, bounds=bounds,opacity=0.7)\n",
" out[date] = raster\n",
" return out, bounds"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6afe49d7332941ce96ce20c301a8a516",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(HBox(children=(Label(value=''), Label(value='')), layout=Layout(justify_content='space-between'…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Set up a region to load data\n",
"query = {\n",
" 'y': (-34.06813, -34.22099),\n",
" 'x': (139.83315, 140.05151),\n",
" 'time': ('2000-08-31', '2000-10-31'),\n",
"}\n",
"\n",
"# Load DEA Fractional Cover data from the datacube\n",
"fc = dc.load(product='ga_ls_fc_3',\n",
" measurements=['pv'],\n",
" output_crs='EPSG:32754',\n",
" resolution=(-30, 30),\n",
" group_by='solar_day',\n",
" progress_cbk=odc.ui.with_ui_cbk(),\n",
" **query)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Opening: 2000-10-26"
]
}
],
"source": [
"time_dict, bounds = da_to_timeseries_imageoverlay(fc['pv'])"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# Create leafmap approximately centered using bounds\n",
"m = leafmap.Map(center = bounds[0],\n",
" zoom=11)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"# Create dictionary of images for time slider\n",
"m.add_time_slider(time_dict)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c087203d656f46bd869724c169545106",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Map(center=[-34.06619528124256, 139.83298969912786], controls=(ZoomControl(options=['position', 'zoom_in_text'…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Display map\n",
"display(m)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Additional information\n",
"\n",
"**License:** The code in this notebook is licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). \n",
"Digital Earth Australia data is licensed under the [Creative Commons by Attribution 4.0](https://creativecommons.org/licenses/by/4.0/) license.\n",
"\n",
"**Contact:** If you need assistance, please post a question on the [Open Data Cube Slack channel](http://slack.opendatacube.org/) or on the [GIS Stack Exchange](https://gis.stackexchange.com/questions/ask?tags=open-data-cube) using the `open-data-cube` tag (you can view previously asked questions [here](https://gis.stackexchange.com/questions/tagged/open-data-cube)).\n",
"If you would like to report an issue with this notebook, you can file one on [Github](https://github.com/GeoscienceAustralia/dea-notebooks).\n",
"\n",
"**Last modified:** September 2021\n",
"\n",
"**Compatible datacube version:** "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(datacube.__version__)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tags\n",
"Browse all available tags on the DEA User Guide's [Tags Index](https://docs.dea.ga.gov.au/genindex.html)"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"**Tags**: :index:`NCI compatible`, :index:`sandbox compatible`, :index:`sentinel 2`, :index:`widgets`, :index:`ipyleaflet`, :index:`interactive`"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}