Skip to content

Commit

Permalink
Merge 1dbd3d6 into da911cc
Browse files Browse the repository at this point in the history
  • Loading branch information
ljwolf committed Apr 7, 2020
2 parents da911cc + 1dbd3d6 commit 83c4f34
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 34 deletions.
76 changes: 58 additions & 18 deletions contextily/tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from rasterio.enums import Resampling
from . import tile_providers as sources
from . import providers
from ._providers import TileProvider

__all__ = ["bounds2raster", "bounds2img", "warp_tiles", "warp_img_transform", "howmany"]

Expand All @@ -40,7 +41,17 @@ def _clear_cache():


def bounds2raster(
w, s, e, n, path, zoom="auto", url=None, ll=False, wait=0, max_retries=2
w,
s,
e,
n,
path,
zoom="auto",
source=None,
ll=False,
wait=0,
max_retries=2,
url=None,
):
"""
Take bounding box and zoom, and write tiles into a raster file in
Expand All @@ -62,11 +73,11 @@ def bounds2raster(
Level of detail
path : str
Path to raster file to be written
url : str
[Optional. Default:
'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'] URL for
tile provider. The placeholders for the XYZ need to be `tileX`,
`tileY`, `tileZ`, respectively. See `cx.sources`.
source : contextily.tile or str
[Optional. Default: 'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png']
URL for tile provider. The placeholders for the XYZ need to be
`tileX`, `tileY`, `tileZ`, respectively. IMPORTANT: tiles are
assumed to be in the Spherical Mercator projection (EPSG:3857).
ll : Boolean
[Optional. Default: False] If True, `w`, `s`, `e`, `n` are
assumed to be lon/lat as opposed to Spherical Mercator.
Expand All @@ -78,6 +89,11 @@ def bounds2raster(
[Optional. Default: 2]
total number of rejected requests allowed before contextily
will stop trying to fetch more tiles from a rate-limited API.
url : str [DEPRECATED]
[Optional. Default:
'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png'] URL for
tile provider. The placeholders for the XYZ need to be `tileX`,
`tileY`, `tileZ`, respectively. See `cx.sources`.
Returns
-------
Expand All @@ -91,7 +107,7 @@ def bounds2raster(
w, s = _sm2ll(w, s)
e, n = _sm2ll(e, n)
# Download
Z, ext = bounds2img(w, s, e, n, zoom=zoom, url=url, ll=True)
Z, ext = bounds2img(w, s, e, n, zoom=zoom, source=source, url=url, ll=True)
# Write
# ---
h, w, b = Z.shape
Expand Down Expand Up @@ -119,7 +135,9 @@ def bounds2raster(
return Z, ext


def bounds2img(w, s, e, n, zoom="auto", url=None, ll=False, wait=0, max_retries=2):
def bounds2img(
w, s, e, n, zoom="auto", source=None, ll=False, wait=0, max_retries=2, url=None
):
"""
Take bounding box and zoom and return an image with all the tiles
that compose the map and its Spherical Mercator extent.
Expand All @@ -138,7 +156,7 @@ def bounds2img(w, s, e, n, zoom="auto", url=None, ll=False, wait=0, max_retries=
North edge
zoom : int
Level of detail
url : str
source : contextily.tile or str
[Optional. Default: 'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png']
URL for tile provider. The placeholders for the XYZ need to be
`tileX`, `tileY`, `tileZ`, respectively. IMPORTANT: tiles are
Expand All @@ -154,6 +172,11 @@ def bounds2img(w, s, e, n, zoom="auto", url=None, ll=False, wait=0, max_retries=
[Optional. Default: 2]
total number of rejected requests allowed before contextily
will stop trying to fetch more tiles from a rate-limited API.
url : str [DEPRECATED]
[Optional. Default: 'http://tile.stamen.com/terrain/tileZ/tileX/tileY.png']
URL for tile provider. The placeholders for the XYZ need to be
`tileX`, `tileY`, `tileZ`, respectively. IMPORTANT: tiles are
assumed to be in the Spherical Mercator projection (EPSG:3857).
Returns
-------
Expand All @@ -166,8 +189,23 @@ def bounds2img(w, s, e, n, zoom="auto", url=None, ll=False, wait=0, max_retries=
# Convert w, s, e, n into lon/lat
w, s = _sm2ll(w, s)
e, n = _sm2ll(e, n)
if url is not None and source is None:
warnings.warn(
'The "url" option is deprecated. Please use the "source"'
" argument instead.",
FutureWarning,
stacklevel=2,
)
source = url
elif url is not None and source is not None:
warnings.warn(
'The "url" argument is deprecated. Please use the "source"'
' argument. Do not supply a "url" argument. It will be ignored.',
FutureWarning,
stacklevel=2,
)
# get provider dict given the url
provider = _process_url(url)
provider = _process_source(source)
# calculate and validate zoom level
auto_zoom = zoom == "auto"
if auto_zoom:
Expand Down Expand Up @@ -207,17 +245,19 @@ def _url_from_string(url):
return {"url": url}


def _process_url(url):
if url is None:
def _process_source(source):
if source is None:
provider = providers.Stamen.Terrain
elif isinstance(url, str):
provider = _url_from_string(url)
elif not isinstance(url, dict):
raise TypeError("The 'url' needs to be a dict or string")
elif "url" not in url:
elif isinstance(source, str):
provider = _url_from_string(source)
elif not isinstance(source, (dict, TileProvider)):
raise TypeError(
"The 'url' needs to be a contextily.providers object, a dict, or string"
)
elif "url" not in source:
raise ValueError("The 'url' dict should at least contain a 'url' key")
else:
provider = url
provider = source
return provider


Expand Down
43 changes: 29 additions & 14 deletions contextily/tile_providers.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
"""Common tile provider URLs."""
import warnings

### Tile provider sources ###

ST_TONER = "http://tile.stamen.com/toner/{z}/{x}/{y}.png"
ST_TONER_HYBRID = "http://tile.stamen.com/toner-hybrid/{z}/{x}/{y}.png"
ST_TONER_LABELS = "http://tile.stamen.com/toner-labels/{z}/{x}/{y}.png"
ST_TONER_LINES = "http://tile.stamen.com/toner-lines/{z}/{x}/{y}.png"
ST_TONER_BACKGROUND = "http://tile.stamen.com/toner-background/{z}/{x}/{y}.png"
ST_TONER_LITE = "http://tile.stamen.com/toner-lite/{z}/{x}/{y}.png"
_ST_TONER = "http://tile.stamen.com/toner/{z}/{x}/{y}.png"
_ST_TONER_HYBRID = "http://tile.stamen.com/toner-hybrid/{z}/{x}/{y}.png"
_ST_TONER_LABELS = "http://tile.stamen.com/toner-labels/{z}/{x}/{y}.png"
_ST_TONER_LINES = "http://tile.stamen.com/toner-lines/{z}/{x}/{y}.png"
_ST_TONER_BACKGROUND = "http://tile.stamen.com/toner-background/{z}/{x}/{y}.png"
_ST_TONER_LITE = "http://tile.stamen.com/toner-lite/{z}/{x}/{y}.png"

ST_TERRAIN = "http://tile.stamen.com/terrain/{z}/{x}/{y}.png"
ST_TERRAIN_LABELS = "http://tile.stamen.com/terrain-labels/{z}/{x}/{y}.png"
ST_TERRAIN_LINES = "http://tile.stamen.com/terrain-lines/{z}/{x}/{y}.png"
ST_TERRAIN_BACKGROUND = "http://tile.stamen.com/terrain-background/{z}/{x}/{y}.png"
_ST_TERRAIN = "http://tile.stamen.com/terrain/{z}/{x}/{y}.png"
_ST_TERRAIN_LABELS = "http://tile.stamen.com/terrain-labels/{z}/{x}/{y}.png"
_ST_TERRAIN_LINES = "http://tile.stamen.com/terrain-lines/{z}/{x}/{y}.png"
_ST_TERRAIN_BACKGROUND = "http://tile.stamen.com/terrain-background/{z}/{x}/{y}.png"

ST_WATERCOLOR = "http://tile.stamen.com/watercolor/{z}/{x}/{y}.png"
_T_WATERCOLOR = "http://tile.stamen.com/watercolor/{z}/{x}/{y}.png"

# OpenStreetMap as an alternative
OSM_A = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
OSM_B = "http://b.tile.openstreetmap.org/{z}/{x}/{y}.png"
OSM_C = "http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"
_OSM_A = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
_OSM_B = "http://b.tile.openstreetmap.org/{z}/{x}/{y}.png"
_OSM_C = "http://c.tile.openstreetmap.org/{z}/{x}/{y}.png"

deprecated_sources = {k.lstrip('_') for k, v in locals().items()
if (False if not isinstance(v, str)
else (v.startswith('http')))
}


def __getattr__(name):
if name in deprecated_sources:
warnings.warn('The "contextily.tile_providers" module is deprecated and will be removed in '
'contextily v1.1. Please use "contextily.providers" instead.',
FutureWarning, stacklevel=2)
return globals()[f'_{name}']
raise AttributeError(f'module {__name__} has no attribute {name}')
5 changes: 3 additions & 2 deletions tests/test_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ def test_sources():
-93.50721740722656,
36.49387741088867,
)
sources = [i for i in dir(tilers) if i[0] != "_"]
sources = tilers.deprecated_sources
for src in sources:
img, ext = ctx.bounds2img(w, s, e, n, 4, url=getattr(tilers, src), ll=True)
img, ext = ctx.bounds2img(
w, s, e, n, 4, url=getattr(tilers, '_'+src), ll=True)


def test_deprecated_url_format():
Expand Down

0 comments on commit 83c4f34

Please sign in to comment.