{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# A full look into `providers` objects"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "import xyzservices.providers as xyz"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## What is this \"provider\" object ?"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "The provider objects are stored as dictionaries (with attribute access for easy access), so we can explore them in Python (or using tab completion in an interactive session or as a collapsible inventory in Jupyter!):"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "xyz"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "Most of those providers have themselves multiple options. For example, OpenStreetMap provides multiple background styles:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "xyz.OpenStreetMap"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "Looking at a single one of those options, for example \"Mapnik\" (the default OpenStreetMap background), we can see this is a `TileProvider` object, which behaves as a dict:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "type(xyz.OpenStreetMap.Mapnik)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "We can explore its contents:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "xyz.OpenStreetMap.Mapnik"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "A \"provider object\" is then a dictionary with a few required entries, such as the url (required, with `{z}/{x}/{y}` to be replaced), with some additional metadata information (optional). These can be the attribution text to be used on the plot (`attribution`), or the maximum zoom level available for these tiles (`max_zoom`). When this information is available, other libraries like `geopandas` or `contextily` may be smart enough to access and use it automatically."
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Which providers are available by default?"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "The providers definitions that are shipped with `xyzservices` in the `xyzservices.providers` submodule, are coming from the [`leaflet-providers`](https://github.com/leaflet-extras/leaflet-providers) package, an extension to javascript mapping library Leaflet that contains configurations for various free tile providers. Thus, all providers that are listed on their preview [http://leaflet-extras.github.io/leaflet-providers/preview/](http://leaflet-extras.github.io/leaflet-providers/preview/) should also be available in `xyzservices`. On top of that, `xyzservices` can have a few more as a bonus.\n",
    "\n",
    "```{important}\n",
    "You should always check the license and terms and conditions of XYZ tiles you want to use. Not all of them can be used in all circumstances.\n",
    "```"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Specifying options for a provider"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "Some providers require additional information, such as an API access key. This can be specified by calling the provider object. Any keyword specified will override the default value in the provider object.\n",
    "\n",
    "For example, the OpenWeatherMap requires an API key:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "xyz.OpenWeatherMap.Clouds"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "xyz.OpenWeatherMap.Clouds.requires_token()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "We can specify this API key by calling the object or overriding the attribute:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# Overriding the attribute will alter existing object\n",
    "xyz.OpenWeatherMap.Clouds[\"apiKey\"] = \"my-private-api-key\"\n",
    "\n",
    "# Calling the object will return a copy\n",
    "xyz.OpenWeatherMap.Clouds(apiKey=\"my-private-api-key\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "This can then be specified where a key or token is expected. For example:\n",
    "    \n",
    "```python\n",
    "contextily.add_basemap(ax, source=xyz.OpenWeatherMap.Clouds(apiKey=\"my-private-api-key\"))\n",
    "```\n",
    "\n",
    "```{note}\n",
    "It may occasionally happen that the `TileProvider` is broken. In such a case, it will have additional attribute `status` with a `\"broken\"` flag. If you think that the `TileProvider` is broken but it is not flagged as such, please [report it](https://github.com/geopandas/xyzservices/issues).\n",
    "```\n"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Building the tile URL\n",
    "\n",
    "Some packages like `contextily` can use `xyzservices.TileProvider` directly and parse the required information under the hood. Others need and explicit URL string, attribution and other attributes. However, not every package need the URL in the same format. `xyzsevices` can build the URL in most of the required formats, with or without placeholders.\n",
    "\n",
    "Typical use case would be a folium map, which needs a URL and an attribution with `{x}`, `{y}` and `{z}` placeholders but already filled API keys if needed. You can get the most standard URL in the  `'https://myserver.com/tiles/{z}/{x}/{y}.png'` format via `TileProvider.build_url()`. And if you want a sharper resolution (when supported by the provider), you can pass an optional `scale_factor` attribute."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "import folium\n",
    "\n",
    "tiles = xyz.CartoDB.Positron\n",
    "\n",
    "folium.Map(\n",
    "    location=[53.4108, -2.9358],\n",
    "    tiles=tiles.build_url(scale_factor=\"@2x\"),\n",
    "    attr=tiles.html_attribution,\n",
    ")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "If you need an URL of a single tile, you can pass `x`, `y` and `z` directly, alongside other required attributes like `accessToken`."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "xyz.OpenWeatherMap.Clouds.build_url(x=12, y=21, z=15, apiKey=\"my-private-api-key\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Overview of built-in providers"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "Let us create a flat dictionary of the built-in providers:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "providers = xyz.flatten()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "This results in quite a few of them already available:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "len(providers)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "For this illustration, let's single out the following ones and use `folium` to have a look at them:"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "selection = ['OpenStreetMap.Mapnik', \n",
    "             'OpenTopoMap', \n",
    "             'Stamen.Toner', \n",
    "             'Stamen.TonerLite', \n",
    "             'Stamen.Terrain', \n",
    "             'Stamen.TerrainBackground', \n",
    "             'Stamen.Watercolor', \n",
    "             'NASAGIBS.ViirsEarthAtNight2012', \n",
    "             'CartoDB.Positron', \n",
    "             'CartoDB.Voyager'\n",
    "            ]"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "You first create a `Map` instance, then looping through the `selection` add all selected base maps as layers. You can switch between them using the layer control in the top-right corner."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "source": [
    "m = folium.Map(location=[53.4108, -2.9358], zoom_start=8)\n",
    "\n",
    "for tiles_name in selection:\n",
    "    tiles = providers[tiles_name]\n",
    "    folium.TileLayer(\n",
    "        tiles=tiles.build_url(),\n",
    "        attr=tiles.html_attribution,\n",
    "        name=tiles.name,\n",
    "    ).add_to(m)\n",
    "\n",
    "folium.LayerControl().add_to(m)\n",
    "\n",
    "m"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "<folium.folium.Map at 0x1656a5940>"
      ],
      "text/html": [
       "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=%3C%21DOCTYPE%20html%3E%0A%3Chead%3E%20%20%20%20%0A%20%20%20%20%3Cmeta%20http-equiv%3D%22content-type%22%20content%3D%22text/html%3B%20charset%3DUTF-8%22%20/%3E%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20L_NO_TOUCH%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20L_DISABLE_3D%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20%3C/script%3E%0A%20%20%20%20%0A%20%20%20%20%3Cstyle%3Ehtml%2C%20body%20%7Bwidth%3A%20100%25%3Bheight%3A%20100%25%3Bmargin%3A%200%3Bpadding%3A%200%3B%7D%3C/style%3E%0A%20%20%20%20%3Cstyle%3E%23map%20%7Bposition%3Aabsolute%3Btop%3A0%3Bbottom%3A0%3Bright%3A0%3Bleft%3A0%3B%7D%3C/style%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//cdn.jsdelivr.net/npm/leaflet%401.6.0/dist/leaflet.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//code.jquery.com/jquery-1.12.4.min.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js%22%3E%3C/script%3E%0A%20%20%20%20%3Cscript%20src%3D%22https%3A//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.js%22%3E%3C/script%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//cdn.jsdelivr.net/npm/leaflet%401.6.0/dist/leaflet.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css%22/%3E%0A%20%20%20%20%3Clink%20rel%3D%22stylesheet%22%20href%3D%22https%3A//cdn.jsdelivr.net/gh/python-visualization/folium/folium/templates/leaflet.awesome.rotate.min.css%22/%3E%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cmeta%20name%3D%22viewport%22%20content%3D%22width%3Ddevice-width%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial-scale%3D1.0%2C%20maximum-scale%3D1.0%2C%20user-scalable%3Dno%22%20/%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23map_751b35603c85463a92e72556ee1db07d%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20relative%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20100.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3A%20100.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20left%3A%200.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20top%3A%200.0%25%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C/style%3E%0A%20%20%20%20%20%20%20%20%0A%3C/head%3E%0A%3Cbody%3E%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22folium-map%22%20id%3D%22map_751b35603c85463a92e72556ee1db07d%22%20%3E%3C/div%3E%0A%20%20%20%20%20%20%20%20%0A%3C/body%3E%0A%3Cscript%3E%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20map_751b35603c85463a92e72556ee1db07d%20%3D%20L.map%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22map_751b35603c85463a92e72556ee1db07d%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20center%3A%20%5B53.4108%2C%20-2.9358%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20crs%3A%20L.CRS.EPSG3857%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zoom%3A%208%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20zoomControl%3A%20true%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20preferCanvas%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_3be742203a3443bf9924479193c24b2f%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//%7Bs%7D.tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Data%20by%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22http%3A//openstreetmap.org%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%2C%20under%20%5Cu003ca%20href%3D%5C%22http%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eODbL%5Cu003c/a%5Cu003e.%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_fa9e8262497f44f6ac89a9a5ad52ffd5%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//a.tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_90e71b091ef24f63aedafe3e000786f7%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//a.tile.opentopomap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Map%20data%3A%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%2C%20%5Cu003ca%20href%3D%5C%22http%3A//viewfinderpanoramas.org%5C%22%5Cu003eSRTM%5Cu003c/a%5Cu003e%20%7C%20Map%20style%3A%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//opentopomap.org%5C%22%5Cu003eOpenTopoMap%5Cu003c/a%5Cu003e%20%28%5Cu003ca%20href%3D%5C%22https%3A//creativecommons.org/licenses/by-sa/3.0/%5C%22%5Cu003eCC-BY-SA%5Cu003c/a%5Cu003e%29%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_8e41c637372a4de19e9d5487d7b7c590%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//stamen-tiles-a.a.ssl.fastly.net/toner/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Map%20tiles%20by%20%5Cu003ca%20href%3D%5C%22http%3A//stamen.com%5C%22%5Cu003eStamen%20Design%5Cu003c/a%5Cu003e%2C%20%5Cu003ca%20href%3D%5C%22http%3A//creativecommons.org/licenses/by/3.0%5C%22%5Cu003eCC%20BY%203.0%5Cu003c/a%5Cu003e%20%5Cu0026mdash%3B%20Map%20data%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_dbc7470ffc044e6d9588247c0bc7b5e3%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//stamen-tiles-a.a.ssl.fastly.net/toner-lite/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Map%20tiles%20by%20%5Cu003ca%20href%3D%5C%22http%3A//stamen.com%5C%22%5Cu003eStamen%20Design%5Cu003c/a%5Cu003e%2C%20%5Cu003ca%20href%3D%5C%22http%3A//creativecommons.org/licenses/by/3.0%5C%22%5Cu003eCC%20BY%203.0%5Cu003c/a%5Cu003e%20%5Cu0026mdash%3B%20Map%20data%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_54d4d85f93f84a59b3eff7f03d451dcf%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//stamen-tiles-a.a.ssl.fastly.net/terrain/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Map%20tiles%20by%20%5Cu003ca%20href%3D%5C%22http%3A//stamen.com%5C%22%5Cu003eStamen%20Design%5Cu003c/a%5Cu003e%2C%20%5Cu003ca%20href%3D%5C%22http%3A//creativecommons.org/licenses/by/3.0%5C%22%5Cu003eCC%20BY%203.0%5Cu003c/a%5Cu003e%20%5Cu0026mdash%3B%20Map%20data%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_a80231bec90948828080e284d2473c76%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//stamen-tiles-a.a.ssl.fastly.net/terrain-background/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Map%20tiles%20by%20%5Cu003ca%20href%3D%5C%22http%3A//stamen.com%5C%22%5Cu003eStamen%20Design%5Cu003c/a%5Cu003e%2C%20%5Cu003ca%20href%3D%5C%22http%3A//creativecommons.org/licenses/by/3.0%5C%22%5Cu003eCC%20BY%203.0%5Cu003c/a%5Cu003e%20%5Cu0026mdash%3B%20Map%20data%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_5d1e6a712ebc44acadb9d33a7ed52d7c%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//stamen-tiles-a.a.ssl.fastly.net/watercolor/%7Bz%7D/%7Bx%7D/%7By%7D.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Map%20tiles%20by%20%5Cu003ca%20href%3D%5C%22http%3A//stamen.com%5C%22%5Cu003eStamen%20Design%5Cu003c/a%5Cu003e%2C%20%5Cu003ca%20href%3D%5C%22http%3A//creativecommons.org/licenses/by/3.0%5C%22%5Cu003eCC%20BY%203.0%5Cu003c/a%5Cu003e%20%5Cu0026mdash%3B%20Map%20data%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_d84b3264b4244dbaaa2302dd3e2e805e%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//map1.vis.earthdata.nasa.gov/wmts-webmerc/VIIRS_CityLights_2012/default//GoogleMapsCompatible_Level8/%7Bz%7D/%7By%7D/%7Bx%7D.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22Imagery%20provided%20by%20services%20from%20the%20Global%20Imagery%20Browse%20Services%20%28GIBS%29%2C%20operated%20by%20the%20NASA/GSFC/Earth%20Science%20Data%20and%20Information%20System%20%28%5Cu003ca%20href%3D%5C%22https%3A//earthdata.nasa.gov%5C%22%5Cu003eESDIS%5Cu003c/a%5Cu003e%29%20with%20funding%20provided%20by%20NASA/HQ.%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_6d8d6e0499bd4d40bf3edfbdd1de4a47%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//a.basemaps.cartocdn.com/light_all/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//carto.com/attributions%5C%22%5Cu003eCARTO%5Cu003c/a%5Cu003e%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tile_layer_af412f55bf944dcfa5a8a2eba45625f8%20%3D%20L.tileLayer%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A//a.basemaps.cartocdn.com/rastertiles/voyager/%7Bz%7D/%7Bx%7D/%7By%7D.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22attribution%22%3A%20%22%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//www.openstreetmap.org/copyright%5C%22%5Cu003eOpenStreetMap%5Cu003c/a%5Cu003e%20contributors%20%5Cu0026copy%3B%20%5Cu003ca%20href%3D%5C%22https%3A//carto.com/attributions%5C%22%5Cu003eCARTO%5Cu003c/a%5Cu003e%22%2C%20%22detectRetina%22%3A%20false%2C%20%22maxNativeZoom%22%3A%2018%2C%20%22maxZoom%22%3A%2018%2C%20%22minZoom%22%3A%200%2C%20%22noWrap%22%3A%20false%2C%20%22opacity%22%3A%201%2C%20%22subdomains%22%3A%20%22abc%22%2C%20%22tms%22%3A%20false%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20layer_control_985081ee13ef44408e7f9e73a75dce90%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20base_layers%20%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22openstreetmap%22%20%3A%20tile_layer_3be742203a3443bf9924479193c24b2f%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22OpenStreetMap.Mapnik%22%20%3A%20tile_layer_fa9e8262497f44f6ac89a9a5ad52ffd5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22OpenTopoMap%22%20%3A%20tile_layer_90e71b091ef24f63aedafe3e000786f7%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Stamen.Toner%22%20%3A%20tile_layer_8e41c637372a4de19e9d5487d7b7c590%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Stamen.TonerLite%22%20%3A%20tile_layer_dbc7470ffc044e6d9588247c0bc7b5e3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Stamen.Terrain%22%20%3A%20tile_layer_54d4d85f93f84a59b3eff7f03d451dcf%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Stamen.TerrainBackground%22%20%3A%20tile_layer_a80231bec90948828080e284d2473c76%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Stamen.Watercolor%22%20%3A%20tile_layer_5d1e6a712ebc44acadb9d33a7ed52d7c%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22NASAGIBS.ViirsEarthAtNight2012%22%20%3A%20tile_layer_d84b3264b4244dbaaa2302dd3e2e805e%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22CartoDB.Positron%22%20%3A%20tile_layer_6d8d6e0499bd4d40bf3edfbdd1de4a47%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22CartoDB.Voyager%22%20%3A%20tile_layer_af412f55bf944dcfa5a8a2eba45625f8%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20overlays%20%3A%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20L.control.layers%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20layer_control_985081ee13ef44408e7f9e73a75dce90.base_layers%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20layer_control_985081ee13ef44408e7f9e73a75dce90.overlays%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%22autoZIndex%22%3A%20true%2C%20%22collapsed%22%3A%20true%2C%20%22position%22%3A%20%22topright%22%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%29.addTo%28map_751b35603c85463a92e72556ee1db07d%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_fa9e8262497f44f6ac89a9a5ad52ffd5.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_90e71b091ef24f63aedafe3e000786f7.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_8e41c637372a4de19e9d5487d7b7c590.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_dbc7470ffc044e6d9588247c0bc7b5e3.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_54d4d85f93f84a59b3eff7f03d451dcf.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_a80231bec90948828080e284d2473c76.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_5d1e6a712ebc44acadb9d33a7ed52d7c.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_d84b3264b4244dbaaa2302dd3e2e805e.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_6d8d6e0499bd4d40bf3edfbdd1de4a47.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tile_layer_af412f55bf944dcfa5a8a2eba45625f8.remove%28%29%3B%0A%20%20%20%20%20%20%20%20%0A%3C/script%3E onload=\"this.contentDocument.open();this.contentDocument.write(    decodeURIComponent(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
      ]
     },
     "metadata": {},
     "execution_count": 24
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Loading providers from [Quick Map Services](https://qms.nextgis.com/)\n",
    "\n",
    "Even though `xyzservices` comes with a large number of built-in providers, you can load even more directly from [Quick Map Services](https://qms.nextgis.com/) using the `TileProvider.from_qms()` method. Note that the name needs to match the name in the QMS database."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "source": [
    "from xyzservices import TileProvider\n",
    "\n",
    "qms_provider = TileProvider.from_qms(\"OpenTopoMap\")\n",
    "qms_provider"
   ],
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "{'name': 'OpenTopoMap',\n",
       " 'url': 'https://tile.opentopomap.org/{z}/{x}/{y}.png',\n",
       " 'min_zoom': 0,\n",
       " 'max_zoom': 19,\n",
       " 'attribution': 'OpenTopoMap (CC-BY-SA)'}"
      ],
      "text/html": [
       "\n",
       "        <div>\n",
       "        <style>\n",
       "/* CSS stylesheet for displaying xyzservices objects in Jupyter.*/\n",
       ".xyz-wrap {\n",
       "    --xyz-border-color: var(--jp-border-color2, #ddd);\n",
       "    --xyz-font-color2: var(--jp-content-font-color2, rgba(128, 128, 128, 1));\n",
       "    --xyz-background-color-white: var(--jp-layout-color1, white);\n",
       "    --xyz-background-color: var(--jp-layout-color2, rgba(128, 128, 128, 0.1));\n",
       "}\n",
       "\n",
       "html[theme=dark] .xyz-wrap,\n",
       "body.vscode-dark .xyz-wrap,\n",
       "body.vscode-high-contrast .xyz-wrap {\n",
       "    --xyz-border-color: #222;\n",
       "    --xyz-font-color2: rgba(255, 255, 255, 0.54);\n",
       "    --xyz-background-color-white: rgba(255, 255, 255, 1);\n",
       "    --xyz-background-color: rgba(255, 255, 255, 0.05);\n",
       "\n",
       "}\n",
       "\n",
       ".xyz-header {\n",
       "    padding-top: 6px;\n",
       "    padding-bottom: 6px;\n",
       "    margin-bottom: 4px;\n",
       "    border-bottom: solid 1px var(--xyz-border-color);\n",
       "}\n",
       "\n",
       ".xyz-header>div {\n",
       "    display: inline;\n",
       "    margin-top: 0;\n",
       "    margin-bottom: 0;\n",
       "}\n",
       "\n",
       ".xyz-obj,\n",
       ".xyz-name {\n",
       "    margin-left: 2px;\n",
       "    margin-right: 10px;\n",
       "}\n",
       "\n",
       ".xyz-obj {\n",
       "    color: var(--xyz-font-color2);\n",
       "}\n",
       "\n",
       ".xyz-attrs {\n",
       "    grid-column: 1 / -1;\n",
       "}\n",
       "\n",
       "dl.xyz-attrs {\n",
       "    padding: 0 5px 0 5px;\n",
       "    margin: 0;\n",
       "    display: grid;\n",
       "    grid-template-columns: 135px auto;\n",
       "    background-color: var(--xyz-background-color);\n",
       "}\n",
       "\n",
       ".xyz-attrs dt,\n",
       "dd {\n",
       "    padding: 0;\n",
       "    margin: 0;\n",
       "    float: left;\n",
       "    padding-right: 10px;\n",
       "    width: auto;\n",
       "}\n",
       "\n",
       ".xyz-attrs dt {\n",
       "    font-weight: normal;\n",
       "    grid-column: 1;\n",
       "}\n",
       "\n",
       ".xyz-attrs dd {\n",
       "    grid-column: 2;\n",
       "    white-space: pre-wrap;\n",
       "    word-break: break-all;\n",
       "}\n",
       "\n",
       ".xyz-details ul>li>label>span {\n",
       "    color: var(--xyz-font-color2);\n",
       "    padding-left: 10px;\n",
       "}\n",
       "\n",
       ".xyz-inside {\n",
       "    display: none;\n",
       "}\n",
       "\n",
       ".xyz-checkbox:checked~.xyz-inside {\n",
       "    display: contents;\n",
       "}\n",
       "\n",
       ".xyz-collapsible li>input {\n",
       "    display: none;\n",
       "}\n",
       "\n",
       ".xyz-collapsible>li>label {\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".xyz-collapsible>li>label:hover {\n",
       "    color: var(--xyz-font-color2);\n",
       "}\n",
       "\n",
       "ul.xyz-collapsible {\n",
       "    list-style: none!important;\n",
       "    padding-left: 20px!important;\n",
       "}\n",
       "\n",
       ".xyz-checkbox+label:before {\n",
       "    content: '►';\n",
       "    font-size: 11px;\n",
       "}\n",
       "\n",
       ".xyz-checkbox:checked+label:before {\n",
       "    content: '▼';\n",
       "}\n",
       "\n",
       ".xyz-wrap {\n",
       "    margin-bottom: 10px;\n",
       "}\n",
       "</style>\n",
       "            <div class=\"xyz-wrap\">\n",
       "                <div class=\"xyz-header\">\n",
       "                    <div class=\"xyz-obj\">xyzservices.TileProvider</div>\n",
       "                    <div class=\"xyz-name\">OpenTopoMap</div>\n",
       "                </div>\n",
       "                <div class=\"xyz-details\">\n",
       "                    <dl class=\"xyz-attrs\">\n",
       "                        <dt><span>url</span></dt><dd>https://tile.opentopomap.org/{z}/{x}/{y}.png</dd><dt><span>min_zoom</span></dt><dd>0</dd><dt><span>max_zoom</span></dt><dd>19</dd><dt><span>attribution</span></dt><dd>OpenTopoMap (CC-BY-SA)</dd>\n",
       "                    </dl>\n",
       "                </div>\n",
       "            </div>\n",
       "        </div>\n",
       "        "
      ]
     },
     "metadata": {},
     "execution_count": 25
    }
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "```{important}\n",
    "You should always check the license and terms and conditions of XYZ tiles you want to use. Not all of them can be used in all circumstances and not all Quick Map Services can be considered free even though they may work.\n",
    "```"
   ],
   "metadata": {}
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "9914e2881520d4f08a067c2c2c181121476026b863eca2e121cd0758701ab602"
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.9.2 64-bit ('geo_dev': conda)"
  },
  "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.9.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}