python-package/lets_plot/settings_utils.py (69 lines of code) (raw):
# Copyright (c) 2020. JetBrains s.r.o.
# Use of this source code is governed by the MIT license that can be found in the LICENSE file.
from ._global_settings import GEOCODING_PROVIDER_URL, MAPTILES_SOLID_FILL_COLOR, TILES_CHESSBOARD, \
_DATALORE_TILES_SERVICE
from ._global_settings import MAPTILES_KIND, MAPTILES_URL, MAPTILES_THEME, MAPTILES_ATTRIBUTION, MAPTILES_MIN_ZOOM, \
MAPTILES_MAX_ZOOM, TILES_VECTOR_LETS_PLOT, TILES_RASTER_ZXY, TILES_SOLID, _DATALORE_TILES_ATTRIBUTION
from ._global_settings import has_global_value, get_global_val, _DATALORE_TILES_MIN_ZOOM, _DATALORE_TILES_MAX_ZOOM
__all__ = ['maptiles_zxy', 'maptiles_lets_plot', 'maptiles_solid']
def maptiles_lets_plot(url: str = None, theme: str = None) -> dict:
"""
Make vector tiles config. Can be used individually in `geom_livemap() <https://lets-plot.org/python/pages/api/lets_plot.geom_livemap.html>`__
or in every livemap via `LetsPlot.set() <https://lets-plot.org/python/pages/api/lets_plot.LetsPlot.html#lets_plot.LetsPlot.set>`__.
Parameters
----------
url : str
Address of the tile server. Can be omitted if URL is already set in global settings.
theme : {'color', 'light', 'dark', 'bw'}
Tiles theme.
Returns
-------
dict
Tile provider settings.
Notes
-----
If you are using Safari and having trouble loading tiles, try disabling the NSURLSession Websocket feature.
Go to `Develop -> Experimental Features -> NSURLSession Websocket` to turn it off.
Also, you could use raster tiles from ``lets_plot.tilesets``, e.g.
``ggplot() + geom_livemap(tiles=tilesets.OPEN_TOPO_MAP)``.
Examples
--------
.. jupyter-execute::
:linenos:
:emphasize-lines: 3
from lets_plot import *
LetsPlot.setup_html()
tiles = maptiles_lets_plot(url='wss://tiles.datalore.jetbrains.com', theme='light')
ggplot() + geom_livemap(tiles=tiles)
"""
assert isinstance(url, (str, type(None))), "'url' argument is not str: {}".format(type(url))
assert isinstance(theme, (str, type(None))), "'theme' argument is not str: {}".format(type(theme))
if url is None:
global_maptiles_kind = get_global_val(MAPTILES_KIND) if has_global_value(MAPTILES_KIND) else None
global_maptiles_url = get_global_val(MAPTILES_URL) if has_global_value(MAPTILES_URL) else None
# try to read url from global settings
if global_maptiles_kind == TILES_VECTOR_LETS_PLOT:
if global_maptiles_url is None:
# global URL is somehow broken - use default URL
url = _DATALORE_TILES_SERVICE
else:
url = global_maptiles_url
else:
# User input:
# LetsPlot.set(maptiles_zxy(...))
# LetsPlot.set(maptiles_lets_plot(...))
# In this case global_maptiles_url will contain not-applicable raster tile URL.
# Use hardcoded lets_plot tiles URL.
url = _DATALORE_TILES_SERVICE
if url is None:
raise ValueError('lets_plot tiles service URL is not defined')
return {
MAPTILES_KIND: TILES_VECTOR_LETS_PLOT,
MAPTILES_URL: url,
MAPTILES_THEME: theme,
MAPTILES_ATTRIBUTION: _DATALORE_TILES_ATTRIBUTION,
MAPTILES_MIN_ZOOM: _DATALORE_TILES_MIN_ZOOM,
MAPTILES_MAX_ZOOM: _DATALORE_TILES_MAX_ZOOM,
}
def maptiles_zxy(url: str, attribution: str = None, min_zoom: int = None, max_zoom: int = None, subdomains: str = None,
**other_args) -> dict:
"""
Make raster tiles config. Can be used individually in `geom_livemap() <https://lets-plot.org/python/pages/api/lets_plot.geom_livemap.html>`__
or in every livemap via `LetsPlot.set() <https://lets-plot.org/python/pages/api/lets_plot.LetsPlot.html#lets_plot.LetsPlot.set>`__.
Parameters
----------
url : str
Template for a standard raster ZXY tile provider with {z}, {x}, {y} and {s} placeholders,
e.g. ``"https://{s}.tile.com/{z}/{x}/{y}.png"``. Where {z} means zoom, {x} and {y} means
tile coordinate, {s} means subdomains.
attribution : str
An attribution or a copyright notice to display on the map as required by the tile license.
Supports HTML links: ``'<a href="http://www.example.com">Example</a>'``.
min_zoom : int
Minimal zoom limit, an integer from 1 to 15. Should be less than or equal to ``max_zoom``.
max_zoom : int
Maximal zoom limit, an integer from 1 to 15. Should be greater than or equal to ``min_zoom``.
subdomains : str
Each character of this list is interpreted as standalone tile servers, so an interactive map
can request tiles from any of these servers independently for better load balance. If url
contains {s} placeholder and subdomains parameter is not set default string 'abc' will be used.
other_args
Any key-value pairs that can be substituted into the URL template, e.g.
``maptiles_zxy(url='http://maps.example.com/{z}/{x}/{y}.png?access_key={key}', key='MY_ACCESS_KEY')``.
Returns
-------
dict
Tile provider settings.
Examples
--------
.. jupyter-execute::
:linenos:
:emphasize-lines: 3-7
from lets_plot import *
LetsPlot.setup_html()
tiles = maptiles_zxy(
url="https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/VIIRS_CityLights_2012/default/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg",
attribution='<a href="https://earthdata.nasa.gov/eosdis/science-system-description/eosdis-components/gibs">© NASA Global Imagery Browse Services (GIBS)</a>',
max_zoom=8
)
ggplot() + geom_livemap(tiles=tiles)
"""
assert isinstance(url, str), "'url' argument is not str: {}".format(type(url))
assert isinstance(attribution, (str, type(None))), "'attribution' argument is not str: {}".format(type(url))
if subdomains is not None and "{s}" not in url:
raise ValueError("Subdomains are set but {s} placeholder is not found in url: " + subdomains)
for k, v in other_args.items():
assert k not in ["x", "y", "z", "s"], "other_args can't contain keys x, y, z and s"
url = url.replace("{" + k + "}", v)
if subdomains is not None and "{s}" in url:
url = url.replace("{s}", '[' + subdomains + ']')
elif subdomains is None and "{s}" in url:
url = url.replace("{s}", '[abc]')
return {
MAPTILES_KIND: TILES_RASTER_ZXY,
MAPTILES_URL: url,
MAPTILES_ATTRIBUTION: _build_attribution(attribution),
MAPTILES_MIN_ZOOM: min_zoom,
MAPTILES_MAX_ZOOM: max_zoom
}
def maptiles_solid(color: str):
"""
Make solid color tiles config. Can be used individually in `geom_livemap() <https://lets-plot.org/python/pages/api/lets_plot.geom_livemap.html>`__
or in every livemap via `LetsPlot.set() <https://lets-plot.org/python/pages/api/lets_plot.LetsPlot.html#lets_plot.LetsPlot.set>`__.
Parameters
----------
color : str
Color in HEX format.
Returns
-------
dict
Tile provider settings.
Examples
--------
.. jupyter-execute::
:linenos:
:emphasize-lines: 5
from lets_plot import *
from lets_plot.geo_data import *
LetsPlot.setup_html()
nyc = geocode_cities('New York').get_boundaries()
tiles = maptiles_solid(color='#d3d3d3')
ggplot() + geom_livemap(tiles=tiles) + geom_map(data=nyc)
"""
return {
MAPTILES_KIND: TILES_SOLID,
MAPTILES_SOLID_FILL_COLOR: color
}
def maptiles_chessboard():
"""
Make solid color tiles with chessboard pattern. Can be used individually in `geom_livemap() <https://lets-plot.org/python/pages/api/lets_plot.geom_livemap.html>`__
or in every livemap via `LetsPlot.set() <https://lets-plot.org/python/pages/api/lets_plot.LetsPlot.html#lets_plot.LetsPlot.set>`__.
Returns
-------
dict
Tile provider settings.
Examples
--------
.. jupyter-execute::
:linenos:
:emphasize-lines: 3
from lets_plot.settings_utils import maptiles_chessboard
LetsPlot.setup_html()
ggplot() + geom_livemap(tiles=maptiles_chessboard())
"""
return {
MAPTILES_KIND: TILES_CHESSBOARD
}
def geocoding_service(url: str):
"""
Make geocoding service config.
Can be applied via LetsPlot.set(...)
Parameters
----------
url : string
Address of the geocoding server
Returns
-------
Geocoding service settings
"""
assert isinstance(url, str), "'url' argument is not str: {}".format(type(url))
return {
GEOCODING_PROVIDER_URL: url
}
def _build_attribution(other_attributions):
map_attribution = '<a href="https://lets-plot.org">\u00a9 Lets-Plot</a>'
if other_attributions is None:
return map_attribution
else:
return map_attribution + ', ' + other_attributions