{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "[](https://demo.leafmap.org/lab/index.html?path=workshops/SIGSPATIAL_2021.ipynb)\n", "[](https://gishub.org/acm-colab)\n", "" ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "**Interactive Mapping and Geospatial Analysis with Leafmap & Jupyter**\n", "\n", "\n", "This notebook was developed for the [leafmap workshop](https://dataoceanlab.github.io/spatial-api-2021/files/paper_1.pdf) taking place on November 2, 2021 at the [The 3rd ACM SIGSPATIAL International Workshop on APIs and Libraries for Geospatial Data Science (SpatialAPI 2021)](https://dataoceanlab.github.io/spatial-api-2021).\n", "\n", "Author: [Qiusheng Wu](https://github.com/giswqs)\n", "\n", "Launch this notebook to execute code interactively using: \n", "- Google Colab: https://gishub.org/acm-colab\n", "- Pangeo Binder JupyterLab: https://gishub.org/acm-binder\n", "- Pangeo Binder Jupyter Notebook: https://gishub.org/acm-binder-nb\n", "- Streamlit web app: https://streamlit.gishub.org\n", "\n", "\n", "## Introduction\n", "\n", "### Workshop description\n", "\n", "[Leafmap](https://leafmap.org) is a Python package for interactive mapping and geospatial analysis with minimal coding in a Jupyter environment. It is built upon a number of open-source packages, such as [folium](https://github.com/python-visualization/folium) and [ipyleaflet](https://github.com/jupyter-widgets/ipyleaflet) (for creating interactive maps), [WhiteboxTools](https://github.com/jblindsay/whitebox-tools) and [whiteboxgui](https://github.com/opengeos/whiteboxgui) (for analyzing geospatial data), and [ipywidgets](https://github.com/jupyter-widgets/ipywidgets) (for designing interactive graphical user interface). The WhiteboxTools library currently contains 480+ tools for advanced geospatial analysis. Leafmap provides many convenient functions for loading and visualizing geospatial data with only one line of code. Users can also use the interactive user interface to load geospatial data without coding. Anyone with a web browser and Internet connection can use leafmap to perform geospatial analysis and data visualization in the cloud with minimal coding. The topics that will be covered in this workshop include: \n", "\n", "1. A brief introduction to leafmap and relevant web resources \n", "2. Creating interactive maps using multiple plotting backends\n", "3. Changing basemaps\n", "4. Loading and visualizing vector/raster data\n", "5. Using Cloud Optimized GeoTIFF (COG) and SpatialTemporal Asset Catalog (STAC)\n", "6. Downloading OpenStreetMap data\n", "7. Creating custom legends and colorbars\n", "8. Creating split-panel maps and linked maps\n", "9. Performing geospatial analysis using whiteboxgui.\n", "10. Discussion and Q&A\n", "\n", "\n", "This workshop is intended for scientific programmers, data scientists, geospatial analysts, and concerned citizens of Earth. The attendees are expected to have a basic understanding of Python and the Jupyter ecosystem. Familiarity with Earth science and geospatial datasets is useful but not required. More information about leafmap can be found at https://leafmap.org.\n", "\n", "\n", "### Jupyter keyboard shortcuts\n", "\n", "- Shift+Enter: run cell, select below\n", "- Ctrl+Enter: : run selected cells\n", "- Alt+Enter: run cell and insert below\n", "- Tab: code completion or indent\n", "- Shift+Tab: tooltip\n", "- Ctrl+/: comment out code" ] }, { "cell_type": "markdown", "id": "2", "metadata": {}, "source": [ "## Set up environment\n", "\n", "### Required Python packages:\n", "* [leafmap](https://github.com/opengeos/leafmap) - A Python package for interactive mapping and geospatial analysis with minimal coding in a Jupyter environment\n", "* [keplergl](https://docs.kepler.gl/docs/keplergl-jupyter) - A high-performance web-based application for visual exploration of large-scale geolocation data sets\n", "* [pydeck](https://deckgl.readthedocs.io/en/latest) - High-scale spatial rendering in Python, powered by deck.gl.\n", "* [geopandas](https://geopandas.org) - An open source project to make working with geospatial data in python easier. \n", "* [xarray-leaflet](https://github.com/davidbrochart/xarray_leaflet) - An xarray extension for tiled map plotting.\n", "\n", "### Use Google Colab\n", "\n", "Click the button below to open this notebook in Google Colab and execute code interactively.\n", "\n", "[](https://demo.leafmap.org/lab/index.html?path=workshops/SIGSPATIAL_2021.ipynb)\n", "[](https://gishub.org/acm-colab)" ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": {}, "outputs": [], "source": [ "# !pip install leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": {}, "outputs": [], "source": [ "import os\n", "import subprocess\n", "import sys" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "import warnings\n", "\n", "warnings.filterwarnings(\"ignore\")" ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [ "A function for installing Python packages." ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": {}, "outputs": [], "source": [ "def install(package):\n", " subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", package])" ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "Install required Python packages in Google Colab." ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "pkgs = [\n", " \"leafmap\",\n", " \"geopandas\",\n", " \"keplergl\",\n", " \"pydeck\",\n", " \"xarray_leaflet\",\n", " \"osmnx\",\n", " \"pygeos\",\n", " \"imageio\",\n", " \"tifffile\",\n", "]\n", "if \"google.colab\" in sys.modules:\n", " for pkg in pkgs:\n", " install(pkg)" ] }, { "cell_type": "markdown", "id": "10", "metadata": {}, "source": [ "### Use Pangeo Binder\n", "\n", "Click the buttons below to open this notebook in JupyterLab (first button) or Jupyter Notebook (second button) and execute code interactively.\n", "\n", "[](https://gishub.org/acm-binder)\n", "[](https://gishub.org/acm-binder-nb)\n", "\n", "- JupyterLab: https://gishub.org/acm-binder\n", "- Jupyter Notebook: https://gishub.org/acm-binder-nb" ] }, { "cell_type": "markdown", "id": "11", "metadata": {}, "source": [ "### Use Miniconda/Anaconda\n", "\n", "If you have\n", "[Anaconda](https://www.anaconda.com/distribution/#download-section) or [Miniconda](https://docs.conda.io/en/latest/miniconda.html) installed on your computer, you can install leafmap using the following commands. Leafmap has an optional dependency - [geopandas](https://geopandas.org), which can be challenging to install on some computers, especially Windows. It is highly recommended that you create a fresh conda environment to install geopandas and leafmap. Follow the commands below to set up a conda env and install geopandas, leafmap, keplergl, and xarray_leaflet. \n", "\n", "```\n", "conda create -n geo python=3.8\n", "conda activate geo\n", "conda install geopandas\n", "conda install mamba -c conda-forge\n", "mamba install leafmap keplergl pydeck xarray_leaflet -c conda-forge\n", "mamba install osmnx pygeos imageio tifffile -c conda-forge\n", "jupyter lab\n", "```" ] }, { "cell_type": "code", "execution_count": null, "id": "12", "metadata": {}, "outputs": [], "source": [ "try:\n", " import leafmap\n", "except ImportError:\n", " install(\"leafmap\")" ] }, { "cell_type": "markdown", "id": "13", "metadata": {}, "source": [ "## Create an interactive map\n", "\n", "`Leafmap` has five plotting backends: [folium](https://github.com/python-visualization/folium), [ipyleaflet](https://github.com/jupyter-widgets/ipyleaflet), [here-map](https://github.com/heremaps/here-map-widget-for-jupyter), [kepler.gl](https://docs.kepler.gl/docs/keplergl-jupyter), and [pydeck](https://deckgl.readthedocs.io). Note that the backends do not offer equal functionality. Some interactive functionality in `ipyleaflet` might not be available in other plotting backends. To use a specific plotting backend, use one of the following:\n", "\n", "- `import leafmap.leafmap as leafmap`\n", "- `import leafmap.foliumap as leafmap`\n", "- `import leafmap.heremap as leafmap`\n", "- `import leafmap.kepler as leafmap`\n", "- `import leafmap.deck as leafmap`\n", "\n", "### Use ipyleaflet" ] }, { "cell_type": "code", "execution_count": null, "id": "14", "metadata": {}, "outputs": [], "source": [ "import leafmap\n", "\n", "m = leafmap.Map()\n", "m" ] }, { "cell_type": "markdown", "id": "15", "metadata": {}, "source": [ "### Use folium" ] }, { "cell_type": "code", "execution_count": null, "id": "16", "metadata": {}, "outputs": [], "source": [ "import leafmap.foliumap as leafmap\n", "\n", "m = leafmap.Map()\n", "m" ] }, { "cell_type": "markdown", "id": "17", "metadata": {}, "source": [ "### Use kepler.gl" ] }, { "cell_type": "code", "execution_count": null, "id": "18", "metadata": {}, "outputs": [], "source": [ "import leafmap.kepler as leafmap\n", "\n", "m = leafmap.Map()\n", "m" ] }, { "cell_type": "markdown", "id": "19", "metadata": {}, "source": [ "If you encounter an error saying `Error displaying widget: model not found` when trying to display the map, you can use `m.static_map()` as a workaround until this [kepler.gl bug](https://github.com/keplergl/kepler.gl/issues/1165) has been resolved." ] }, { "cell_type": "code", "execution_count": null, "id": "20", "metadata": {}, "outputs": [], "source": [ "m.static_map(width=1280, height=600)" ] }, { "cell_type": "markdown", "id": "21", "metadata": {}, "source": [ "### Use pydeck" ] }, { "cell_type": "code", "execution_count": null, "id": "22", "metadata": {}, "outputs": [], "source": [ "import leafmap.deck as leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "23", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m" ] }, { "cell_type": "markdown", "id": "24", "metadata": {}, "source": [ "## Customize the default map\n", "\n", "### Specify map center and zoom level" ] }, { "cell_type": "code", "execution_count": null, "id": "25", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "26", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=(40, -100), zoom=4) # center=(lat, lon)\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "27", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=(51.5, -0.15), zoom=17)\n", "m" ] }, { "cell_type": "markdown", "id": "28", "metadata": {}, "source": [ "### Change map size" ] }, { "cell_type": "code", "execution_count": null, "id": "29", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(height=\"400px\", width=\"800px\")\n", "m" ] }, { "cell_type": "markdown", "id": "30", "metadata": {}, "source": [ "### Set control visibility\n", "\n", "When creating a map, set the following controls to either `True` or `False` as appropriate.\n", "\n", "* attribution_control\n", "* draw_control\n", "* fullscreen_control\n", "* layers_control\n", "* measure_control\n", "* scale_control\n", "* toolbar_control" ] }, { "cell_type": "code", "execution_count": null, "id": "31", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(\n", " draw_control=False,\n", " measure_control=False,\n", " fullscreen_control=False,\n", " attribution_control=False,\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "32", "metadata": {}, "source": [ "Remove all controls from the map." ] }, { "cell_type": "code", "execution_count": null, "id": "33", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.clear_controls()\n", "m" ] }, { "cell_type": "markdown", "id": "34", "metadata": {}, "source": [ "## Change basemaps\n", "\n", "Specify a Google basemap to use, can be one of [\"ROADMAP\", \"TERRAIN\", \"SATELLITE\", \"HYBRID\"]." ] }, { "cell_type": "code", "execution_count": null, "id": "35", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "36", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(google_map=\"TERRAIN\") # HYBRID, ROADMAP, SATELLITE, TERRAIN\n", "m" ] }, { "cell_type": "markdown", "id": "37", "metadata": {}, "source": [ "Add a basemap using the `add_basemap()` function." ] }, { "cell_type": "code", "execution_count": null, "id": "38", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_basemap(\"Esri.NatGeoWorldMap\")\n", "m" ] }, { "cell_type": "markdown", "id": "39", "metadata": {}, "source": [ "Print out the list of available basemaps." ] }, { "cell_type": "code", "execution_count": null, "id": "40", "metadata": {}, "outputs": [], "source": [ "for basemap in leafmap.basemaps:\n", " print(basemap)" ] }, { "cell_type": "markdown", "id": "41", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "execution_count": null, "id": "42", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_tile_layer(\n", " url=\"https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}\",\n", " name=\"Google Satellite\",\n", " attribution=\"Google\",\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "43", "metadata": {}, "source": [ "### Add WMS tile layer\n", "\n", "More WMS basemaps can be found at the following websites:\n", "\n", "- USGS National Map: https://viewer.nationalmap.gov/services\n", "- MRLC NLCD Land Cover data: https://www.mrlc.gov/data-services-page\n", "- FWS NWI Wetlands data: https://www.fws.gov/wetlands/Data/Web-Map-Services.html" ] }, { "cell_type": "code", "execution_count": null, "id": "44", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "naip_url = \"https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer?\"\n", "m.add_wms_layer(\n", " url=naip_url, layers=\"0\", name=\"NAIP Imagery\", format=\"image/png\", shown=True\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "45", "metadata": {}, "source": [ "### Add xyzservices provider\n", "\n", "Add a layer from [xyzservices](https://github.com/geopandas/xyzservices) provider object." ] }, { "cell_type": "code", "execution_count": null, "id": "46", "metadata": {}, "outputs": [], "source": [ "import leafmap\n", "import xyzservices.providers as xyz" ] }, { "cell_type": "code", "execution_count": null, "id": "47", "metadata": {}, "outputs": [], "source": [ "basemap = xyz.OpenTopoMap\n", "basemap" ] }, { "cell_type": "code", "execution_count": null, "id": "48", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_basemap(basemap)\n", "m" ] }, { "cell_type": "markdown", "id": "49", "metadata": {}, "source": [ "## Add COG/STAC layers\n", "\n", "A Cloud Optimized GeoTIFF (COG) is a regular GeoTIFF file, aimed at being hosted on a HTTP file server, with an internal organization that enables more efficient workflows on the cloud. It does this by leveraging the ability of clients issuing HTTP GET range requests to ask for just the parts of a file they need. \n", "\n", "More information about COG can be found at <https://www.cogeo.org/in-depth.html>\n", "\n", "Some publicly available Cloud Optimized GeoTIFFs:\n", "\n", "* https://stacindex.org/\n", "* https://cloud.google.com/storage/docs/public-datasets/landsat\n", "* https://www.digitalglobe.com/ecosystem/open-data\n", "* https://earthexplorer.usgs.gov/\n", "\n", "For this demo, we will use data from https://www.maxar.com/open-data/california-colorado-fires for mapping California and Colorado fires. A list of COGs can be found [here](https://github.com/opengeos/leafmap/blob/master/examples/data/cog_files.txt).\n", "\n", "### Add COG layer" ] }, { "cell_type": "code", "execution_count": null, "id": "50", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "51", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "url = \"https://github.com/opengeos/data/releases/download/raster/Libya-2023-07-01.tif\"\n", "url2 = \"https://github.com/opengeos/data/releases/download/raster/Libya-2023-09-13.tif\"\n", "\n", "m.add_cog_layer(url, name=\"Fire (pre-event)\")\n", "m.add_cog_layer(url2, name=\"Fire (post-event)\")\n", "m" ] }, { "cell_type": "markdown", "id": "52", "metadata": {}, "source": [ "### Add STAC layer\n", "\n", "The SpatioTemporal Asset Catalog (STAC) specification provides a common language to describe a range of geospatial information, so it can more easily be indexed and discovered. A 'spatiotemporal asset' is any file that represents information about the earth captured in a certain space and time. The initial focus is primarily remotely-sensed imagery (from satellites, but also planes, drones, balloons, etc), but the core is designed to be extensible to SAR, full motion video, point clouds, hyperspectral, LiDAR and derived data like NDVI, Digital Elevation Models, mosaics, etc. More information about STAC can be found at https://stacspec.org/\n", "\n", "Some publicly available SpatioTemporal Asset Catalog (STAC):\n", "\n", "* https://stacindex.org\n", "\n", "For this demo, we will use STAC assets from https://stacindex.org/catalogs/spot-orthoimages-canada-2005#/?t=catalogs" ] }, { "cell_type": "code", "execution_count": null, "id": "53", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "url = \"https://canada-spot-ortho.s3.amazonaws.com/canada_spot_orthoimages/canada_spot5_orthoimages/S5_2007/S5_11055_6057_20070622/S5_11055_6057_20070622.json\"\n", "m.add_stac_layer(url, bands=[\"B3\", \"B2\", \"B1\"], name=\"False color\")\n", "m" ] }, { "cell_type": "markdown", "id": "54", "metadata": {}, "source": [ "## Add local raster datasets\n", "\n", "The `add_raster` function relies on the `xarray_leaflet` package and is only available for the ipyleaflet plotting backend. Therefore, Google Colab is not supported. Note that `xarray_leaflet` does not work properly on Windows ([source](https://github.com/davidbrochart/xarray_leaflet/issues/30))." ] }, { "cell_type": "code", "execution_count": null, "id": "55", "metadata": {}, "outputs": [], "source": [ "import os\n", "import leafmap" ] }, { "cell_type": "markdown", "id": "56", "metadata": {}, "source": [ "Download samples raster datasets\n", "\n", "More datasets can be downloaded from https://viewer.nationalmap.gov/basic/" ] }, { "cell_type": "code", "execution_count": null, "id": "57", "metadata": {}, "outputs": [], "source": [ "out_dir = os.getcwd()\n", "\n", "landsat = os.path.join(out_dir, \"landsat.tif\")\n", "dem = os.path.join(out_dir, \"dem.tif\")" ] }, { "cell_type": "markdown", "id": "58", "metadata": {}, "source": [ "Download a small Landsat imagery." ] }, { "cell_type": "code", "execution_count": null, "id": "59", "metadata": {}, "outputs": [], "source": [ "landsat_url = (\n", " \"https://drive.google.com/file/d/1EV38RjNxdwEozjc9m0FcO3LFgAoAX1Uw/view?usp=sharing\"\n", ")\n", "leafmap.download_file(landsat_url, \"landsat.tif\", unzip=False)" ] }, { "cell_type": "markdown", "id": "60", "metadata": {}, "source": [ "Download a small DEM dataset." ] }, { "cell_type": "code", "execution_count": null, "id": "61", "metadata": {}, "outputs": [], "source": [ "dem_url = (\n", " \"https://drive.google.com/file/d/1vRkAWQYsLWCi6vcTMk8vLxoXMFbdMFn8/view?usp=sharing\"\n", ")\n", "leafmap.download_file(dem_url, \"dem.tif\", unzip=False)" ] }, { "cell_type": "code", "execution_count": null, "id": "62", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()" ] }, { "cell_type": "markdown", "id": "63", "metadata": {}, "source": [ "Add local raster datasets to the map\n", "\n", "More colormap can be found at https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html" ] }, { "cell_type": "code", "execution_count": null, "id": "64", "metadata": {}, "outputs": [], "source": [ "m.add_raster(dem, colormap=\"terrain\", layer_name=\"DEM\")" ] }, { "cell_type": "code", "execution_count": null, "id": "65", "metadata": {}, "outputs": [], "source": [ "m.add_raster(landsat, bands=[5, 4, 3], layer_name=\"Landsat\")" ] }, { "cell_type": "code", "execution_count": null, "id": "66", "metadata": {}, "outputs": [], "source": [ "m" ] }, { "cell_type": "markdown", "id": "67", "metadata": {}, "source": [ "## Add legend\n", "\n", "### Add built-in legend" ] }, { "cell_type": "code", "execution_count": null, "id": "68", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "markdown", "id": "69", "metadata": {}, "source": [ "List all available built-in legends." ] }, { "cell_type": "code", "execution_count": null, "id": "70", "metadata": {}, "outputs": [], "source": [ "legends = leafmap.builtin_legends\n", "for legend in legends:\n", " print(legend)" ] }, { "cell_type": "markdown", "id": "71", "metadata": {}, "source": [ "Add a WMS layer and built-in legend to the map." ] }, { "cell_type": "code", "execution_count": null, "id": "72", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "url = \"https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2019_Land_Cover_L48/wms?\"\n", "m.add_wms_layer(\n", " url,\n", " layers=\"NLCD_2019_Land_Cover_L48\",\n", " name=\"NLCD 2019 CONUS Land Cover\",\n", " format=\"image/png\",\n", " transparent=True,\n", ")\n", "m.add_legend(builtin_legend=\"NLCD\")\n", "m" ] }, { "cell_type": "markdown", "id": "73", "metadata": {}, "source": [ "Add U.S. National Wetlands Inventory (NWI). More info at https://www.fws.gov/wetlands." ] }, { "cell_type": "code", "execution_count": null, "id": "74", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(google_map=\"HYBRID\")\n", "\n", "url1 = \"https://www.fws.gov/wetlands/arcgis/services/Wetlands/MapServer/WMSServer?\"\n", "m.add_wms_layer(\n", " url1, layers=\"1\", format=\"image/png\", transparent=True, name=\"NWI Wetlands Vector\"\n", ")\n", "\n", "url2 = \"https://www.fws.gov/wetlands/arcgis/services/Wetlands_Raster/ImageServer/WMSServer?\"\n", "m.add_wms_layer(\n", " url2, layers=\"0\", format=\"image/png\", transparent=True, name=\"NWI Wetlands Raster\"\n", ")\n", "\n", "m.add_legend(builtin_legend=\"NWI\")\n", "m" ] }, { "cell_type": "markdown", "id": "75", "metadata": {}, "source": [ "### Add custom legend\n", "\n", "There are two ways you can add custom legends:\n", "\n", "1. Define legend labels and colors\n", "2. Define legend dictionary\n", "\n", "Define legend keys and colors" ] }, { "cell_type": "code", "execution_count": null, "id": "76", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "\n", "labels = [\"One\", \"Two\", \"Three\", \"Four\", \"etc\"]\n", "# color can be defined using either hex code or RGB (0-255, 0-255, 0-255)\n", "colors = [\"#8DD3C7\", \"#FFFFB3\", \"#BEBADA\", \"#FB8072\", \"#80B1D3\"]\n", "# colors = [(255, 0, 0), (127, 255, 0), (127, 18, 25), (36, 70, 180), (96, 68, 123)]\n", "\n", "m.add_legend(title=\"Legend\", labels=labels, colors=colors)\n", "m" ] }, { "cell_type": "markdown", "id": "77", "metadata": {}, "source": [ "Define a legend dictionary." ] }, { "cell_type": "code", "execution_count": null, "id": "78", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "\n", "url = \"https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2019_Land_Cover_L48/wms?\"\n", "m.add_wms_layer(\n", " url,\n", " layers=\"NLCD_2019_Land_Cover_L48\",\n", " name=\"NLCD 2019 CONUS Land Cover\",\n", " format=\"image/png\",\n", " transparent=True,\n", ")\n", "\n", "legend_dict = {\n", " \"11 Open Water\": \"466b9f\",\n", " \"12 Perennial Ice/Snow\": \"d1def8\",\n", " \"21 Developed, Open Space\": \"dec5c5\",\n", " \"22 Developed, Low Intensity\": \"d99282\",\n", " \"23 Developed, Medium Intensity\": \"eb0000\",\n", " \"24 Developed High Intensity\": \"ab0000\",\n", " \"31 Barren Land (Rock/Sand/Clay)\": \"b3ac9f\",\n", " \"41 Deciduous Forest\": \"68ab5f\",\n", " \"42 Evergreen Forest\": \"1c5f2c\",\n", " \"43 Mixed Forest\": \"b5c58f\",\n", " \"51 Dwarf Scrub\": \"af963c\",\n", " \"52 Shrub/Scrub\": \"ccb879\",\n", " \"71 Grassland/Herbaceous\": \"dfdfc2\",\n", " \"72 Sedge/Herbaceous\": \"d1d182\",\n", " \"73 Lichens\": \"a3cc51\",\n", " \"74 Moss\": \"82ba9e\",\n", " \"81 Pasture/Hay\": \"dcd939\",\n", " \"82 Cultivated Crops\": \"ab6c28\",\n", " \"90 Woody Wetlands\": \"b8d9eb\",\n", " \"95 Emergent Herbaceous Wetlands\": \"6c9fb8\",\n", "}\n", "\n", "m.add_legend(title=\"NLCD Land Cover Classification\", legend_dict=legend_dict)\n", "m" ] }, { "cell_type": "markdown", "id": "79", "metadata": {}, "source": [ "## Add colormap\n", "\n", "The colormap functionality requires the ipyleaflet plotting backend. Folium is not supported." ] }, { "cell_type": "code", "execution_count": null, "id": "80", "metadata": {}, "outputs": [], "source": [ "import leafmap\n", "import leafmap.colormaps as cm" ] }, { "cell_type": "markdown", "id": "81", "metadata": {}, "source": [ "### Common colormaps\n", "\n", "Color palette for DEM data." ] }, { "cell_type": "code", "execution_count": null, "id": "82", "metadata": {}, "outputs": [], "source": [ "cm.palettes.dem" ] }, { "cell_type": "markdown", "id": "83", "metadata": {}, "source": [ "Show the DEM palette." ] }, { "cell_type": "code", "execution_count": null, "id": "84", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(colors=cm.palettes.dem, axis_off=True)" ] }, { "cell_type": "markdown", "id": "85", "metadata": {}, "source": [ "Color palette for NDVI data." ] }, { "cell_type": "code", "execution_count": null, "id": "86", "metadata": {}, "outputs": [], "source": [ "cm.palettes.ndvi" ] }, { "cell_type": "markdown", "id": "87", "metadata": {}, "source": [ "Show the NDVI palette." ] }, { "cell_type": "code", "execution_count": null, "id": "88", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(colors=cm.palettes.ndvi)" ] }, { "cell_type": "markdown", "id": "89", "metadata": {}, "source": [ "### Custom colormaps\n", "\n", "Specify the number of classes for a palette." ] }, { "cell_type": "code", "execution_count": null, "id": "90", "metadata": {}, "outputs": [], "source": [ "cm.get_palette(\"terrain\", n_class=8)" ] }, { "cell_type": "markdown", "id": "91", "metadata": {}, "source": [ "Show the terrain palette with 8 classes." ] }, { "cell_type": "code", "execution_count": null, "id": "92", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(colors=cm.get_palette(\"terrain\", n_class=8))" ] }, { "cell_type": "markdown", "id": "93", "metadata": {}, "source": [ "Create a palette with custom colors, label, and font size." ] }, { "cell_type": "code", "execution_count": null, "id": "94", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(colors=[\"red\", \"green\", \"blue\"], label=\"Temperature\", font_size=12)" ] }, { "cell_type": "markdown", "id": "95", "metadata": {}, "source": [ "Create a discrete color palette." ] }, { "cell_type": "code", "execution_count": null, "id": "96", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(\n", " colors=[\"red\", \"green\", \"blue\"], discrete=True, label=\"Temperature\", font_size=12\n", ")" ] }, { "cell_type": "markdown", "id": "97", "metadata": {}, "source": [ "Specify the width and height for the palette." ] }, { "cell_type": "code", "execution_count": null, "id": "98", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(\n", " \"terrain\",\n", " label=\"Elevation\",\n", " width=8.0,\n", " height=0.4,\n", " orientation=\"horizontal\",\n", " vmin=0,\n", " vmax=1000,\n", ")" ] }, { "cell_type": "markdown", "id": "99", "metadata": {}, "source": [ "Change the orentation of the colormap to be vertical." ] }, { "cell_type": "code", "execution_count": null, "id": "100", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormap(\n", " \"terrain\",\n", " label=\"Elevation\",\n", " width=0.4,\n", " height=4,\n", " orientation=\"vertical\",\n", " vmin=0,\n", " vmax=1000,\n", ")" ] }, { "cell_type": "markdown", "id": "101", "metadata": {}, "source": [ "### Horizontal colormap\n", "\n", "Add a horizontal colorbar to an interactive map." ] }, { "cell_type": "code", "execution_count": null, "id": "102", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_basemap(\"OpenTopoMap\")\n", "m.add_colormap(\n", " \"terrain\",\n", " label=\"Elevation\",\n", " width=8.0,\n", " height=0.4,\n", " orientation=\"horizontal\",\n", " vmin=0,\n", " vmax=4000,\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "103", "metadata": {}, "source": [ "### Vertical colormap\n", "\n", "Add a vertical colorbar to an interactive map." ] }, { "cell_type": "code", "execution_count": null, "id": "104", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_basemap(\"OpenTopoMap\")\n", "m.add_colormap(\n", " \"terrain\",\n", " label=\"Elevation\",\n", " width=0.4,\n", " height=4,\n", " orientation=\"vertical\",\n", " vmin=0,\n", " vmax=4000,\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "105", "metadata": {}, "source": [ "### List of available colormaps" ] }, { "cell_type": "code", "execution_count": null, "id": "106", "metadata": {}, "outputs": [], "source": [ "cm.plot_colormaps(width=12, height=0.4)" ] }, { "cell_type": "markdown", "id": "107", "metadata": {}, "source": [ "## Add vector datasets\n", "\n", "### Add CSV\n", "\n", "Read a CSV as a Pandas DataFrame." ] }, { "cell_type": "code", "execution_count": null, "id": "108", "metadata": {}, "outputs": [], "source": [ "import os\n", "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "109", "metadata": {}, "outputs": [], "source": [ "in_csv = \"https://raw.githubusercontent.com/opengeos/data/main/world/world_cities.csv\"\n", "df = leafmap.csv_to_df(in_csv)\n", "df" ] }, { "cell_type": "markdown", "id": "110", "metadata": {}, "source": [ "Create a point layer from a CSV file containing lat/long information." ] }, { "cell_type": "code", "execution_count": null, "id": "111", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_xy_data(in_csv, x=\"longitude\", y=\"latitude\", layer_name=\"World Cities\")\n", "m" ] }, { "cell_type": "markdown", "id": "112", "metadata": {}, "source": [ "Set the output directory." ] }, { "cell_type": "code", "execution_count": null, "id": "113", "metadata": {}, "outputs": [], "source": [ "out_dir = os.getcwd()\n", "out_shp = os.path.join(out_dir, \"world_cities.shp\")" ] }, { "cell_type": "markdown", "id": "114", "metadata": {}, "source": [ "Convert a CSV file containing lat/long information to a shapefile." ] }, { "cell_type": "code", "execution_count": null, "id": "115", "metadata": {}, "outputs": [], "source": [ "leafmap.csv_to_shp(in_csv, out_shp)" ] }, { "cell_type": "markdown", "id": "116", "metadata": {}, "source": [ "Convert a CSV file containing lat/long information to a GeoJSON." ] }, { "cell_type": "code", "execution_count": null, "id": "117", "metadata": {}, "outputs": [], "source": [ "out_geojson = os.path.join(out_dir, \"world_cities.geojson\")\n", "leafmap.csv_to_geojson(in_csv, out_geojson)" ] }, { "cell_type": "markdown", "id": "118", "metadata": {}, "source": [ "Convert a CSV file containing lat/long information to a GeoPandas GeoDataFrame." ] }, { "cell_type": "code", "execution_count": null, "id": "119", "metadata": {}, "outputs": [], "source": [ "gdf = leafmap.csv_to_gdf(in_csv)\n", "gdf" ] }, { "cell_type": "markdown", "id": "120", "metadata": {}, "source": [ "### Add GeoJSON\n", "\n", "Add a GeoJSON to the map." ] }, { "cell_type": "code", "execution_count": null, "id": "121", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=[0, 0], zoom=2)\n", "in_geojson = \"https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/cable_geo.geojson\"\n", "m.add_geojson(in_geojson, layer_name=\"Cable lines\", info_mode=\"on_hover\")\n", "m" ] }, { "cell_type": "markdown", "id": "122", "metadata": {}, "source": [ "Add a GeoJSON with random filled color to the map." ] }, { "cell_type": "code", "execution_count": null, "id": "123", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=[0, 0], zoom=2)\n", "url = \"https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/countries.geojson\"\n", "m.add_geojson(\n", " url, layer_name=\"Countries\", fill_colors=[\"red\", \"yellow\", \"green\", \"orange\"]\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "124", "metadata": {}, "source": [ "### Add shapefile" ] }, { "cell_type": "code", "execution_count": null, "id": "125", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=[0, 0], zoom=2)\n", "in_shp = \"https://github.com/opengeos/leafmap/raw/master/examples/data/countries.zip\"\n", "m.add_shp(in_shp, layer_name=\"Countries\")\n", "m" ] }, { "cell_type": "markdown", "id": "126", "metadata": {}, "source": [ "### Add KML" ] }, { "cell_type": "code", "execution_count": null, "id": "127", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "128", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "in_kml = \"https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/us_states.kml\"\n", "m.add_kml(in_kml, layer_name=\"US States KML\")\n", "m" ] }, { "cell_type": "markdown", "id": "129", "metadata": {}, "source": [ "### Add GeoDataFrame" ] }, { "cell_type": "code", "execution_count": null, "id": "130", "metadata": {}, "outputs": [], "source": [ "import geopandas as gpd" ] }, { "cell_type": "code", "execution_count": null, "id": "131", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "gdf = gpd.read_file(\n", " \"https://github.com/opengeos/leafmap/raw/master/examples/data/cable_geo.geojson\"\n", ")\n", "m.add_gdf(gdf, layer_name=\"Cable lines\")\n", "m" ] }, { "cell_type": "markdown", "id": "132", "metadata": {}, "source": [ "### Add point layer\n", "\n", "Add a point layer using the interactive GUI.\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "id": "133", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m" ] }, { "cell_type": "markdown", "id": "134", "metadata": {}, "source": [ "Add a point layer programmatically." ] }, { "cell_type": "code", "execution_count": null, "id": "135", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "url = \"https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/us_cities.geojson\"\n", "m.add_point_layer(url, popup=[\"name\", \"pop_max\"], layer_name=\"US Cities\")\n", "m" ] }, { "cell_type": "markdown", "id": "136", "metadata": {}, "source": [ "### Add vector\n", "\n", "The `add_vector` function supports any vector data format supported by GeoPandas." ] }, { "cell_type": "code", "execution_count": null, "id": "137", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=[0, 0], zoom=2)\n", "url = \"https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/countries.geojson\"\n", "m.add_vector(\n", " url, layer_name=\"Countries\", fill_colors=[\"red\", \"yellow\", \"green\", \"orange\"]\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "138", "metadata": {}, "source": [ "## Download OSM data\n", "\n", "### OSM from geocode\n", "\n", "Add OSM data of place(s) by name or ID to the map. Note that the leafmap custom layer control does not support GeoJSON, we need to use the ipyleaflet built-in layer control." ] }, { "cell_type": "code", "execution_count": null, "id": "139", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "140", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(toolbar_control=False, layers_control=True)\n", "m.add_osm_from_geocode(\"New York City\", layer_name=\"NYC\")\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "141", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(toolbar_control=False, layers_control=True)\n", "m.add_osm_from_geocode(\"Chicago, Illinois\", layer_name=\"Chicago, IL\")\n", "m" ] }, { "cell_type": "markdown", "id": "142", "metadata": {}, "source": [ "### OSM from place\n", "\n", "Add OSM entities within boundaries of geocodable place(s) to the map." ] }, { "cell_type": "markdown", "id": "143", "metadata": {}, "source": [ "Show OSM feature tags.\n", "https://wiki.openstreetmap.org/wiki/Map_features" ] }, { "cell_type": "code", "execution_count": null, "id": "144", "metadata": {}, "outputs": [], "source": [ "# leafmap.osm_tags_list()" ] }, { "cell_type": "markdown", "id": "145", "metadata": {}, "source": [ "### OSM from address" ] }, { "cell_type": "code", "execution_count": null, "id": "146", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(toolbar_control=False, layers_control=True)\n", "m.add_osm_from_address(\n", " address=\"New York City\", tags={\"amenity\": \"bar\"}, dist=1500, layer_name=\"NYC bars\"\n", ")\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "147", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(toolbar_control=False, layers_control=True)\n", "m.add_osm_from_address(\n", " address=\"New York City\",\n", " tags={\"landuse\": [\"retail\", \"commercial\"], \"building\": True},\n", " dist=1000,\n", " layer_name=\"NYC buildings\",\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "148", "metadata": {}, "source": [ "### OSM from bbox" ] }, { "cell_type": "code", "execution_count": null, "id": "149", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(toolbar_control=False, layers_control=True)\n", "north, south, east, west = 40.7551, 40.7454, -73.9738, -73.9965\n", "m.add_osm_from_bbox(\n", " north, south, east, west, tags={\"amenity\": \"bar\"}, layer_name=\"NYC bars\"\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "150", "metadata": {}, "source": [ "### OSM from point\n", "\n", "Add OSM entities within some distance N, S, E, W of a point to the map." ] }, { "cell_type": "code", "execution_count": null, "id": "151", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(\n", " center=[46.7808, -96.0156], zoom=12, toolbar_control=False, layers_control=True\n", ")\n", "m.add_osm_from_point(\n", " center_point=(46.7808, -96.0156),\n", " tags={\"natural\": \"water\"},\n", " dist=10000,\n", " layer_name=\"Lakes\",\n", ")\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "152", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(\n", " center=[39.9170, 116.3908], zoom=15, toolbar_control=False, layers_control=True\n", ")\n", "m.add_osm_from_point(\n", " center_point=(39.9170, 116.3908),\n", " tags={\"building\": True, \"natural\": \"water\"},\n", " dist=1000,\n", " layer_name=\"Beijing\",\n", ")\n", "m" ] }, { "cell_type": "markdown", "id": "153", "metadata": {}, "source": [ "### OSM from view\n", "\n", "Add OSM entities within the current map view to the map." ] }, { "cell_type": "code", "execution_count": null, "id": "154", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(toolbar_control=False, layers_control=True)\n", "m.set_center(-73.9854, 40.7500, 16)\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "155", "metadata": {}, "outputs": [], "source": [ "m.add_osm_from_view(tags={\"amenity\": \"bar\", \"building\": True}, layer_name=\"New York\")" ] }, { "cell_type": "markdown", "id": "156", "metadata": {}, "source": [ "Create a GeoPandas GeoDataFrame from place." ] }, { "cell_type": "code", "execution_count": null, "id": "157", "metadata": {}, "outputs": [], "source": [ "gdf = leafmap.osm_gdf_from_place(\"New York City\", tags={\"amenity\": \"bar\"})\n", "gdf" ] }, { "cell_type": "markdown", "id": "158", "metadata": {}, "source": [ "## Use WhiteboxTools\n", "\n", "Use the built-in toolbox to perform geospatial analysis. For example, you can perform depression filling using the sample DEM dataset downloaded in the above step.\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "id": "159", "metadata": {}, "outputs": [], "source": [ "import os\n", "import leafmap\n", "import urllib.request" ] }, { "cell_type": "markdown", "id": "160", "metadata": {}, "source": [ "Download a sample DEM dataset." ] }, { "cell_type": "code", "execution_count": null, "id": "161", "metadata": {}, "outputs": [], "source": [ "url = \"https://github.com/opengeos/whitebox-python/raw/master/whitebox/testdata/DEM.tif\"" ] }, { "cell_type": "code", "execution_count": null, "id": "162", "metadata": {}, "outputs": [], "source": [ "urllib.request.urlretrieve(url, \"dem.tif\")" ] }, { "cell_type": "code", "execution_count": null, "id": "163", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m" ] }, { "cell_type": "markdown", "id": "164", "metadata": {}, "source": [ "Display the toolbox using the default mode." ] }, { "cell_type": "code", "execution_count": null, "id": "165", "metadata": {}, "outputs": [], "source": [ "leafmap.whiteboxgui()" ] }, { "cell_type": "markdown", "id": "166", "metadata": {}, "source": [ "Display the toolbox using the collapsible tree mode. Note that the tree mode does not support Google Colab." ] }, { "cell_type": "code", "execution_count": null, "id": "167", "metadata": {}, "outputs": [], "source": [ "leafmap.whiteboxgui(tree=True)" ] }, { "cell_type": "markdown", "id": "168", "metadata": {}, "source": [ "Perform geospatial analysis using the [whitebox](https://github.com/opengeos/whitebox-python) package." ] }, { "cell_type": "code", "execution_count": null, "id": "169", "metadata": {}, "outputs": [], "source": [ "import os\n", "import whitebox" ] }, { "cell_type": "code", "execution_count": null, "id": "170", "metadata": {}, "outputs": [], "source": [ "wbt = whitebox.WhiteboxTools()\n", "wbt.verbose = False" ] }, { "cell_type": "code", "execution_count": null, "id": "171", "metadata": {}, "outputs": [], "source": [ "data_dir = os.getcwd()\n", "wbt.set_working_dir(data_dir)" ] }, { "cell_type": "code", "execution_count": null, "id": "172", "metadata": {}, "outputs": [], "source": [ "wbt.feature_preserving_smoothing(\"dem.tif\", \"smoothed.tif\", filter=9)\n", "wbt.breach_depressions(\"smoothed.tif\", \"breached.tif\")\n", "wbt.d_inf_flow_accumulation(\"breached.tif\", \"flow_accum.tif\")" ] }, { "cell_type": "code", "execution_count": null, "id": "173", "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import imageio\n", "\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": null, "id": "174", "metadata": {}, "outputs": [], "source": [ "original = imageio.imread(os.path.join(data_dir, \"dem.tif\"))\n", "smoothed = imageio.imread(os.path.join(data_dir, \"smoothed.tif\"))\n", "breached = imageio.imread(os.path.join(data_dir, \"breached.tif\"))\n", "flow_accum = imageio.imread(os.path.join(data_dir, \"flow_accum.tif\"))" ] }, { "cell_type": "code", "execution_count": null, "id": "175", "metadata": {}, "outputs": [], "source": [ "fig = plt.figure(figsize=(16, 11))\n", "\n", "ax1 = fig.add_subplot(2, 2, 1)\n", "ax1.set_title(\"Original DEM\")\n", "plt.imshow(original)\n", "\n", "ax2 = fig.add_subplot(2, 2, 2)\n", "ax2.set_title(\"Smoothed DEM\")\n", "plt.imshow(smoothed)\n", "\n", "ax3 = fig.add_subplot(2, 2, 3)\n", "ax3.set_title(\"Breached DEM\")\n", "plt.imshow(breached)\n", "\n", "ax4 = fig.add_subplot(2, 2, 4)\n", "ax4.set_title(\"Flow Accumulation\")\n", "plt.imshow(flow_accum)\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "176", "metadata": {}, "source": [ "## Create linked map" ] }, { "cell_type": "code", "execution_count": null, "id": "177", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "178", "metadata": {}, "outputs": [], "source": [ "leafmap.basemaps.keys()" ] }, { "cell_type": "code", "execution_count": null, "id": "179", "metadata": {}, "outputs": [], "source": [ "layers = [\"ROADMAP\", \"HYBRID\"]\n", "leafmap.linked_maps(rows=1, cols=2, height=\"400px\", layers=layers)" ] }, { "cell_type": "code", "execution_count": null, "id": "180", "metadata": {}, "outputs": [], "source": [ "layers = [\"Esri.WorldTopoMap\", \"OpenTopoMap\"]\n", "leafmap.linked_maps(rows=1, cols=2, height=\"400px\", layers=layers)" ] }, { "cell_type": "markdown", "id": "181", "metadata": {}, "source": [ "Create a 2 * 2 linked map to visualize land cover change. Specify the `center` and `zoom` parameters to change the default map center and zoom level." ] }, { "cell_type": "code", "execution_count": null, "id": "182", "metadata": {}, "outputs": [], "source": [ "layers = [str(f\"NLCD {year} CONUS Land Cover\") for year in [2001, 2006, 2011, 2016]]\n", "labels = [str(f\"NLCD {year}\") for year in [2001, 2006, 2011, 2016]]\n", "leafmap.linked_maps(\n", " rows=2,\n", " cols=2,\n", " height=\"300px\",\n", " layers=layers,\n", " labels=labels,\n", " center=[36.1, -115.2],\n", " zoom=9,\n", ")" ] }, { "cell_type": "markdown", "id": "183", "metadata": {}, "source": [ "## Create split-panel map\n", "\n", "Create a split-panel map by specifying the `left_layer` and `right_layer`, which can be chosen from the basemap names, or any custom XYZ tile layer." ] }, { "cell_type": "code", "execution_count": null, "id": "184", "metadata": {}, "outputs": [], "source": [ "import leafmap" ] }, { "cell_type": "code", "execution_count": null, "id": "185", "metadata": {}, "outputs": [], "source": [ "leafmap.split_map(left_layer=\"ROADMAP\", right_layer=\"HYBRID\")" ] }, { "cell_type": "markdown", "id": "186", "metadata": {}, "source": [ "Hide the zoom control from the map." ] }, { "cell_type": "code", "execution_count": null, "id": "187", "metadata": {}, "outputs": [], "source": [ "leafmap.split_map(\n", " left_layer=\"Esri.WorldTopoMap\", right_layer=\"OpenTopoMap\", zoom_control=False\n", ")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }