Skip to content

Commit

Permalink
Add zoom_adjust param to pygmt.datasets.load_tile_map and Figure.tile…
Browse files Browse the repository at this point in the history
…map (#2934)

The zoom_adjust parameter is used to adjust the automatic zoom level by integer increments.
This was added in contextily=1.5.0, see geopandas/contextily#228.

* Document that zoom_adjust requires contextily>=1.5.0
* Raise error if zoom_adjust parameter is used with contextily<1.5.0
* Add type hint for zoom_adjust parameter
* Fix typecheck by using np.array constructor instead of np.uint8

Fixes `error: Argument 1 to "unsignedinteger" has incompatible type "list[int]";
expected "SupportsInt | str | bytes | SupportsIndex"  [arg-type]`

* Change directive for zoom_adjust from versionadded to note
* Use note and important admonitions in other parts of the docstring
* Rely on sphinx-autodoc-typehints

---------

Co-authored-by: Dongdong Tian <seisman.info@gmail.com>
Co-authored-by: Yvonne Fröhlich <94163266+yvonnefroehlich@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 8, 2024
1 parent b379976 commit c9c3a4a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 13 deletions.
42 changes: 35 additions & 7 deletions pygmt/datasets/tile_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Function to load raster tile maps from XYZ tile providers, and load as
:class:`xarray.DataArray`.
"""
from __future__ import annotations

from packaging.version import Version

try:
import contextily
Expand All @@ -16,7 +19,15 @@
__doctest_requires__ = {("load_tile_map"): ["contextily"]}


def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_retries=2):
def load_tile_map(
region,
zoom="auto",
source=None,
lonlat=True,
wait=0,
max_retries=2,
zoom_adjust: int | None = None,
):
"""
Load a georeferenced raster tile map from XYZ tile providers.
Expand All @@ -40,9 +51,9 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret
``"auto"`` to automatically determine the zoom level based on the
bounding box region extent].
**Note**: The maximum possible zoom level may be smaller than ``22``,
and depends on what is supported by the chosen web tile provider
source.
.. note::
The maximum possible zoom level may be smaller than ``22``, and depends on
what is supported by the chosen web tile provider source.
source : xyzservices.TileProvider or str
Optional. The tile source: web tile provider or path to a local file.
Expand All @@ -62,8 +73,8 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret
basemap. See
:doc:`contextily:working_with_local_files`.
IMPORTANT: Tiles are assumed to be in the Spherical Mercator projection
(EPSG:3857).
.. important::
Tiles are assumed to be in the Spherical Mercator projection (EPSG:3857).
lonlat : bool
Optional. If ``False``, coordinates in ``region`` are assumed to be
Expand All @@ -79,6 +90,13 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret
will stop trying to fetch more tiles from a rate-limited API [Default
is ``2``].
zoom_adjust
The amount to adjust a chosen zoom level if it is chosen automatically. Values
outside of -1 to 1 are not recommended as they can lead to slow execution.
.. note::
The ``zoom_adjust`` parameter requires ``contextily>=1.5.0``.
Returns
-------
raster : xarray.DataArray
Expand Down Expand Up @@ -117,6 +135,15 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret
"to install the package."
)

contextily_kwargs = {}
if zoom_adjust is not None:
contextily_kwargs["zoom_adjust"] = zoom_adjust
if Version(contextily.__version__) < Version("1.5.0"):
raise TypeError(
"The `zoom_adjust` parameter requires `contextily>=1.5.0` to work. "
"Please upgrade contextily, or manually set the `zoom` level instead."
)

west, east, south, north = region
image, extent = contextily.bounds2img(
w=west,
Expand All @@ -128,6 +155,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret
ll=lonlat,
wait=wait,
max_retries=max_retries,
**contextily_kwargs,
)

# Turn RGBA img from channel-last to channel-first and get 3-band RGB only
Expand All @@ -139,7 +167,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret
dataarray = xr.DataArray(
data=rgb_image,
coords={
"band": np.uint8([0, 1, 2]), # Red, Green, Blue
"band": np.array(object=[0, 1, 2], dtype=np.uint8), # Red, Green, Blue
"y": np.linspace(start=top, stop=bottom, num=rgb_image.shape[1]),
"x": np.linspace(start=left, stop=right, num=rgb_image.shape[2]),
},
Expand Down
30 changes: 24 additions & 6 deletions pygmt/src/tilemap.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""
tilemap - Plot XYZ tile maps.
"""
from __future__ import annotations

from pygmt.clib import Session
from pygmt.datasets.tile_map import load_tile_map
from pygmt.helpers import build_arg_string, fmt_docstring, kwargs_to_strings, use_alias
Expand Down Expand Up @@ -30,7 +32,15 @@
)
@kwargs_to_strings(c="sequence_comma", p="sequence") # R="sequence",
def tilemap(
self, region, zoom="auto", source=None, lonlat=True, wait=0, max_retries=2, **kwargs
self,
region,
zoom="auto",
source=None,
lonlat=True,
wait=0,
max_retries=2,
zoom_adjust: int | None = None,
**kwargs,
):
r"""
Plots an XYZ tile map.
Expand Down Expand Up @@ -64,9 +74,9 @@ def tilemap(
``"auto"`` to automatically determine the zoom level based on the
bounding box region extent].
**Note**: The maximum possible zoom level may be smaller than ``22``,
and depends on what is supported by the chosen web tile provider
source.
.. note::
The maximum possible zoom level may be smaller than ``22``, and depends on
what is supported by the chosen web tile provider source.
source : xyzservices.TileProvider or str
Optional. The tile source: web tile provider or path to a local file.
Expand All @@ -86,8 +96,8 @@ def tilemap(
basemap. See
:doc:`contextily:working_with_local_files`.
IMPORTANT: Tiles are assumed to be in the Spherical Mercator projection
(EPSG:3857).
.. important::
Tiles are assumed to be in the Spherical Mercator projection (EPSG:3857).
lonlat : bool
Optional. If ``False``, coordinates in ``region`` are assumed to be
Expand All @@ -103,6 +113,13 @@ def tilemap(
will stop trying to fetch more tiles from a rate-limited API [Default
is ``2``].
zoom_adjust
The amount to adjust a chosen zoom level if it is chosen automatically. Values
outside of -1 to 1 are not recommended as they can lead to slow execution.
.. note::
The ``zoom_adjust`` parameter requires ``contextily>=1.5.0``.
kwargs : dict
Extra keyword arguments to pass to :meth:`pygmt.Figure.grdimage`.
Expand Down Expand Up @@ -131,6 +148,7 @@ def tilemap(
lonlat=lonlat,
wait=wait,
max_retries=max_retries,
zoom_adjust=zoom_adjust,
)

# Reproject raster from Spherical Mercator (EPSG:3857) to
Expand Down

0 comments on commit c9c3a4a

Please sign in to comment.