Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions examples/tutorials/basics/coastlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
# 3. island-in-lake shore
# 4. lake-in-island-in-lake shore
#
# You can specify which level you want to plot by passing the level number and
# a GMT pen configuration. For example, to plot just the coastlines with 0.5p
# thickness and black lines:
# You can specify which level you want to plot by passing the level number and a GMT
# pen configuration. For example, to plot just the coastlines with 0.5p thickness and
# black lines:

fig = pygmt.Figure()
fig.basemap(region="g", projection="W15c", frame=True)
Expand All @@ -50,18 +50,14 @@
# Resolutions
# -----------
#
# The coastline database comes with 5 resolutions. The resolution drops by 80%
# between levels:
#
# 1. ``"c"``: crude
# 2. ``"l"``: low (default)
# 3. ``"i"``: intermediate
# 4. ``"h"``: high
# 5. ``"f"``: full
# The coastline database comes with 5 resolutions: ``"full"``, ``"high"``,
# ``"intermediate"``, ``"low"``, and ``"crude"``. The resolution drops by 80% between
# levels. The ``resolution`` parameter defaults to ``"auto"`` to automatically select
# the best resolution given the chosen map scale.

oahu = [-158.3, -157.6, 21.2, 21.8]
fig = pygmt.Figure()
for res in ["c", "l", "i", "h", "f"]:
for res in ["crude", "low", "intermediate", "high", "full"]:
fig.coast(resolution=res, shorelines="1p", region=oahu, projection="M5c")
fig.shift_origin(xshift="5c")
fig.show()
Expand All @@ -71,9 +67,9 @@
# Land and water
# --------------
#
# Use the ``land`` and ``water`` parameters to specify a fill color for land
# and water bodies. The colors can be given by name or hex codes (like the ones
# used in HTML and CSS):
# Use the ``land`` and ``water`` parameters to specify a fill color for land and water
# bodies. The colors can be given by name or hex codes (like the ones used in HTML and
# CSS):

fig = pygmt.Figure()
fig.basemap(region="g", projection="W15c", frame=True)
Expand Down
61 changes: 60 additions & 1 deletion pygmt/src/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"""

from pathlib import Path
from typing import Any
from typing import Any, Literal

from pygmt.exceptions import GMTInvalidInput
from pygmt.src.which import which


Expand Down Expand Up @@ -39,3 +40,61 @@ def _data_geometry_is_point(data: Any, kind: str) -> bool:
except FileNotFoundError:
pass
return False


def _parse_coastline_resolution(
resolution: Literal["auto", "full", "high", "intermediate", "low", "crude", None],
allow_auto: bool = False,
) -> str | None:
"""
Parse the resolution parameter for coastline-related functions.

Parameters
----------
resolution
The resolution of the coastline dataset to use. The available resolutions from
highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, ``"low"``,
and ``"crude"``, which drops by 80% between levels.
allow_auto
Whether to allow the ``"auto"`` resolution.

Returns
-------
The parsed single-letter resolution or ``None``.

Raises
------
GMTInvalidInput
If the resolution is invalid.

Examples
--------
>>> _parse_coastline_resolution("full")
'f'
>>> _parse_coastline_resolution("f")
'f'
>>> _parse_coastline_resolution("auto", allow_auto=True)
'a'
>>> _parse_coastline_resolution(None)
>>> _parse_coastline_resolution("invalid")
Traceback (most recent call last):
...
pygmt.exceptions.GMTInvalidInput: Invalid resolution: 'invalid'. Valid values ...
>>> _parse_coastline_resolution("auto")
Traceback (most recent call last):
...
pygmt.exceptions.GMTInvalidInput: Invalid resolution: 'auto'. Valid values ...
"""
if resolution is None:
return None

valid_resolutions = {"full", "high", "intermediate", "low", "crude"}
if allow_auto:
valid_resolutions.add("auto")
if resolution not in {*valid_resolutions, *[res[0] for res in valid_resolutions]}:
msg = (
f"Invalid resolution: '{resolution}'. "
f"Valid values are {', '.join(valid_resolutions)}."
)
raise GMTInvalidInput(msg)
return resolution[0]
25 changes: 19 additions & 6 deletions pygmt/src/coast.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
coast - Plot land and water.
"""

from typing import Literal

from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import (
Expand All @@ -11,6 +13,7 @@
kwargs_to_strings,
use_alias,
)
from pygmt.src._common import _parse_coastline_resolution

__doctest_skip__ = ["coast"]

Expand All @@ -20,7 +23,6 @@
A="area_thresh",
B="frame",
C="lakes",
D="resolution",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing D="resolution", this alias won't be shown in the alias list. Need to wait for #3945.

E="dcw",
F="box",
G="land",
Expand All @@ -37,7 +39,13 @@
t="transparency",
)
@kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence")
def coast(self, **kwargs):
def coast(
self,
resolution: Literal[
"auto", "full", "high", "intermediate", "low", "crude", None
] = None,
**kwargs,
):
r"""
Plot continents, shorelines, rivers, and borders on maps.

Expand Down Expand Up @@ -73,10 +81,12 @@ def coast(self, **kwargs):
parameter. Optionally, specify separate fills by appending
**+l** for lakes or **+r** for river-lakes, and passing multiple
strings in a list.
resolution : str
**f**\|\ **h**\|\ **i**\|\ **l**\|\ **c**.
Select the resolution of the data set to: (**f**\ )ull, (**h**\ )igh,
(**i**\ )ntermediate, (**l**\ )ow, and (**c**\ )rude.
resolution
Comment thread
seisman marked this conversation as resolved.
Select the resolution of the coastline dataset to use. The available resolutions
from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``,
``"low"``, and ``"crude"``, which drops by 80% between levels. Default is
``"auto"`` to automatically select the most suitable resolution given the chosen
map scale.
land : str
Select filling of "dry" areas.
rivers : int, str, or list
Expand Down Expand Up @@ -199,5 +209,8 @@ def coast(self, **kwargs):
"""At least one of the following parameters must be specified:
lakes, land, water, rivers, borders, dcw, Q, or shorelines"""
)
kwargs["D"] = kwargs.get(
"D", _parse_coastline_resolution(resolution, allow_auto=True)
)
with Session() as lib:
lib.call_module(module="coast", args=build_arg_list(kwargs))
33 changes: 20 additions & 13 deletions pygmt/src/grdlandmask.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
grdlandmask - Create a "wet-dry" mask grid from shoreline data base
"""

from typing import Literal

import xarray as xr
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import build_arg_list, fmt_docstring, kwargs_to_strings, use_alias
from pygmt.src._common import _parse_coastline_resolution

__doctest_skip__ = ["grdlandmask"]


@fmt_docstring
@use_alias(
A="area_thresh",
D="resolution",
E="bordervalues",
I="spacing",
N="maskvalues",
Expand All @@ -23,7 +25,11 @@
x="cores",
)
@kwargs_to_strings(I="sequence", R="sequence", N="sequence", E="sequence")
def grdlandmask(outgrid: str | None = None, **kwargs) -> xr.DataArray | None:
def grdlandmask(
outgrid: str | None = None,
resolution: Literal["full", "high", "intermediate", "low", "crude", None] = None,
**kwargs,
) -> xr.DataArray | None:
r"""
Create a grid file with set values for land and water.

Expand All @@ -44,17 +50,14 @@ def grdlandmask(outgrid: str | None = None, **kwargs) -> xr.DataArray | None:
{spacing}
{region}
{area_thresh}
resolution : str
*res*\[\ **+f**\]. Select the resolution of the data set to use
((**f**)ull, (**h**)igh, (**i**)ntermediate, (**l**)ow, or
(**c**)rude). The resolution drops off by ~80% between data sets.
[Default is **l**]. Append **+f** to automatically select a lower
resolution should the one requested not be available
[abort if not found]. Alternatively, choose (**a**)uto to automatically
select the best resolution given the chosen region. Note that because
the coastlines differ in details a node in a mask file using one
resolution is not guaranteed to remain inside [or outside] when a
different resolution is selected.
resolution
Comment thread
seisman marked this conversation as resolved.
Ignored unless ``mask`` is set. Select the resolution of the coastline dataset
to use. The available resolutions from highest to lowest are: ``"full"``,
``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80%
between levels. Note that because the coastlines differ in details a node in a
mask file using one resolution is not guaranteed to remain inside [or outside]
when a different resolution is selected. If ``None``, the low resolution is used
by default.
bordervalues : bool, str, float, or list
Nodes that fall exactly on a polygon boundary should be
considered to be outside the polygon [Default considers them to be
Expand Down Expand Up @@ -98,6 +101,10 @@ def grdlandmask(outgrid: str | None = None, **kwargs) -> xr.DataArray | None:
if kwargs.get("I") is None or kwargs.get("R") is None:
raise GMTInvalidInput("Both 'region' and 'spacing' must be specified.")

kwargs["D"] = kwargs.get(
"D", _parse_coastline_resolution(resolution, allow_auto=True)
)

with Session() as lib:
with lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd:
kwargs["G"] = voutgrd
Expand Down
22 changes: 11 additions & 11 deletions pygmt/src/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use_alias,
validate_output_table_type,
)
from pygmt.src._common import _parse_coastline_resolution

__doctest_skip__ = ["select"]

Expand All @@ -22,7 +23,6 @@
@use_alias(
A="area_thresh",
C="dist2pt",
D="resolution",
F="polygon",
G="gridmask",
I="reverse",
Expand All @@ -48,6 +48,7 @@ def select(
data=None,
output_type: Literal["pandas", "numpy", "file"] = "pandas",
outfile: str | None = None,
resolution: Literal["full", "high", "intermediate", "low", "crude", None] = None,
**kwargs,
) -> pd.DataFrame | np.ndarray | None:
r"""
Expand Down Expand Up @@ -116,16 +117,13 @@ def select(
<reference/file-formats.html#optional-segment-header-records>`
*polygonfile*. For spherical polygons (lon, lat), make sure no
consecutive points are separated by 180 degrees or more in longitude.
resolution : str
*resolution*\ [**+f**].
Ignored unless ``mask`` is set. Selects the resolution of the coastline
data set to use ((**f**)ull, (**h**)igh, (**i**)ntermediate, (**l**)ow,
or (**c**)rude). The resolution drops off by ~80% between data sets.
[Default is **l**]. Append (**+f**) to automatically select a lower
resolution should the one requested not be available [Default is abort
if not found]. Note that because the coastlines differ in details
it is not guaranteed that a point will remain inside [or outside] when
a different resolution is selected.
resolution
Comment thread
seisman marked this conversation as resolved.
Outdated
Ignored unless ``mask`` is set. Select the resolution of the coastline dataset
to use. The available resolutions from highest to lowest are: ``"full"``,
``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80%
between levels. Note that because the coastlines differ in details it is not
guaranteed that a point will remain inside [or outside] when a different
resolution is selected. If ``None``, the low resolution is used by default.
gridmask : str
Pass all locations that are inside the valid data area of the grid
*gridmask*. Nodes that are outside are either NaN or zero.
Expand Down Expand Up @@ -205,6 +203,8 @@ def select(
>>> # longitudes 246 and 247 and latitudes 20 and 21
>>> out = pygmt.select(data=ship_data, region=[246, 247, 20, 21])
"""
kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution))

output_type = validate_output_table_type(output_type, outfile=outfile)

column_names = None
Expand Down
2 changes: 1 addition & 1 deletion pygmt/tests/test_coast.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_coast_world_mercator():
projection="M15c",
frame="af",
land="#aaaaaa",
resolution="c",
resolution="crude",
water="white",
)
return fig
Expand Down