-
Notifications
You must be signed in to change notification settings - Fork 244
Wrap grdmask for creating mask grid from polygons or point coverage #4463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dd3abe1
67da3c5
caedc1a
44d969c
fdee109
7f0ddff
68123cf
e70ca8c
1b0e057
7a166e9
da0cc55
d9b3478
6302abe
1d6d753
d4293de
a0ded64
871bcff
a0519e6
7d98d67
ad23794
8e2a998
21b543d
115733d
68e654f
53b3346
8e9a3b6
2a19936
09bf961
813b8e2
1eb9667
a1ba800
05e9635
f9a87fe
b63a8de
4bafead
e65774a
ee32aca
8851b91
fe5348e
7919391
6c74bb0
38a814e
210e92d
b548821
5c818d6
5990c16
35ab3cc
7486ef9
223b0bc
3949572
02ef75d
223e71c
596f7a6
3b576f8
64432b2
efb23e3
7a165da
f344dab
2253679
b4eb6f9
403a200
6fb81cf
fe2a546
df24648
5ace7d1
151b3a8
682d72c
cff6ad8
1bd98ac
64c8918
cef981e
3dec2b5
7f65f39
32dff85
edaa9c5
cb4e285
1820b94
3138c37
be4f6ba
a260fe2
13263c6
d9df4f6
02c515f
503b79b
19c26c4
34b4398
c0c4c35
d094b2c
dd8dab9
f25b14e
7caf9f1
1d7f40b
f8c6388
83e05f4
5b09e87
9b6a852
5b07849
8896beb
6cb7a73
5f5ad7a
cf2e70b
de4ded9
2e1db9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -126,6 +126,7 @@ Operations on tabular data | |
| blockmedian | ||
| blockmode | ||
| filter1d | ||
| grdmask | ||
| nearneighbor | ||
| project | ||
| select | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,7 @@ | |
| grdhisteq, | ||
| grdinfo, | ||
| grdlandmask, | ||
| grdmask, | ||
| grdpaste, | ||
| grdproject, | ||
| grdsample, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,229 @@ | ||
| """ | ||
| grdmask - Create mask grid from polygons or point coverage. | ||
| """ | ||
|
|
||
| from collections.abc import Sequence | ||
| from typing import Literal | ||
|
|
||
| import xarray as xr | ||
| from pygmt._typing import PathLike | ||
| from pygmt.alias import Alias, AliasSystem | ||
| from pygmt.clib import Session | ||
| from pygmt.exceptions import GMTParameterError, GMTValueError | ||
| from pygmt.helpers import build_arg_list, fmt_docstring | ||
|
|
||
| __doctest_skip__ = ["grdmask"] | ||
|
|
||
|
|
||
| def _alias_option_N( # noqa: N802 | ||
| outside: float | None = None, | ||
| edge: float | Literal["z", "id"] | None = None, | ||
| inside: float | Literal["z", "id"] | None = None, | ||
| id_start: float | None = None, | ||
| ) -> Alias: | ||
| """ | ||
| Return an Alias object for the -N option. | ||
|
|
||
| Builds the -N parameter string for grdmask based on the inside, edge, and outside | ||
| values. Handles special modes "z" (use z-value from polygon data) and "id" (use | ||
| running polygon ID). | ||
|
|
||
| Examples | ||
| -------- | ||
| >>> def parse(**kwargs): | ||
| ... return AliasSystem(N=_alias_option_N(**kwargs)).get("N") | ||
| >>> parse() | ||
| >>> parse(outside=1, edge=2, inside=3) | ||
| '1/2/3' | ||
| >>> parse(outside=3) | ||
| '3/0/1' | ||
| >>> parse(inside="z") | ||
| 'z' | ||
| >>> parse(outside=1, inside="z") | ||
| 'z/1' | ||
| >>> parse(edge="z", inside="z") | ||
| 'Z' | ||
| >>> parse(inside="id") | ||
| 'p' | ||
| >>> parse(edge="id", inside="id") | ||
| 'P' | ||
| >>> parse(inside="id", id_start=5) | ||
| 'p5' | ||
| >>> parse(edge="id", inside="id", id_start=10) | ||
| 'P10' | ||
Chuan1937 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| >>> parse(edge="id", inside="id", id_start=5, outside=3) | ||
| 'P5/3' | ||
| >>> parse(edge="id", id_start=5, outside=3) | ||
| Traceback (most recent call last): | ||
| ... | ||
| pygmt.exceptions.GMTValueError: ... | ||
| >>> parse(edge="z") | ||
| Traceback (most recent call last): | ||
| ... | ||
| pygmt.exceptions.GMTValueError: ... | ||
| >>> parse(inside="z", edge="id") | ||
| Traceback (most recent call last): | ||
| ... | ||
| pygmt.exceptions.GMTValueError: ... | ||
| >>> parse(inside="z", id_start=5) | ||
| Traceback (most recent call last): | ||
| ... | ||
| pygmt.exceptions.GMTValueError: ... | ||
| """ | ||
| _inside_modes = {"z": "z", "id": "p"} | ||
|
|
||
| if id_start is not None and inside != "id": | ||
| raise GMTValueError( | ||
| inside, | ||
| description="value for parameter 'inside'", | ||
| reason="Parameter 'id_start' requires inside='id'.", | ||
| ) | ||
Chuan1937 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # In the special modes, 'edge' must be None or the same as 'inside' | ||
| if (edge in _inside_modes or inside in _inside_modes) and edge not in { | ||
| None, | ||
| inside, | ||
| }: | ||
Chuan1937 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| raise GMTValueError( | ||
| edge, | ||
| description="edge", | ||
| reason=f"inside={inside!r} and edge={edge!r} must be the same.", | ||
| ) | ||
|
|
||
| # outside/edge/inside are all omitted: keep GMT default 0/0/1 | ||
| if all(v is None for v in (outside, inside, edge)): | ||
| return Alias(None, name="mask_values") | ||
| # Build -N argument | ||
| if inside in _inside_modes: # Mode: -Nz, -NZ, -Np, or -NP | ||
| mode = "z" if inside == "z" else "p" | ||
| if edge == inside: | ||
| mode = mode.upper() | ||
| # Append id_start if specified (only valid for "id" mode) | ||
| if id_start: | ||
| mode = f"{mode}{id_start}" | ||
| mask_values = mode if outside is None else [mode, outside] | ||
| else: # Build the full mask with defaults for any missing values. | ||
| mask_values = [ | ||
| 0 if outside is None else outside, | ||
| 0 if edge is None else edge, | ||
| 1 if inside is None else inside, | ||
| ] | ||
| return Alias(mask_values, name="mask_values", sep="/", size=(2, 3)) | ||
|
|
||
seisman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @fmt_docstring | ||
| def grdmask( | ||
| data, | ||
| outgrid: PathLike | None = None, | ||
| spacing: Sequence[float | str] | None = None, | ||
| region: Sequence[float | str] | str | None = None, | ||
| outside: float | None = None, | ||
| edge: float | Literal["z", "id"] | None = None, | ||
| inside: float | Literal["z", "id"] | None = None, | ||
Chuan1937 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| id_start: float | None = None, | ||
| verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] | ||
| | bool = False, | ||
| **kwargs, | ||
| ) -> xr.DataArray | None: | ||
| """ | ||
| Create mask grid from polygons or point coverage. | ||
|
|
||
| Reads one or more files containing polygon or data point coordinates, and creates a | ||
| grid where nodes that fall inside, on the edge, or outside the polygons (or within | ||
| the search radius from data points) are assigned values based on the ``outside``, | ||
| ``edge``, and ``inside`` parameters. | ||
seisman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The mask grid can be used to mask out specific regions in other grids using | ||
| :func:`pygmt.grdmath` or similar tools. For masking based on coastline features, | ||
| consider using :func:`pygmt.grdlandmask` instead. | ||
|
Comment on lines
+136
to
+138
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So far
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, please fix it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #4524 |
||
|
|
||
| Full GMT docs at :gmt-docs:`grdmask.html`. | ||
|
|
||
| **Aliases** | ||
|
|
||
| .. hlist:: | ||
| :columns: 3 | ||
|
|
||
| - G = outgrid | ||
| - I = spacing | ||
| - N = outside, edge, inside, id_start | ||
| - R = region | ||
| - V = verbose | ||
|
|
||
| Parameters | ||
| ---------- | ||
| data | ||
| Pass in either a file name to an ASCII data table, a 2-D $table_classes | ||
| containing the polygon(s) or data points. Input can be: | ||
|
|
||
| - **Polygon mode**: One or more files containing closed polygon coordinates | ||
| - **Point coverage mode**: Data points (used with ``search_radius`` parameter) | ||
Chuan1937 marked this conversation as resolved.
Show resolved
Hide resolved
yvonnefroehlich marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| $outgrid | ||
| $spacing | ||
| outside | ||
| edge | ||
| inside | ||
| Set the value assigned to nodes outside, on the edge, or inside the polygons. | ||
| Can be any number, or one of ``None``, ``"NaN"``, and ``np.nan`` for NaN. | ||
|
|
||
| ``inside`` and ``edge`` can also be set to one of the following values: | ||
|
|
||
| - ``"z"``: Use the z-value from polygon data (segment header ``-Zzval``, | ||
| ``-Lheader``, or via ``-aZ=name``). | ||
| - ``"id"``: Use a running polygon ID number. | ||
|
|
||
| To treat edges as inside, use the same value as ``inside``. | ||
| id_start | ||
| The starting number for polygon IDs when ``inside="id"`` [Default is ``0``]. | ||
| Only valid when ``inside="id"``. | ||
| $region | ||
| $verbose | ||
|
|
||
| Returns | ||
| ------- | ||
| ret | ||
| Return type depends on whether the ``outgrid`` parameter is set: | ||
|
|
||
| - :class:`xarray.DataArray` if ``outgrid`` is not set | ||
| - ``None`` if ``outgrid`` is set (grid output will be stored in the file set by | ||
| ``outgrid``) | ||
|
|
||
| Example | ||
| ------- | ||
| >>> import pygmt | ||
| >>> import numpy as np | ||
| >>> # Create a simple polygon as a triangle | ||
| >>> polygon = np.array([[125, 30], [130, 30], [130, 35], [125, 30]]) | ||
| >>> # Create a mask grid with 1 arc-degree spacing | ||
| >>> mask = pygmt.grdmask(data=polygon, spacing=1, region=[125, 130, 30, 35]) | ||
| >>> mask.values | ||
| array([[0., 0., 0., 0., 0., 0.], | ||
| [0., 0., 1., 1., 1., 0.], | ||
| [0., 0., 0., 1., 1., 0.], | ||
| [0., 0., 0., 0., 1., 0.], | ||
| [0., 0., 0., 0., 0., 0.], | ||
| [0., 0., 0., 0., 0., 0.]], dtype=float32) | ||
| """ | ||
| if kwargs.get("I", spacing) is None or kwargs.get("R", region) is None: | ||
| raise GMTParameterError(required=["region", "spacing"]) | ||
|
|
||
| aliasdict = AliasSystem( | ||
| I=Alias(spacing, name="spacing", sep="/", size=2), | ||
| N=_alias_option_N(outside=outside, edge=edge, inside=inside, id_start=id_start), | ||
| ).add_common( | ||
| R=region, | ||
| V=verbose, | ||
| ) | ||
| aliasdict.merge(kwargs) | ||
|
|
||
| with Session() as lib: | ||
| with ( | ||
| lib.virtualfile_in(check_kind="vector", data=data) as vintbl, | ||
| lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd, | ||
| ): | ||
| aliasdict["G"] = voutgrd | ||
| lib.call_module( | ||
| module="grdmask", | ||
| args=build_arg_list(aliasdict, infile=vintbl), | ||
| ) | ||
| return lib.virtualfile_to_raster(vfname=voutgrd, outgrid=outgrid) | ||
Uh oh!
There was an error while loading. Please reload this page.