Skip to content

Commit ebe9df1

Browse files
Remote datasets: Add "load_earth_dist" to load "GSHHG Earth distance to shoreline" dataset (#3706)
Co-authored-by: Dongdong Tian <seisman.info@gmail.com>
1 parent 33a4bac commit ebe9df1

File tree

6 files changed

+180
-0
lines changed

6 files changed

+180
-0
lines changed

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ and store them in GMT's user data directory.
233233
datasets.load_black_marble
234234
datasets.load_blue_marble
235235
datasets.load_earth_age
236+
datasets.load_earth_dist
236237
datasets.load_earth_free_air_anomaly
237238
datasets.load_earth_geoid
238239
datasets.load_earth_magnetic_anomaly

pygmt/datasets/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from pygmt.datasets.earth_age import load_earth_age
88
from pygmt.datasets.earth_day import load_blue_marble
9+
from pygmt.datasets.earth_dist import load_earth_dist
910
from pygmt.datasets.earth_free_air_anomaly import load_earth_free_air_anomaly
1011
from pygmt.datasets.earth_geoid import load_earth_geoid
1112
from pygmt.datasets.earth_magnetic_anomaly import load_earth_magnetic_anomaly

pygmt/datasets/earth_dist.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""
2+
Function to download the GSHHG Earth distance to shoreline dataset from the GMT data
3+
server, and load as :class:`xarray.DataArray`.
4+
5+
The grids are available in various resolutions.
6+
"""
7+
8+
from collections.abc import Sequence
9+
from typing import Literal
10+
11+
import xarray as xr
12+
from pygmt.datasets.load_remote_dataset import _load_remote_dataset
13+
14+
__doctest_skip__ = ["load_earth_dist"]
15+
16+
17+
def load_earth_dist(
18+
resolution: Literal[
19+
"01d", "30m", "20m", "15m", "10m", "06m", "05m", "04m", "03m", "02m", "01m"
20+
] = "01d",
21+
region: Sequence[float] | str | None = None,
22+
registration: Literal["gridline", "pixel"] = "gridline",
23+
) -> xr.DataArray:
24+
r"""
25+
Load the GSHHG Earth distance to shoreline dataset in various resolutions.
26+
27+
.. figure:: https://www.generic-mapping-tools.org/remote-datasets/_images/GMT_earth_dist.jpg
28+
:width: 80 %
29+
:align: center
30+
31+
GSHHG Earth distance to shoreline dataset.
32+
33+
The grids are downloaded to a user data directory (usually
34+
``~/.gmt/server/earth/earth_dist/``) the first time you invoke this function.
35+
Afterwards, it will load the grid from the data directory. So you'll need an
36+
internet connection the first time around.
37+
38+
These grids can also be accessed by passing in the file name
39+
**@earth_dist**\_\ *res*\[_\ *reg*] to any grid processing function or plotting
40+
method. *res* is the grid resolution (see below), and *reg* is the grid registration
41+
type (**p** for pixel registration or **g** for gridline registration).
42+
43+
The default color palette table (CPT) for this dataset is *@earth_dist.cpt*. It's
44+
implicitly used when passing in the file name of the dataset to any grid plotting
45+
method if no CPT is explicitly specified. When the dataset is loaded and plotted
46+
as an :class:`xarray.DataArray` object, the default CPT is ignored, and GMT's
47+
default CPT (*turbo*) is used. To use the dataset-specific CPT, you need to
48+
explicitly set ``cmap="@earth_dist.cpt"``.
49+
50+
Refer to :gmt-datasets:`earth-dist.html` for more details about available datasets,
51+
including version information and references.
52+
53+
Parameters
54+
----------
55+
resolution
56+
The grid resolution. The suffix ``d`` and ``m`` stand for arc-degrees and
57+
arc-minutes.
58+
region
59+
The subregion of the grid to load, in the form of a sequence [*xmin*, *xmax*,
60+
*ymin*, *ymax*] or an ISO country code. Required for grids with resolutions
61+
higher than 5 arc-minutes (i.e., ``"05m"``).
62+
registration
63+
Grid registration type. Either ``"pixel"`` for pixel registration or
64+
``"gridline"`` for gridline registration.
65+
66+
Returns
67+
-------
68+
grid
69+
The GSHHG Earth distance to shoreline grid. Coordinates are latitude and
70+
longitude in degrees. Distances are in kilometers, where positive (negative)
71+
values mean land to coastline (ocean to coastline).
72+
73+
Note
74+
----
75+
The registration and coordinate system type of the returned
76+
:class:`xarray.DataArray` grid can be accessed via the GMT accessors (i.e.,
77+
``grid.gmt.registration`` and ``grid.gmt.gtype`` respectively). However, these
78+
properties may be lost after specific grid operations (such as slicing) and will
79+
need to be manually set before passing the grid to any PyGMT data processing or
80+
plotting functions. Refer to :class:`pygmt.GMTDataArrayAccessor` for detailed
81+
explanations and workarounds.
82+
83+
Examples
84+
--------
85+
86+
>>> from pygmt.datasets import load_earth_dist
87+
>>> # load the default grid (gridline-registered 1 arc-degree grid)
88+
>>> grid = load_earth_dist()
89+
>>> # load the 30 arc-minutes grid with "gridline" registration
90+
>>> grid = load_earth_dist(resolution="30m", registration="gridline")
91+
>>> # load high-resolution (5 arc-minutes) grid for a specific region
92+
>>> grid = load_earth_dist(
93+
... resolution="05m",
94+
... region=[120, 160, 30, 60],
95+
... registration="gridline",
96+
... )
97+
"""
98+
grid = _load_remote_dataset(
99+
name="earth_dist",
100+
prefix="earth_dist",
101+
resolution=resolution,
102+
region=region,
103+
registration=registration,
104+
)
105+
return grid

pygmt/datasets/load_remote_dataset.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,24 @@ class GMTRemoteDataset(NamedTuple):
9292
"30s": Resolution("30s", registrations=["pixel"]),
9393
},
9494
),
95+
"earth_dist": GMTRemoteDataset(
96+
description="GSHHG Earth distance to shoreline",
97+
units="km",
98+
extra_attributes={"horizontal_datum": "WGS84"},
99+
resolutions={
100+
"01d": Resolution("01d"),
101+
"30m": Resolution("30m"),
102+
"20m": Resolution("20m"),
103+
"15m": Resolution("15m"),
104+
"10m": Resolution("10m"),
105+
"06m": Resolution("06m"),
106+
"05m": Resolution("05m", tiled=True),
107+
"04m": Resolution("04m", tiled=True),
108+
"03m": Resolution("03m", tiled=True),
109+
"02m": Resolution("02m", tiled=True),
110+
"01m": Resolution("01m", registrations=["gridline"], tiled=True),
111+
},
112+
),
95113
"earth_faa": GMTRemoteDataset(
96114
description="IGPP Earth free-air anomaly",
97115
units="mGal",

pygmt/helpers/caching.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def cache_data():
1414
# List of GMT remote datasets.
1515
"@earth_age_01d_g",
1616
"@earth_day_01d",
17+
"@earth_dist_01d",
1718
"@earth_faa_01d_g",
1819
"@earth_gebco_01d_g",
1920
"@earth_gebcosi_01d_g",
@@ -45,6 +46,7 @@ def cache_data():
4546
"@N00W030.earth_age_01m_g.nc",
4647
"@N30E060.earth_age_01m_g.nc",
4748
"@N30E090.earth_age_01m_g.nc",
49+
"@N00W030.earth_dist_01m_g.nc",
4850
"@N00W030.earth_faa_01m_p.nc",
4951
"@N00W030.earth_geoid_01m_g.nc",
5052
"@S30W060.earth_mag_02m_p.nc",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
Test basic functionality for loading Earth distance to shoreline datasets.
3+
"""
4+
5+
import numpy as np
6+
import numpy.testing as npt
7+
from pygmt.datasets import load_earth_dist
8+
9+
10+
def test_earth_dist_01d():
11+
"""
12+
Test some properties of the Earth distance to shoreline 01d data.
13+
"""
14+
data = load_earth_dist(resolution="01d")
15+
assert data.name == "z"
16+
assert data.attrs["description"] == "GSHHG Earth distance to shoreline"
17+
assert data.attrs["units"] == "km"
18+
assert data.attrs["horizontal_datum"] == "WGS84"
19+
assert data.shape == (181, 361)
20+
assert data.gmt.registration == 0
21+
npt.assert_allclose(data.lat, np.arange(-90, 91, 1))
22+
npt.assert_allclose(data.lon, np.arange(-180, 181, 1))
23+
npt.assert_allclose(data.min(), -2655.7, atol=0.01)
24+
npt.assert_allclose(data.max(), 2463.42, atol=0.01)
25+
26+
27+
def test_earth_dist_01d_with_region():
28+
"""
29+
Test loading low-resolution Earth distance to shoreline with "region".
30+
"""
31+
data = load_earth_dist(resolution="01d", region=[-10, 10, -5, 5])
32+
assert data.shape == (11, 21)
33+
assert data.gmt.registration == 0
34+
npt.assert_allclose(data.lat, np.arange(-5, 6, 1))
35+
npt.assert_allclose(data.lon, np.arange(-10, 11, 1))
36+
npt.assert_allclose(data.min(), -1081.94, atol=0.01)
37+
npt.assert_allclose(data.max(), 105.18, atol=0.01)
38+
39+
40+
def test_earth_dist_01m_default_registration():
41+
"""
42+
Test that the grid returned by default for the 1 arc-minute resolution has a
43+
"gridline" registration.
44+
"""
45+
data = load_earth_dist(resolution="01m", region=[-10, -9, 3, 5])
46+
assert data.shape == (121, 61)
47+
assert data.gmt.registration == 0
48+
assert data.coords["lat"].data.min() == 3.0
49+
assert data.coords["lat"].data.max() == 5.0
50+
assert data.coords["lon"].data.min() == -10.0
51+
assert data.coords["lon"].data.max() == -9.0
52+
npt.assert_allclose(data.min(), -243.62, atol=0.01)
53+
npt.assert_allclose(data.max(), 2.94, atol=0.01)

0 commit comments

Comments
 (0)