diff --git a/jupyter-notebooks/Tile-Services/images/bokeh_plot.png b/jupyter-notebooks/Tile-Services/images/bokeh_plot.png new file mode 100644 index 0000000..867d1e8 Binary files /dev/null and b/jupyter-notebooks/Tile-Services/images/bokeh_plot.png differ diff --git a/jupyter-notebooks/Tile-Services/images/bokeh_plot_zoomed_in.png b/jupyter-notebooks/Tile-Services/images/bokeh_plot_zoomed_in.png new file mode 100644 index 0000000..fd6b2a3 Binary files /dev/null and b/jupyter-notebooks/Tile-Services/images/bokeh_plot_zoomed_in.png differ diff --git a/jupyter-notebooks/Tile-Services/images/leaflet_map.png b/jupyter-notebooks/Tile-Services/images/leaflet_map.png new file mode 100644 index 0000000..5302154 Binary files /dev/null and b/jupyter-notebooks/Tile-Services/images/leaflet_map.png differ diff --git a/jupyter-notebooks/Tile-Services/mapping_basemap_tiles_bokeh.ipynb b/jupyter-notebooks/Tile-Services/mapping_basemap_tiles_bokeh.ipynb new file mode 100644 index 0000000..0c9eb21 --- /dev/null +++ b/jupyter-notebooks/Tile-Services/mapping_basemap_tiles_bokeh.ipynb @@ -0,0 +1,217 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tile Services Mapping Demo\n", + "\n", + "This notebook demonstrates how to render Planet Basemaps via [XYZ Tile Services](https://developers.planet.com/docs/basemaps/tile-services/#basemap-tile-service).\n", + "\n", + "In this example, you will build an interactive map plots with [Bokeh](https://bokeh.org/) that looks like this one:\n", + "\n", + "![bokeh_plot.png](images/bokeh_plot.png)\n", + "\n", + "Additionally, you will see how to make linked plots so that you can zoom and pan across multiple maps together:\n", + "\n", + "![bokeh_plot_zoomed_in.png](images/bokeh_plot_zoomed_in.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ## install dependencies if needed using your preferred package manager\n", + "# !pip install bokeh jupyter_bokeh xyzservices" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import getpass\n", + "import os\n", + "\n", + "from bokeh.io import output_notebook\n", + "from bokeh.layouts import gridplot\n", + "from bokeh.plotting import figure, show\n", + "from xyzservices import TileProvider" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# setup Planet API key\n", + "PLANET_API_KEY = os.getenv('PL_API_KEY')\n", + "if not PLANET_API_KEY:\n", + " PLANET_API_KEY = getpass.getpass('Enter your Planet API key: ')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# You may need to adjust this to a location within your own Area of Access\n", + "lat, lon = 37.7749, -122.4194" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "output_notebook()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Make the Maps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "basemap_names = ['global_monthly_2024_02_mosaic', 'global_monthly_2024_05_mosaic', 'global_monthly_2024_08_mosaic', 'global_monthly_2024_11_mosaic']\n", + "\n", + "# Create a list to store the figure objects\n", + "plots = []\n", + "\n", + "# Create each map figure\n", + "for basemap in basemap_names:\n", + " provider = TileProvider(\n", + " name=basemap,\n", + " url=f'https://tiles.planet.com/basemaps/v1/planet-tiles/{basemap}/gmap/{{z}}/{{x}}/{{y}}.png?api_key={PLANET_API_KEY}',\n", + " attribution='Planet Labs PBC'\n", + " )\n", + " \n", + " p = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),\n", + " x_axis_type=\"mercator\", y_axis_type=\"mercator\",\n", + " width=400, height=400, # Set dimensions for each plot\n", + " active_scroll=\"wheel_zoom\",\n", + " active_drag=\"pan\",\n", + " title=basemap.replace('global_monthly_', '').replace('_mosaic', ''))\n", + " \n", + " p.add_tile(provider)\n", + " plots.append(p)\n", + "\n", + "# Arrange plots in a 2x2 grid\n", + "grid = gridplot([[plots[0], plots[1]], \n", + " [plots[2], plots[3]]], \n", + " sizing_mode=\"scale_width\")\n", + "\n", + "# Show the combined plot\n", + "show(grid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should now see 4 separately rendered map figures in a grid with independent control. Try zooming and panning." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a list to store the figure objects\n", + "plots = []\n", + "\n", + "# Create the first plot to use as a reference for linking\n", + "ref_plot = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),\n", + " x_axis_type=\"mercator\", y_axis_type=\"mercator\",\n", + " width=400, height=400,\n", + " active_scroll=\"wheel_zoom\",\n", + " active_drag=\"pan\",\n", + " title=basemap_names[0].replace('global_monthly_', '').replace('_mosaic', ''))\n", + "\n", + "provider = TileProvider(\n", + " name=basemap_names[0],\n", + " url=f'https://tiles.planet.com/basemaps/v1/planet-tiles/{basemap_names[0]}/gmap/{{z}}/{{x}}/{{y}}.png?api_key={PLANET_API_KEY}',\n", + " attribution='Planet Labs PBC'\n", + ")\n", + "ref_plot.add_tile(provider)\n", + "plots.append(ref_plot)\n", + "\n", + "# Create the rest of the plots linked to the first one\n", + "for basemap in basemap_names[1:]:\n", + " provider = TileProvider(\n", + " name=basemap,\n", + " url=f'https://tiles.planet.com/basemaps/v1/planet-tiles/{basemap}/gmap/{{z}}/{{x}}/{{y}}.png?api_key={PLANET_API_KEY}',\n", + " attribution='Planet Labs PBC'\n", + " )\n", + " \n", + " # Create new plot with ranges linked to the reference plot\n", + " p = figure(x_range=ref_plot.x_range, y_range=ref_plot.y_range,\n", + " x_axis_type=\"mercator\", y_axis_type=\"mercator\",\n", + " width=400, height=400,\n", + " active_scroll=\"wheel_zoom\",\n", + " active_drag=\"pan\",\n", + " title=basemap.replace('global_monthly_', '').replace('_mosaic', ''))\n", + " \n", + " p.add_tile(provider)\n", + " plots.append(p)\n", + "\n", + "# Arrange plots in a 2x2 grid\n", + "grid = gridplot([[plots[0], plots[1]], \n", + " [plots[2], plots[3]]], \n", + " sizing_mode=\"scale_width\")\n", + "\n", + "# Show the combined plot\n", + "show(grid)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now try zooming and panning and the separate maps in the grid should stay linked." + ] + } + ], + "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.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/jupyter-notebooks/Tile-Services/mapping_basemap_tiles_leaflet.ipynb b/jupyter-notebooks/Tile-Services/mapping_basemap_tiles_leaflet.ipynb new file mode 100644 index 0000000..fbaf173 --- /dev/null +++ b/jupyter-notebooks/Tile-Services/mapping_basemap_tiles_leaflet.ipynb @@ -0,0 +1,150 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tile Services Mapping Demo\n", + "\n", + "This notebook demonstrates how to render Planet Basemaps via [XYZ Tile Services](https://developers.planet.com/docs/basemaps/tile-services/#basemap-tile-service).\n", + "\n", + "In this example, you will build an interactive map that looks like this one:\n", + "\n", + "![leaflet_map.png](images/leaflet_map.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "## install ipyleaflet if needed\n", + "# !pip install ipyleaflet" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import getpass\n", + "import os\n", + "import ipyleaflet\n", + "from ipyleaflet import TileLayer, Map, basemaps" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# setup Planet API key\n", + "PLANET_API_KEY = os.getenv('PL_API_KEY')\n", + "if not PLANET_API_KEY:\n", + " PLANET_API_KEY = getpass.getpass('Enter your Planet API key: ')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# You may need to adjust this to a location within your own Area of Access\n", + "lat, lon = 37.7749, -122.4194" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Make the Map" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "498a071f22fa46e9aa6a6884dfea749e", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Map(center=[37.7749, -122.4194], controls=(ZoomControl(options=['position', 'zoom_in_text', 'zoom_in_title', '…" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m = Map(\n", + " center=(lat, lon),\n", + " zoom=12,\n", + " basemap=basemaps.CartoDB.Positron # this is an underlying basemap that will show up below our Planet tile layers\n", + ")\n", + "\n", + "# replace these with different basemap names if you do not have access to global monthly basemaps\n", + "basemap_names = ['global_monthly_2024_11_mosaic', 'global_monthly_2024_08_mosaic', 'global_monthly_2024_05_mosaic']\n", + "for basemap in basemap_names:\n", + " layer = TileLayer(\n", + " url=f'https://tiles.planet.com/basemaps/v1/planet-tiles/{basemap}/gmap/{{z}}/{{x}}/{{y}}.png?api_key={PLANET_API_KEY}',\n", + " name=basemap,\n", + " attribution='Planet Labs PBC'\n", + " )\n", + " m.add_layer(layer)\n", + "\n", + "# Add layer control\n", + "layer_control = ipyleaflet.LayersControl(position='topright')\n", + "m.add_control(layer_control)\n", + "\n", + "# Display the map\n", + "m" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should now see a rendered map with one layer per basemap.\n", + "Try toggling layers on/off to see how the area in view changed over time." + ] + } + ], + "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.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}