From 6f7a4f0217d57e67419d79b29e337471324d68a2 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 12:18:40 -0400 Subject: [PATCH 01/27] Add function to load raster basemap tiles using contextily New dataset function to load XYZ tiles! Uses contextily to retrieve the tiles based on a bounding box. Included an example doctest that shows how the map tiles can be loaded into an xarray.DataArray. Added a new section in the API docs and intersphinx mappings for contextily and xyzservices. --- doc/api/index.rst | 1 + doc/conf.py | 4 +- pygmt/datasets/__init__.py | 1 + pygmt/datasets/map_tiles.py | 108 ++++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 pygmt/datasets/map_tiles.py diff --git a/doc/api/index.rst b/doc/api/index.rst index 40f6fc8fad4..98d7e058912 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -227,6 +227,7 @@ and store them in the GMT cache folder. datasets.load_fractures_compilation datasets.load_hotspots datasets.load_japan_quakes + datasets.load_map_tiles datasets.load_mars_shape datasets.load_ocean_ridge_points datasets.load_sample_bathymetry diff --git a/doc/conf.py b/doc/conf.py index 0d57658079c..8932bc23686 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -54,11 +54,13 @@ # intersphinx configuration intersphinx_mapping = { - "python": ("https://docs.python.org/3/", None), + "contextily": ("https://contextily.readthedocs.io/en/stable/", None), "geopandas": ("https://geopandas.org/en/stable/", None), "numpy": ("https://numpy.org/doc/stable/", None), + "python": ("https://docs.python.org/3/", None), "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None), "xarray": ("https://xarray.pydata.org/en/stable/", None), + "xyzservices": ("https://xyzservices.readthedocs.io/en/stable", None), } # options for sphinx-copybutton diff --git a/pygmt/datasets/__init__.py b/pygmt/datasets/__init__.py index 93b7210a73e..934b0cbe914 100644 --- a/pygmt/datasets/__init__.py +++ b/pygmt/datasets/__init__.py @@ -4,6 +4,7 @@ from pygmt.datasets.earth_age import load_earth_age from pygmt.datasets.earth_relief import load_earth_relief +from pygmt.datasets.map_tiles import load_map_tiles from pygmt.datasets.samples import ( list_sample_data, load_fractures_compilation, diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py new file mode 100644 index 00000000000..d534b099121 --- /dev/null +++ b/pygmt/datasets/map_tiles.py @@ -0,0 +1,108 @@ +""" +Function to load raster basemap tiles from XYZ tile providers, and load as +:class:`xarray.DataArray`. +""" + +try: + import contextily +except ImportError: + contextily = None + +import numpy as np +import xarray as xr + + +def load_map_tiles(region, source=None, ll=False, **kwargs): + """ + Load a georeferenced raster basemap from XYZ tile providers. + + The tiles that compose the map are merged and georeferenced into an + :class:`xarray.DataArray` image with 3 bands (RGB). Note that the returned + image is in a Spherical Mercator (EPSG:3857) coordinate reference system. + + Parameters + ---------- + region : list + The bounding box of the map in the form of a list [*xmin*, *xmax*, + *ymin*, *ymax*]. These coordinates should be in Spherical Mercator + (EPSG:3857) if ``ll=False``, or longitude/latitude if ``ll=True``. + + source : xyzservices.TileProvider or str + [Optional. Default: Stamen Terrain web tiles] The tile source: web tile + provider or path to local file. The web tile provider can be in the + form of a :class:`xyzservices.TileProvider` object or a URL. The + placeholders for the XYZ in the URL need to be {x}, {y}, {z}, + respectively. For local file paths, the file is read with rasterio and + all bands are loaded into the basemap. IMPORTANT: tiles are assumed to + be in the Spherical Mercator projection (EPSG:3857). + + ll : bool + [Optional. Default: False]. If True, coordinates in ``region`` are + assumed to be lon/lat as opposed to Spherical Mercator. + + kwargs : dict + Extra keyword arguments to pass to :func:`contextily.bounds2img`. + + Returns + ------- + raster : xarray.DataArray + Georefenced 3D data array of RGB value. + + Raises + ------ + ModuleNotFoundError + If ``contextily`` is not installed. Follow + :doc:`install instructions for contextily `, (e.g. + via ``pip install contextily``) before using this function. + + Examples + -------- + >>> import contextily + >>> from pygmt.datasets import load_map_tiles + ... + >>> raster = load_map_tiles( + ... region=[103.60, 104.06, 1.22, 1.49], # West, East, South, North + ... source=contextily.providers.Stamen.TerrainBackground, + ... ll=True, # bounding box coordinates are longitude/latitude + ... ) + >>> raster.sizes + Frozen({'band': 3, 'y': 1024, 'x': 1536}) + >>> raster.coords + Coordinates: + * band (band) int64 0 1 2 + * y (y) float64 1.49 1.49 1.489 1.489 1.489 ... 1.221 1.221 ... + * x (x) float64 103.6 103.6 103.6 103.6 ... 104.1 104.1 104.1 ... + """ + if contextily is None: + raise ModuleNotFoundError( + "Package `contextily` is required to be installed to use this function. " + "Please use `pip install contextily` or " + "`conda install -c conda-forge contextily` " + "to install the package" + ) + + west, east, south, north = region + image, extent = contextily.bounds2img( + w=west, s=south, e=east, n=north, source=source, ll=ll, **kwargs + ) + + # Turn RGBA image from channel-last to channel-first and get 3-band RGB only + _image = image.transpose(2, 0, 1) # Change image from (H, W, C) to (C, H, W) + rgb_image = _image[0:3, :, :] # Get just RGB by dropping RGBA's alpha channel + + # Georeference RGB image into an xarray.DataArray + dataarray = xr.DataArray( + data=rgb_image, + coords=dict( + band=[0, 1, 2], # Red, Green, Blue + y=np.linspace(start=north, stop=south, num=rgb_image.shape[1]), + x=np.linspace(start=west, stop=east, num=rgb_image.shape[2]), + ), + dims=("band", "y", "x"), + ) + + # If rioxarray is installed, set the coordinate reference system + if hasattr(dataarray, "rio"): + dataarray = dataarray.rio.write_crs(input_crs="EPSG:3857") + + return dataarray From 917604d79869014ca75c08eeac071b91fbcd4c0a Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 12:27:29 -0400 Subject: [PATCH 02/27] Format to remove triple dots --- pygmt/datasets/map_tiles.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index d534b099121..0df21b847d5 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -59,7 +59,6 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): -------- >>> import contextily >>> from pygmt.datasets import load_map_tiles - ... >>> raster = load_map_tiles( ... region=[103.60, 104.06, 1.22, 1.49], # West, East, South, North ... source=contextily.providers.Stamen.TerrainBackground, From 66f66cc3a8bce3f2a9882ed0d2b0a779f733f445 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 13:42:19 -0400 Subject: [PATCH 03/27] Use correct Spherical Mercator coordinates Can't assume that the input bounding box (which can be in longitude/latitude) is the same as the returned extent (which is always in EPSG:3857). --- pygmt/datasets/map_tiles.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 0df21b847d5..65738a899e9 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -85,17 +85,18 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): w=west, s=south, e=east, n=north, source=source, ll=ll, **kwargs ) - # Turn RGBA image from channel-last to channel-first and get 3-band RGB only + # Turn RGBA image from channel-last to channel-first and get 3band RGB only _image = image.transpose(2, 0, 1) # Change image from (H, W, C) to (C, H, W) rgb_image = _image[0:3, :, :] # Get just RGB by dropping RGBA's alpha channel # Georeference RGB image into an xarray.DataArray + left, right, bottom, top = extent # xmin, xmax, ymin, ymax dataarray = xr.DataArray( data=rgb_image, coords=dict( band=[0, 1, 2], # Red, Green, Blue - y=np.linspace(start=north, stop=south, num=rgb_image.shape[1]), - x=np.linspace(start=west, stop=east, num=rgb_image.shape[2]), + y=np.linspace(start=top, stop=bottom, num=rgb_image.shape[1]), + x=np.linspace(start=left, stop=right, num=rgb_image.shape[2]), ), dims=("band", "y", "x"), ) From e99ed4dc913897d06bfe0c641ae7a9fe1fb028e6 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 13:44:35 -0400 Subject: [PATCH 04/27] Fix coordinates for doctest --- pygmt/datasets/map_tiles.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 65738a899e9..ae6b5f475fe 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -69,8 +69,8 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): >>> raster.coords Coordinates: * band (band) int64 0 1 2 - * y (y) float64 1.49 1.49 1.489 1.489 1.489 ... 1.221 1.221 ... - * x (x) float64 103.6 103.6 103.6 103.6 ... 104.1 104.1 104.1 ... + * y (y) float64 1.663e+05 1.663e+05 1.663e+05 ... 1.272e+05 ... + * x (x) float64 1.153e+07 1.153e+07 1.153e+07 ... 1.158e+07 ... """ if contextily is None: raise ModuleNotFoundError( From 3c437c057a34f25f39f5443a0c9b3e88ada63c39 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 13:49:39 -0400 Subject: [PATCH 05/27] Change ll parameter to lonlat To fix pylint `C0103: Argument name "ll" doesn't conform to snake_case naming style (invalid-name)`. --- pygmt/datasets/map_tiles.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index ae6b5f475fe..54cd8594618 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -12,7 +12,7 @@ import xarray as xr -def load_map_tiles(region, source=None, ll=False, **kwargs): +def load_map_tiles(region, source=None, lonlat=False, **kwargs): """ Load a georeferenced raster basemap from XYZ tile providers. @@ -25,7 +25,8 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): region : list The bounding box of the map in the form of a list [*xmin*, *xmax*, *ymin*, *ymax*]. These coordinates should be in Spherical Mercator - (EPSG:3857) if ``ll=False``, or longitude/latitude if ``ll=True``. + (EPSG:3857) if ``lonlat=False``, or longitude/latitude if + ``lonlat=True``. source : xyzservices.TileProvider or str [Optional. Default: Stamen Terrain web tiles] The tile source: web tile @@ -36,7 +37,7 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): all bands are loaded into the basemap. IMPORTANT: tiles are assumed to be in the Spherical Mercator projection (EPSG:3857). - ll : bool + lonlat : bool [Optional. Default: False]. If True, coordinates in ``region`` are assumed to be lon/lat as opposed to Spherical Mercator. @@ -62,7 +63,7 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): >>> raster = load_map_tiles( ... region=[103.60, 104.06, 1.22, 1.49], # West, East, South, North ... source=contextily.providers.Stamen.TerrainBackground, - ... ll=True, # bounding box coordinates are longitude/latitude + ... lonlat=True, # bounding box coordinates are longitude/latitude ... ) >>> raster.sizes Frozen({'band': 3, 'y': 1024, 'x': 1536}) @@ -82,7 +83,7 @@ def load_map_tiles(region, source=None, ll=False, **kwargs): west, east, south, north = region image, extent = contextily.bounds2img( - w=west, s=south, e=east, n=north, source=source, ll=ll, **kwargs + w=west, s=south, e=east, n=north, source=source, ll=lonlat, **kwargs ) # Turn RGBA image from channel-last to channel-first and get 3band RGB only From c738375c483bf3f6e2888789e5386d84db14a094 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 13:55:04 -0400 Subject: [PATCH 06/27] Reduce number of local variables to fix pylint R0914 Remove the extent and _image variables to prevent `R0914: Too many local variables (17/15) (too-many-locals)`. --- pygmt/datasets/map_tiles.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 54cd8594618..af44ab09512 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -82,16 +82,15 @@ def load_map_tiles(region, source=None, lonlat=False, **kwargs): ) west, east, south, north = region - image, extent = contextily.bounds2img( + image, (left, right, bottom, top) = contextily.bounds2img( w=west, s=south, e=east, n=north, source=source, ll=lonlat, **kwargs ) - # Turn RGBA image from channel-last to channel-first and get 3band RGB only - _image = image.transpose(2, 0, 1) # Change image from (H, W, C) to (C, H, W) - rgb_image = _image[0:3, :, :] # Get just RGB by dropping RGBA's alpha channel + # Turn RGBA image from channel-last (H, W, C) to channel-first (C, H, W) + # and get just RGB (3 band) by dropping RGBA's alpha channel + rgb_image = image.transpose(2, 0, 1)[0:3, :, :] # Georeference RGB image into an xarray.DataArray - left, right, bottom, top = extent # xmin, xmax, ymin, ymax dataarray = xr.DataArray( data=rgb_image, coords=dict( From 30fd9a2d2505316dafea0a05b5ff7ef0b1ddbf48 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 19 Sep 2022 14:04:11 -0400 Subject: [PATCH 07/27] Add contextily to CI build matrix and include it as optional dependency Let the Continuous Integration tests run with `contextily`, include it in pyproject.toml and environment.yml, and document it in `doc/install.rst` as an optional dependency. --- .github/workflows/ci_tests.yaml | 2 +- .github/workflows/ci_tests_dev.yaml | 2 +- .github/workflows/ci_tests_legacy.yaml | 2 +- doc/install.rst | 1 + environment.yml | 1 + pyproject.toml | 1 + 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci_tests.yaml b/.github/workflows/ci_tests.yaml index b99c8444413..f36e5b558ad 100644 --- a/.github/workflows/ci_tests.yaml +++ b/.github/workflows/ci_tests.yaml @@ -47,7 +47,7 @@ jobs: optional-packages: '' - python-version: '3.10' numpy-version: '1.23' - optional-packages: 'geopandas ipython' + optional-packages: 'contextily geopandas ipython' timeout-minutes: 30 defaults: run: diff --git a/.github/workflows/ci_tests_dev.yaml b/.github/workflows/ci_tests_dev.yaml index b5ee62d4d9c..e2005837884 100644 --- a/.github/workflows/ci_tests_dev.yaml +++ b/.github/workflows/ci_tests_dev.yaml @@ -100,7 +100,7 @@ jobs: geopandas ghostscript libnetcdf hdf5 zlib curl pcre make pip install --pre --prefer-binary \ numpy pandas xarray netCDF4 packaging \ - build dvc ipython 'pytest>=6.0' pytest-cov \ + contextily build dvc ipython 'pytest>=6.0' pytest-cov \ pytest-doctestplus pytest-mpl sphinx-gallery # Pull baseline image data from dvc remote (DAGsHub) diff --git a/.github/workflows/ci_tests_legacy.yaml b/.github/workflows/ci_tests_legacy.yaml index ba43b12a503..02f0958d739 100644 --- a/.github/workflows/ci_tests_legacy.yaml +++ b/.github/workflows/ci_tests_legacy.yaml @@ -64,7 +64,7 @@ jobs: - name: Install dependencies run: | mamba install gmt=${{ matrix.gmt_version }} numpy \ - pandas xarray netCDF4 packaging geopandas \ + pandas xarray netCDF4 packaging contextily geopandas \ build dvc make pytest>=6.0 \ pytest-cov pytest-doctestplus pytest-mpl sphinx-gallery diff --git a/doc/install.rst b/doc/install.rst index b3e98b7ecd6..5cfe823fde2 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -106,6 +106,7 @@ PyGMT requires the following libraries to be installed: The following are optional dependencies: * `IPython `__: For embedding the figures in Jupyter notebooks (recommended). +* `Contextily `__: For retrieving tile maps from the internet. * `GeoPandas `__: For using and plotting GeoDataFrame objects. Installing GMT and other dependencies diff --git a/environment.yml b/environment.yml index ed699cab1dd..237466b3320 100644 --- a/environment.yml +++ b/environment.yml @@ -12,6 +12,7 @@ dependencies: - netCDF4 - packaging # Optional dependencies + - contextily - geopandas # Development dependencies (general) - build diff --git a/pyproject.toml b/pyproject.toml index bd412406363..6496c8cb792 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dynamic = ["version"] [project.optional-dependencies] all = [ + "contextily", "geopandas", "ipython" ] From f913222ff1bf480a1dbc4873eb2ada48c968a1c5 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Tue, 20 Sep 2022 16:37:54 -0400 Subject: [PATCH 08/27] Set default bounding box coordinates to be lonlat Bounding box coordinates are assumed to be longitude/latitude by default, rather than in Spherical Mercator. --- pygmt/datasets/map_tiles.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index af44ab09512..6ceb9221c84 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -12,7 +12,7 @@ import xarray as xr -def load_map_tiles(region, source=None, lonlat=False, **kwargs): +def load_map_tiles(region, source=None, lonlat=True, **kwargs): """ Load a georeferenced raster basemap from XYZ tile providers. @@ -24,9 +24,8 @@ def load_map_tiles(region, source=None, lonlat=False, **kwargs): ---------- region : list The bounding box of the map in the form of a list [*xmin*, *xmax*, - *ymin*, *ymax*]. These coordinates should be in Spherical Mercator - (EPSG:3857) if ``lonlat=False``, or longitude/latitude if - ``lonlat=True``. + *ymin*, *ymax*]. These coordinates should be in longitude/latitude if + ``lonlat=True`` or Spherical Mercator (EPSG:3857) if ``lonlat=False``. source : xyzservices.TileProvider or str [Optional. Default: Stamen Terrain web tiles] The tile source: web tile @@ -38,8 +37,8 @@ def load_map_tiles(region, source=None, lonlat=False, **kwargs): be in the Spherical Mercator projection (EPSG:3857). lonlat : bool - [Optional. Default: False]. If True, coordinates in ``region`` are - assumed to be lon/lat as opposed to Spherical Mercator. + [Optional. Default: True]. If False, coordinates in ``region`` are + assumed to be Spherical Mercator as opposed to lon/lat. kwargs : dict Extra keyword arguments to pass to :func:`contextily.bounds2img`. From 0455bb4dadd7d7aa157a089489dc8972e2ceb889 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Wed, 12 Oct 2022 11:11:19 -0400 Subject: [PATCH 09/27] Skip doctest when contextily is not installed Using the `__doctest_requires__` variable, see https://github.com/astropy/pytest-doctestplus/tree/v0.12.1#doctest-dependencies --- pygmt/datasets/map_tiles.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 6ceb9221c84..3a0eef648e5 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -11,6 +11,8 @@ import numpy as np import xarray as xr +__doctest_requires__ = {("load_map_tiles"): ["contextily"]} + def load_map_tiles(region, source=None, lonlat=True, **kwargs): """ From 6142b40d02471e9f8e95ae507c0ffb5fb51351d6 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Fri, 4 Nov 2022 15:19:52 -0400 Subject: [PATCH 10/27] Fix typo Co-Authored-By: Dongdong Tian --- pygmt/datasets/map_tiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 3a0eef648e5..aaae65df978 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -31,7 +31,7 @@ def load_map_tiles(region, source=None, lonlat=True, **kwargs): source : xyzservices.TileProvider or str [Optional. Default: Stamen Terrain web tiles] The tile source: web tile - provider or path to local file. The web tile provider can be in the + provider or path to a local file. The web tile provider can be in the form of a :class:`xyzservices.TileProvider` object or a URL. The placeholders for the XYZ in the URL need to be {x}, {y}, {z}, respectively. For local file paths, the file is read with rasterio and From 5400710f38658f39b266da71622a35a549a1c076 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Fri, 4 Nov 2022 15:40:37 -0400 Subject: [PATCH 11/27] Add intersphinx link for rasterio Also updated intersphinx link for xarray to new URL at https://docs.xarray.dev/en/stable --- doc/conf.py | 3 ++- pygmt/datasets/map_tiles.py | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index bf7f5b72dfc..12a23665557 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -59,7 +59,8 @@ "numpy": ("https://numpy.org/doc/stable/", None), "python": ("https://docs.python.org/3/", None), "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None), - "xarray": ("https://xarray.pydata.org/en/stable/", None), + "rasterio": ("https://rasterio.readthedocs.io/en/stable/", None), + "xarray": ("https://docs.xarray.dev/en/stable/", None), "xyzservices": ("https://xyzservices.readthedocs.io/en/stable", None), } diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index aaae65df978..98b891fbda4 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -34,9 +34,10 @@ def load_map_tiles(region, source=None, lonlat=True, **kwargs): provider or path to a local file. The web tile provider can be in the form of a :class:`xyzservices.TileProvider` object or a URL. The placeholders for the XYZ in the URL need to be {x}, {y}, {z}, - respectively. For local file paths, the file is read with rasterio and - all bands are loaded into the basemap. IMPORTANT: tiles are assumed to - be in the Spherical Mercator projection (EPSG:3857). + respectively. For local file paths, the file is read with + :doc:`rasterio ` and all bands are loaded into the + basemap. IMPORTANT: tiles are assumed to be in the Spherical Mercator + projection (EPSG:3857). lonlat : bool [Optional. Default: True]. If False, coordinates in ``region`` are From 2959e5836a2cfe2b5c6dd6edc00fbf51a9d42dac Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Wed, 28 Dec 2022 11:31:11 -0500 Subject: [PATCH 12/27] Document wait and max_retries parameters used in contextily.bounds2img --- pygmt/datasets/map_tiles.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 98b891fbda4..47921617dba 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -43,6 +43,15 @@ def load_map_tiles(region, source=None, lonlat=True, **kwargs): [Optional. Default: True]. If False, coordinates in ``region`` are assumed to be Spherical Mercator as opposed to lon/lat. + wait : int + [Optional. Default: 0]. If the tile API is rate-limited, the number of + seconds to wait between a failed request and the next try. + + max_retries : int + [Optional. Default: 2]. Total number of rejected requests allowed + before contextily will stop trying to fetch more tiles from a + rate-limited API. + kwargs : dict Extra keyword arguments to pass to :func:`contextily.bounds2img`. From eeda97356cd483a67136b8991e8524311f3e0537 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Fri, 6 Jan 2023 23:25:26 -0500 Subject: [PATCH 13/27] Reorder deps and add a fullstop Co-authored-by: Dongdong Tian --- .github/workflows/ci_tests_dev.yaml | 2 +- pygmt/datasets/map_tiles.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_tests_dev.yaml b/.github/workflows/ci_tests_dev.yaml index bae80e6f777..28542acadbf 100644 --- a/.github/workflows/ci_tests_dev.yaml +++ b/.github/workflows/ci_tests_dev.yaml @@ -101,7 +101,7 @@ jobs: geopandas ghostscript libnetcdf hdf5 zlib curl pcre make pip install --pre --prefer-binary \ numpy pandas xarray netCDF4 packaging \ - contextily build dvc ipython 'pytest>=6.0' pytest-cov \ + build contextily dvc ipython 'pytest>=6.0' pytest-cov \ pytest-doctestplus pytest-mpl sphinx-gallery # Pull baseline image data from dvc remote (DAGsHub) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index 47921617dba..ffcfac23fbd 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -89,7 +89,7 @@ def load_map_tiles(region, source=None, lonlat=True, **kwargs): "Package `contextily` is required to be installed to use this function. " "Please use `pip install contextily` or " "`conda install -c conda-forge contextily` " - "to install the package" + "to install the package." ) west, east, south, north = region From 67b17fc04ca8b7eae90893c26d802ba626cf0ed5 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Tue, 24 Jan 2023 13:54:54 +0800 Subject: [PATCH 14/27] Use PyGMT's convention for default values in docstrings Modified from original contextily.bounds2img docstring to fit PyGMT's standards. Xref https://github.com/Generi cMappingTools/pygmt/pull/1182. --- pygmt/datasets/map_tiles.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/map_tiles.py index ffcfac23fbd..185a370796d 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/map_tiles.py @@ -30,27 +30,28 @@ def load_map_tiles(region, source=None, lonlat=True, **kwargs): ``lonlat=True`` or Spherical Mercator (EPSG:3857) if ``lonlat=False``. source : xyzservices.TileProvider or str - [Optional. Default: Stamen Terrain web tiles] The tile source: web tile - provider or path to a local file. The web tile provider can be in the - form of a :class:`xyzservices.TileProvider` object or a URL. The - placeholders for the XYZ in the URL need to be {x}, {y}, {z}, - respectively. For local file paths, the file is read with - :doc:`rasterio ` and all bands are loaded into the - basemap. IMPORTANT: tiles are assumed to be in the Spherical Mercator - projection (EPSG:3857). + Optional. The tile source: web tile provider or path to a local file. + The web tile provider can be in the form of a + :class:`xyzservices.TileProvider` object or a URL. The placeholders for + the XYZ in the URL need to be {x}, {y}, {z}, respectively. For local + file paths, the file is read with :doc:`rasterio ` and + all bands are loaded into the basemap. IMPORTANT: tiles are assumed to + be in the Spherical Mercator projection (EPSG:3857). [Default is + ``xyzservices.providers.Stamen.Terrain``, i.e. Stamen Terrain web + tiles]. lonlat : bool - [Optional. Default: True]. If False, coordinates in ``region`` are - assumed to be Spherical Mercator as opposed to lon/lat. + Optional. If False, coordinates in ``region`` are assumed to be + Spherical Mercator as opposed to lon/lat. [Default is True]. wait : int - [Optional. Default: 0]. If the tile API is rate-limited, the number of - seconds to wait between a failed request and the next try. + Optional. If the tile API is rate-limited, the number of seconds to + wait between a failed request and the next try. [Default is 0]. max_retries : int - [Optional. Default: 2]. Total number of rejected requests allowed - before contextily will stop trying to fetch more tiles from a - rate-limited API. + Optional. Total number of rejected requests allowed before contextily + will stop trying to fetch more tiles from a rate-limited API. [Default + is 2]. kwargs : dict Extra keyword arguments to pass to :func:`contextily.bounds2img`. From 3dc8846585df4b4e74ae2dd7887b979d1bac1bd2 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 27 Feb 2023 10:22:37 +1300 Subject: [PATCH 15/27] Rename load_map_tiles to load_tile_map Also create new dedicated section for load_tile_map in the API docs index. --- doc/api/index.rst | 9 ++++++++- pygmt/datasets/__init__.py | 2 +- pygmt/datasets/{map_tiles.py => tile_map.py} | 8 ++++---- 3 files changed, 13 insertions(+), 6 deletions(-) rename pygmt/datasets/{map_tiles.py => tile_map.py} (95%) diff --git a/doc/api/index.rst b/doc/api/index.rst index d642e058704..6303559be52 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -227,7 +227,14 @@ and store them in GMT's user data directory. datasets.load_earth_vertical_gravity_gradient datasets.load_sample_data - datasets.load_map_tiles +In addition, there is also a special function to load XYZ tile maps via +:doc:`contextily ` to be used as base maps. + +.. autosummary:: + :toctree: generated + + datasets.load_tile_map + .. currentmodule:: pygmt Exceptions diff --git a/pygmt/datasets/__init__.py b/pygmt/datasets/__init__.py index 9549f5afbb0..7aba16154be 100644 --- a/pygmt/datasets/__init__.py +++ b/pygmt/datasets/__init__.py @@ -13,5 +13,5 @@ from pygmt.datasets.earth_vertical_gravity_gradient import ( load_earth_vertical_gravity_gradient, ) -from pygmt.datasets.map_tiles import load_map_tiles from pygmt.datasets.samples import list_sample_data, load_sample_data +from pygmt.datasets.tile_map import load_tile_map diff --git a/pygmt/datasets/map_tiles.py b/pygmt/datasets/tile_map.py similarity index 95% rename from pygmt/datasets/map_tiles.py rename to pygmt/datasets/tile_map.py index 185a370796d..6947989b4ef 100644 --- a/pygmt/datasets/map_tiles.py +++ b/pygmt/datasets/tile_map.py @@ -11,10 +11,10 @@ import numpy as np import xarray as xr -__doctest_requires__ = {("load_map_tiles"): ["contextily"]} +__doctest_requires__ = {("load_tile_map"): ["contextily"]} -def load_map_tiles(region, source=None, lonlat=True, **kwargs): +def load_tile_map(region, source=None, lonlat=True, **kwargs): """ Load a georeferenced raster basemap from XYZ tile providers. @@ -71,8 +71,8 @@ def load_map_tiles(region, source=None, lonlat=True, **kwargs): Examples -------- >>> import contextily - >>> from pygmt.datasets import load_map_tiles - >>> raster = load_map_tiles( + >>> from pygmt.datasets import load_tile_map + >>> raster = load_tile_map( ... region=[103.60, 104.06, 1.22, 1.49], # West, East, South, North ... source=contextily.providers.Stamen.TerrainBackground, ... lonlat=True, # bounding box coordinates are longitude/latitude From 5c6177919ea1f109b161e7d297a0c5dcf06ac43c Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 27 Feb 2023 10:28:31 +1300 Subject: [PATCH 16/27] Lint to change coords dict() to {} --- pygmt/datasets/tile_map.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 6947989b4ef..ff60f2fb8da 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -105,11 +105,11 @@ def load_tile_map(region, source=None, lonlat=True, **kwargs): # Georeference RGB image into an xarray.DataArray dataarray = xr.DataArray( data=rgb_image, - coords=dict( - band=[0, 1, 2], # 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]), - ), + coords={ + "band": [0, 1, 2], # 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]), + }, dims=("band", "y", "x"), ) From d06e2c0ee457c9bdbaa5d3de5b6366f10b754edb Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 27 Feb 2023 10:42:20 +1300 Subject: [PATCH 17/27] Add zoom parameter and remove kwargs Wrap all of the parameters in contextily.bounds2img, and so can remove kwargs. Need to disable the pylint recommendation `R0914: Too many local variables`. --- pygmt/datasets/tile_map.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index ff60f2fb8da..48535a8fea1 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -14,7 +14,7 @@ __doctest_requires__ = {("load_tile_map"): ["contextily"]} -def load_tile_map(region, source=None, lonlat=True, **kwargs): +def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_retries=2): """ Load a georeferenced raster basemap from XYZ tile providers. @@ -29,6 +29,9 @@ def load_tile_map(region, source=None, lonlat=True, **kwargs): *ymin*, *ymax*]. These coordinates should be in longitude/latitude if ``lonlat=True`` or Spherical Mercator (EPSG:3857) if ``lonlat=False``. + zoom : int + Optional. Level of detail. [Default is 'auto']. + source : xyzservices.TileProvider or str Optional. The tile source: web tile provider or path to a local file. The web tile provider can be in the form of a @@ -85,6 +88,7 @@ def load_tile_map(region, source=None, lonlat=True, **kwargs): * y (y) float64 1.663e+05 1.663e+05 1.663e+05 ... 1.272e+05 ... * x (x) float64 1.153e+07 1.153e+07 1.153e+07 ... 1.158e+07 ... """ + # pylint: disable=too-many-locals if contextily is None: raise ModuleNotFoundError( "Package `contextily` is required to be installed to use this function. " @@ -95,7 +99,15 @@ def load_tile_map(region, source=None, lonlat=True, **kwargs): west, east, south, north = region image, (left, right, bottom, top) = contextily.bounds2img( - w=west, s=south, e=east, n=north, source=source, ll=lonlat, **kwargs + w=west, + s=south, + e=east, + n=north, + zoom=zoom, + source=source, + ll=lonlat, + wait=wait, + max_retries=max_retries, ) # Turn RGBA image from channel-last (H, W, C) to channel-first (C, H, W) From 6b2d5cd848ca28e6a843587f966c086cb025150b Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 27 Feb 2023 10:48:12 +1300 Subject: [PATCH 18/27] Revert "Reduce number of local variables to fix pylint R0914" This reverts commit c738375c483bf3f6e2888789e5386d84db14a094. Since we've ignored the too-many-locals pylint recommendation already. --- pygmt/datasets/tile_map.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 48535a8fea1..d68ce8e39be 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -98,7 +98,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret ) west, east, south, north = region - image, (left, right, bottom, top) = contextily.bounds2img( + image, extent = contextily.bounds2img( w=west, s=south, e=east, @@ -110,11 +110,12 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret max_retries=max_retries, ) - # Turn RGBA image from channel-last (H, W, C) to channel-first (C, H, W) - # and get just RGB (3 band) by dropping RGBA's alpha channel - rgb_image = image.transpose(2, 0, 1)[0:3, :, :] + # Turn RGBA image from channel-last to channel-first and get 3band RGB only + _image = image.transpose(2, 0, 1) # Change image from (H, W, C) to (C, H, W) + rgb_image = _image[0:3, :, :] # Get just RGB by dropping RGBA's alpha channel # Georeference RGB image into an xarray.DataArray + left, right, bottom, top = extent dataarray = xr.DataArray( data=rgb_image, coords={ From b1ad795226ac626710f48fd87368254a36b23241 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 27 Feb 2023 16:35:05 +1300 Subject: [PATCH 19/27] Add contextily to docs build CI requirements --- .github/workflows/ci_docs.yml | 2 +- ci/requirements/docs.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_docs.yml b/.github/workflows/ci_docs.yml index 5ec85256512..c7a87a005bc 100644 --- a/.github/workflows/ci_docs.yml +++ b/.github/workflows/ci_docs.yml @@ -71,7 +71,7 @@ jobs: - name: Install dependencies run: | mamba install gmt=6.4.0 numpy pandas xarray netCDF4 packaging \ - build ipython make myst-parser geopandas \ + build ipython make myst-parser contextily geopandas \ sphinx sphinx-copybutton sphinx-design sphinx-gallery sphinx_rtd_theme # Show installed pkg information for postmortem diagnostic diff --git a/ci/requirements/docs.yml b/ci/requirements/docs.yml index 7d725cde8e2..a11194fec36 100644 --- a/ci/requirements/docs.yml +++ b/ci/requirements/docs.yml @@ -12,6 +12,7 @@ dependencies: - netCDF4 - packaging # Optional dependencies + - contextily - geopandas # Development dependencies (general) - build From 484b6c878a22944964cb985295929c0569e8a86b Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Mon, 27 Feb 2023 16:37:21 +1300 Subject: [PATCH 20/27] Add contextily to pygmt.show_versions() dependency list --- pygmt/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pygmt/__init__.py b/pygmt/__init__.py index deec3f2b114..1e1ee13447b 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -158,7 +158,15 @@ def _get_ghostscript_version(): "machine": platform.platform(), } - deps = ["numpy", "pandas", "xarray", "netCDF4", "packaging", "geopandas"] + deps = [ + "numpy", + "pandas", + "xarray", + "netCDF4", + "packaging", + "contextily", + "geopandas", + ] print("PyGMT information:") print(f" version: {__version__}") From cf7ab34f44b3800ea1c18cc992d6b8f8c8280f3a Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Tue, 28 Feb 2023 10:13:18 +1300 Subject: [PATCH 21/27] Apply suggestions from code review Co-authored-by: Dongdong Tian --- pygmt/datasets/tile_map.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index d68ce8e39be..9eaa77078af 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -1,5 +1,5 @@ """ -Function to load raster basemap tiles from XYZ tile providers, and load as +Function to load raster tile maps from XYZ tile providers, and load as :class:`xarray.DataArray`. """ @@ -16,7 +16,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_retries=2): """ - Load a georeferenced raster basemap from XYZ tile providers. + Load a georeferenced raster tile map from XYZ tile providers. The tiles that compose the map are merged and georeferenced into an :class:`xarray.DataArray` image with 3 bands (RGB). Note that the returned @@ -45,7 +45,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret lonlat : bool Optional. If False, coordinates in ``region`` are assumed to be - Spherical Mercator as opposed to lon/lat. [Default is True]. + Spherical Mercator as opposed to longitude/latitude. [Default is True]. wait : int Optional. If the tile API is rate-limited, the number of seconds to @@ -56,13 +56,10 @@ 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]. - kwargs : dict - Extra keyword arguments to pass to :func:`contextily.bounds2img`. - Returns ------- raster : xarray.DataArray - Georefenced 3D data array of RGB value. + Georefenced 3-D data array of RGB value. Raises ------ @@ -110,7 +107,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret max_retries=max_retries, ) - # Turn RGBA image from channel-last to channel-first and get 3band RGB only + # Turn RGBA image from channel-last to channel-first and get 3-band RGB only _image = image.transpose(2, 0, 1) # Change image from (H, W, C) to (C, H, W) rgb_image = _image[0:3, :, :] # Get just RGB by dropping RGBA's alpha channel From 8563ecf17eb0dabd4025e0e1c779e25a08e9d6c7 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Tue, 28 Feb 2023 10:16:57 +1300 Subject: [PATCH 22/27] Lint to reduce length of comment line --- pygmt/datasets/tile_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 9eaa77078af..7475ab809f5 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -107,7 +107,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret max_retries=max_retries, ) - # Turn RGBA image from channel-last to channel-first and get 3-band RGB only + # Turn RGBA img from channel-last to channel-first and get 3-band RGB only _image = image.transpose(2, 0, 1) # Change image from (H, W, C) to (C, H, W) rgb_image = _image[0:3, :, :] # Get just RGB by dropping RGBA's alpha channel From aa2d5fb1ebb45a072a2df6709918e55c2baccfeb Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Thu, 2 Mar 2023 18:36:03 +1300 Subject: [PATCH 23/27] Document the three possible source options thoroughly Split out the three possible source options into bullet points. Link to https://contextily.readthedocs.io/en/latest/providers_deepdive.html, give an example OpenStreetMap URL, and link to https://contextily.readthedocs.io/en/stable/working_with_local_files.html. --- pygmt/datasets/tile_map.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 7475ab809f5..b28102a8f1f 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -34,14 +34,24 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret source : xyzservices.TileProvider or str Optional. The tile source: web tile provider or path to a local file. - The web tile provider can be in the form of a - :class:`xyzservices.TileProvider` object or a URL. The placeholders for - the XYZ in the URL need to be {x}, {y}, {z}, respectively. For local - file paths, the file is read with :doc:`rasterio ` and - all bands are loaded into the basemap. IMPORTANT: tiles are assumed to - be in the Spherical Mercator projection (EPSG:3857). [Default is - ``xyzservices.providers.Stamen.Terrain``, i.e. Stamen Terrain web - tiles]. + Provide either: + + - A web tile provider in the form of a + :class:`xyzservices.TileProvider` object. See + :doc:`Contextily providers ` for a + list of tile providers [Default is + ``xyzservices.providers.Stamen.Terrain``, i.e. Stamen Terrain web + tiles]. + - A web tile provider in the form of a URL. The placeholders for the + XYZ in the URL need to be {x}, {y}, {z}, respectively. E.g. + ``https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png``. + - A local file path. The file is read with + :doc:`rasterio ` and all bands are loaded into the + basemap. See + :doc:`contextily:working_with_local_files`. + + 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 From d74f878f138f7cb12693af27f6acbe29fef238e7 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:29:42 +1300 Subject: [PATCH 24/27] Remove extra fullstops and fix typos Co-authored-by: Michael Grund <23025878+michaelgrund@users.noreply.github.com> --- pygmt/datasets/tile_map.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index b28102a8f1f..75dd29a29a7 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -55,21 +55,21 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret lonlat : bool Optional. If False, coordinates in ``region`` are assumed to be - Spherical Mercator as opposed to longitude/latitude. [Default is True]. + Spherical Mercator as opposed to longitude/latitude [Default is True]. wait : int Optional. If the tile API is rate-limited, the number of seconds to - wait between a failed request and the next try. [Default is 0]. + wait between a failed request and the next try [Default is 0]. max_retries : int Optional. Total number of rejected requests allowed before contextily - will stop trying to fetch more tiles from a rate-limited API. [Default + will stop trying to fetch more tiles from a rate-limited API [Default is 2]. Returns ------- raster : xarray.DataArray - Georefenced 3-D data array of RGB value. + Georeferenced 3-D data array of RGB values. Raises ------ From 9f14d31608f29c1aa8277b3c9b52470724eb7fd1 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Thu, 2 Mar 2023 22:35:23 +1300 Subject: [PATCH 25/27] Add more detail about the zoom level of detail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Yvonne Fröhlich <94163266+yvonnefroehlich@users.noreply.github.com> --- pygmt/datasets/tile_map.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 75dd29a29a7..d7b9ec792b4 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -29,8 +29,17 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret *ymin*, *ymax*]. These coordinates should be in longitude/latitude if ``lonlat=True`` or Spherical Mercator (EPSG:3857) if ``lonlat=False``. - zoom : int - Optional. Level of detail. [Default is 'auto']. + zoom : int or str + Optional. Level of detail. Higher levels (e.g. ``22``) means a zoom + level closer to the Earth's surface, with more tiles covering a smaller + geographical area and thus more detail. Lower levels (e.g. ``0``) means + a zoom level further from the Earth's surface, with less tiles covering + a larger geographical area and thus less detail. [Default is + ``"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. source : xyzservices.TileProvider or str Optional. The tile source: web tile provider or path to a local file. From b02b50ca7b75908950aa49181f25dee88b86df77 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Thu, 2 Mar 2023 22:48:10 +1300 Subject: [PATCH 26/27] Remove another fullstop Co-authored-by: Michael Grund <23025878+michaelgrund@users.noreply.github.com> --- pygmt/datasets/tile_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index d7b9ec792b4..18190a9f83e 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -34,7 +34,7 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret level closer to the Earth's surface, with more tiles covering a smaller geographical area and thus more detail. Lower levels (e.g. ``0``) means a zoom level further from the Earth's surface, with less tiles covering - a larger geographical area and thus less detail. [Default is + a larger geographical area and thus less detail [Default is ``"auto"`` to automatically determine the zoom level based on the bounding box region extent]. From 10af781c011f4d4cf2bc86b560429fe9431e374c Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Fri, 3 Mar 2023 11:25:15 +1300 Subject: [PATCH 27/27] Wrap integers in backticks and fix some typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yvonne Fröhlich <94163266+yvonnefroehlich@users.noreply.github.com> --- pygmt/datasets/tile_map.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 18190a9f83e..2afe28acbf9 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -30,16 +30,17 @@ def load_tile_map(region, zoom="auto", source=None, lonlat=True, wait=0, max_ret ``lonlat=True`` or Spherical Mercator (EPSG:3857) if ``lonlat=False``. zoom : int or str - Optional. Level of detail. Higher levels (e.g. ``22``) means a zoom + Optional. Level of detail. Higher levels (e.g. ``22``) mean a zoom level closer to the Earth's surface, with more tiles covering a smaller - geographical area and thus more detail. Lower levels (e.g. ``0``) means + geographical area and thus more detail. Lower levels (e.g. ``0``) mean a zoom level further from the Earth's surface, with less tiles covering a larger geographical area and thus less detail [Default is ``"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. @@ -59,21 +60,22 @@ 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 + 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 - Spherical Mercator as opposed to longitude/latitude [Default is True]. + Optional. If ``False``, coordinates in ``region`` are assumed to be + Spherical Mercator as opposed to longitude/latitude [Default is + ``True``]. wait : int Optional. If the tile API is rate-limited, the number of seconds to - wait between a failed request and the next try [Default is 0]. + wait between a failed request and the next try [Default is ``0``]. max_retries : int Optional. Total number of rejected requests allowed before contextily will stop trying to fetch more tiles from a rate-limited API [Default - is 2]. + is ``2``]. Returns -------