{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"contentcontainer med left\" style=\"margin-left: -50px;\">\n",
    "<dl class=\"dl-horizontal\">\n",
    "  <dt>Title</dt> <dd> Tiles Element</dd>\n",
    "  <dt>Dependencies</dt> <dd>Plotly</dd>\n",
    "  <dt>Backends</dt>\n",
    "    <dd><a href='../bokeh/Tiles.ipynb'>Bokeh</a></dd>\n",
    "    <dd><a href='Tiles.ipynb'>Plotly</a></dd>\n",
    "</dl>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import holoviews as hv\n",
    "from holoviews import opts\n",
    "hv.extension('plotly')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``Tiles`` element represents a so called web mapping tile source usually used for geographic plots, which fetches tiles appropriate to the current zoom level. To declare a ``Tiles`` element simply provide a URL to the tile server. A standard tile server URL has a number of templated variables that describe the location and zoom level. In the most common case of a WMTS tile source, the URL looks like this:\n",
    "\n",
    "    'https://c.tile.openstreetmap.org/{Z}/{X}/{Y}.png'\n",
    "\n",
    "Here ``{X}``, ``{Y}`` and ``{Z}`` describe the location and zoom level of each tile.\n",
    "A simple example of a WMTS tile source is the OSM maps:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hv.Tiles('https://c.tile.openstreetmap.org/{Z}/{X}/{Y}.png', name=\"OSM\").opts(width=600, height=550)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One thing to note about tile sources is that they are always defined in the [pseudo-Mercator projection](https://epsg.io/3857), which means that if you want to overlay any data on top of a tile source the values have to be expressed as eastings and northings. If you have data in another projection, e.g. latitudes and longitudes, it may make sense to use [GeoViews](https://geoviews.org/) for it to handle the projections for you.\n",
    "\n",
    ">\n",
    "> **Note**: \n",
    "> \n",
    ">   Holoviews provides functions to project longitude, latitude into Web Mercator coordinates. \n",
    ">   See [`hv.util.transform.lon_lat_to_easting_northing(longitude, latitude)`](https://holoviews.org/reference_manual/holoviews.element.html?highlight=lon_lat_to_easting_northing#holoviews.element.Tiles.lon_lat_to_easting_northing)\n",
    ">\n",
    "\n",
    "Both HoloViews and GeoViews provides a number of tile sources by default, provided by CartoDB, OpenStreetMap, and Esri. Stamen tile sources are also available but require a Stadia account when not running locally; see [stadiamaps.com](https://stadiamaps.com/).\n",
    "\n",
    "Tile sources can be imported from the ``holoviews.element.tiles`` module and are provided as callable functions which return a ``Tiles`` element:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hv.element.tiles.EsriImagery().opts(width=600, height=550)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The full set of predefined tile sources can be accessed on the ``holoviews.element.tiles.tile_sources`` and ``holoviews.element.tiles.stamen_sources`` dictionaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hv.Layout([ts().relabel(name) for name, ts in hv.element.tiles.tile_sources.items()]).opts(\n",
    "    opts.Tiles(xaxis=None, yaxis=None, width=225, height=225),\n",
    "    opts.Layout(hspacing=10, vspacing=40)\n",
    ").cols(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For full documentation and the available style and plot options, use ``hv.help(hv.Tiles).``"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Vector Mapbox Tiles\n",
    "\n",
    "In addition to displaying raster tiles loaded from a tile source URL, the Plotly backend can also display vector tiles provided by Mapbox. A vector tile style is specified using the `mapboxstyle` option, and requires a Mapbox\n",
    "access token to be provided as the `accesstoken` option.\n",
    "\n",
    "```python\n",
    "hv.Tiles('').opts(\n",
    "    mapboxstyle=\"dark\",\n",
    "    accesstoken=\"pk...\",\n",
    "    width=600,\n",
    "    height=600\n",
    ")\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
