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