1
1
"""
2
- Functions to download the Earth relief datasets from the GMT data server.
3
- The grids are available in various resolutions.
2
+ Function to download the Earth relief datasets from the GMT data server,
3
+ and load as DataArray. The grids are available in various resolutions.
4
4
"""
5
5
import xarray as xr
6
6
7
- from .. import which
7
+ from .. import grdcut , which
8
8
from ..exceptions import GMTInvalidInput
9
+ from ..helpers import kwargs_to_strings
9
10
10
11
11
- def load_earth_relief (resolution = "01d" , registration = None ):
12
+ @kwargs_to_strings (region = "sequence" )
13
+ def load_earth_relief (resolution = "01d" , region = None , registration = None ):
12
14
"""
13
15
Load Earth relief grids (topography and bathymetry) in various resolutions.
14
16
15
- The grids are downloaded to a user data directory (usually ``~/.gmt/``) the
16
- first time you invoke this function. Afterwards, it will load the data from
17
- the cache. So you'll need an internet connection the first time around.
17
+ The grids are downloaded to a user data directory
18
+ (usually ``~/.gmt/server/earth/earth_relief/``) the first time you invoke
19
+ this function. Afterwards, it will load the grid from the data directory.
20
+ So you'll need an internet connection the first time around.
18
21
19
22
These grids can also be accessed by passing in the file name
20
- ``'@earth_relief_XXm '`` or ``'@earth_relief_XXs'`` to any grid
21
- plotting/processing function .
23
+ ``'@earth_relief_rru[_reg] '`` to any grid plotting/processing function.
24
+ Refer to :gmt-docs:`datasets/remote-data.html` for more details .
22
25
23
26
Parameters
24
27
----------
25
28
resolution : str
26
29
The grid resolution. The suffix ``d``, ``m`` and ``s`` stand for
27
30
arc-degree, arc-minute and arc-second. It can be ``'01d'``, ``'30m'``,
28
31
``'20m'``, ``'15m'``, ``'10m'``, ``'06m'``, ``'05m'``, ``'04m'``,
29
- ``'03m'``, ``'02m'``, ``'01m'``, ``'30s'`` or ``'15s'``.
32
+ ``'03m'``, ``'02m'``, ``'01m'``, ``'30s'``, ``'15s'``, ``'03s'``,
33
+ or ``'01s'``.
34
+
35
+ region : str or list
36
+ The subregion of the grid to load. Required for Earth relief grids with
37
+ resolutions <= 05m.
30
38
31
39
registration : str
32
40
Grid registration type. Either ``pixel`` for pixel registration or
@@ -40,8 +48,29 @@ def load_earth_relief(resolution="01d", registration=None):
40
48
The Earth relief grid. Coordinates are latitude and longitude in
41
49
degrees. Relief is in meters.
42
50
51
+ Notes
52
+ -----
53
+ The DataArray doesn's support slice operation, for Earth relief data with
54
+ resolutions higher than "05m", which are stored as smaller tiles.
55
+
56
+ Examples
57
+ --------
58
+
59
+ >>> # load the default grid (pixel-registered 01d grid)
60
+ >>> grid = load_earth_relief()
61
+ >>> # load the 30m grid with "gridline" registration
62
+ >>> grid = load_earth_relief("30m", registration="gridline")
63
+ >>> # load high-resolution grid for a specific region
64
+ >>> grid = load_earth_relief(
65
+ ... "05m", region=[120, 160, 30, 60], registration="gridline"
66
+ ... )
67
+
43
68
"""
44
- _is_valid_resolution (resolution )
69
+
70
+ # earth relief data stored as single grids for low resolutions
71
+ non_tiled_resolutions = ["01d" , "30m" , "20m" , "15m" , "10m" , "06m" ]
72
+ # earth relief data stored as tiles for high resolutions
73
+ tiled_resolutions = ["05m" , "04m" , "03m" , "02m" , "01m" , "30s" , "15s" , "03s" , "01s" ]
45
74
46
75
if registration in ("pixel" , "gridline" , None ):
47
76
# If None, let GMT decide on Pixel/Gridline type
@@ -54,8 +83,27 @@ def load_earth_relief(resolution="01d", registration=None):
54
83
"gridline-registered grid is available."
55
84
)
56
85
57
- fname = which (f"@earth_relief_{ resolution } { reg } " , download = "a" )
58
- grid = xr .open_dataarray (fname )
86
+ # different ways to load tiled and non-tiled earth relief data
87
+ if resolution in non_tiled_resolutions :
88
+ if region is not None :
89
+ raise NotImplementedError (
90
+ f"'region' is not supported for Earth relief resolution '{ resolution } '"
91
+ )
92
+ fname = which (f"@earth_relief_{ resolution } { reg } " , download = "a" )
93
+ with xr .open_dataarray (fname ) as dataarray :
94
+ grid = dataarray .load ()
95
+ _ = grid .gmt # load GMTDataArray accessor information
96
+ elif resolution in tiled_resolutions :
97
+ # Titled grid can't be sliced.
98
+ # See https://github.com/GenericMappingTools/pygmt/issues/524
99
+ if region is None :
100
+ raise GMTInvalidInput (
101
+ f"'region' is required for Earth relief resolution '{ resolution } '"
102
+ )
103
+ grid = grdcut (f"@earth_relief_{ resolution } { reg } " , region = region )
104
+ else :
105
+ raise GMTInvalidInput (f'Invalid Earth relief resolution "{ resolution } "' )
106
+
59
107
# Add some metadata to the grid
60
108
grid .name = "elevation"
61
109
grid .attrs ["long_name" ] = "elevation relative to the geoid"
@@ -69,86 +117,3 @@ def load_earth_relief(resolution="01d", registration=None):
69
117
for coord in grid .coords :
70
118
grid [coord ].attrs .pop ("actual_range" )
71
119
return grid
72
-
73
-
74
- def _is_valid_resolution (resolution ):
75
- """
76
- Check if a resolution is valid for the global Earth relief grid.
77
-
78
- Parameters
79
- ----------
80
- resolution : str
81
- Same as the input for load_earth_relief
82
-
83
- Raises
84
- ------
85
- GMTInvalidInput
86
- If given resolution is not valid.
87
-
88
- Examples
89
- --------
90
-
91
- >>> _is_valid_resolution("01d")
92
- >>> _is_valid_resolution("60m")
93
- >>> _is_valid_resolution("5m")
94
- Traceback (most recent call last):
95
- ...
96
- pygmt.exceptions.GMTInvalidInput: Invalid Earth relief resolution '5m'.
97
- >>> _is_valid_resolution("15s")
98
- >>> _is_valid_resolution("01s")
99
- Traceback (most recent call last):
100
- ...
101
- pygmt.exceptions.GMTInvalidInput: Invalid Earth relief resolution '01s'.
102
-
103
- """
104
- valid_resolutions = ["01d" ]
105
- valid_resolutions .extend (
106
- [f"{ res :02d} m" for res in [60 , 30 , 20 , 15 , 10 , 6 , 5 , 4 , 3 , 2 , 1 ]]
107
- )
108
- valid_resolutions .extend ([f"{ res :02d} s" for res in [30 , 15 ]])
109
- if resolution not in valid_resolutions :
110
- raise GMTInvalidInput (
111
- "Invalid Earth relief resolution '{}'." .format (resolution )
112
- )
113
-
114
-
115
- def _shape_from_resolution (resolution ):
116
- """
117
- Calculate the shape of the global Earth relief grid given a resolution.
118
-
119
- Parameters
120
- ----------
121
- resolution : str
122
- Same as the input for load_earth_relief
123
-
124
- Returns
125
- -------
126
- shape : (nlat, nlon)
127
- The calculated shape.
128
-
129
- Examples
130
- --------
131
-
132
- >>> _shape_from_resolution('60m')
133
- (181, 361)
134
- >>> _shape_from_resolution('30m')
135
- (361, 721)
136
- >>> _shape_from_resolution('10m')
137
- (1081, 2161)
138
- >>> _shape_from_resolution('30s')
139
- (21601, 43201)
140
- >>> _shape_from_resolution('15s')
141
- (43201, 86401)
142
-
143
- """
144
- _is_valid_resolution (resolution )
145
- unit = resolution [2 ]
146
- if unit == "d" :
147
- seconds = int (resolution [:2 ]) * 60 * 60
148
- elif unit == "m" :
149
- seconds = int (resolution [:2 ]) * 60
150
- elif unit == "s" :
151
- seconds = int (resolution [:2 ])
152
- nlat = 180 * 60 * 60 // seconds + 1
153
- nlon = 360 * 60 * 60 // seconds + 1
154
- return (nlat , nlon )
0 commit comments