Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 8 additions & 7 deletions doc/rst/source/grdfill.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Synopsis
[ |-A|\ *mode*\ [*arg*] ]
[ |-G|\ *outgrid* ]
[ |-L|\ [**p**] ]
[ |-N|\ *value* ]
[ |SYN_OPT-R| ]
[ |SYN_OPT-V| ]
[ |SYN_OPT-f| ]
Expand All @@ -28,8 +29,8 @@ Description

**grdfill** reads a grid that presumably has unfilled holes that the user
wants to fill in some fashion. Holes are identified by NaN values but
this criteria can be changed. There are several different algorithms that
can be used to replace the hole values. One of **-A** or **-L** is required.
this criteria can be changed via **-N**. There are several different algorithms that
can be used to replace the hole values. **Note**: One of **-A** or **-L** is required.

Required Arguments
------------------
Expand All @@ -43,11 +44,11 @@ Optional Arguments
.. _-A:

**-A**\ *mode*\ [*arg*]
Specify the hole-filling algorithm to use. Choose from **c** for constant
fill and append the constant value, **n** for nearest neighbor (and optionally
append a search radius in pixels [default radius is :math:`r^2 = \sqrt{X^2 + Y^2}`,
Specify the hole-filling algorithm to use. Choose among **c** for constant
fill (and append the constant fill *value*), **n** for nearest neighbor (and optionally
append a search *radius* in pixels [default radius is :math:`r^2 = \sqrt{X^2 + Y^2}`,
where (*X,Y*) are the node dimensions of the grid]), or
*s** for bicubic spline [NOT IMPLEMENTED YET].
*s** for bicubic spline (optionally append a *tension* parameter [no tension]).

.. _-G:

Expand All @@ -57,7 +58,7 @@ Optional Arguments
.. _-N:

**-N**\ [*nodata*]
Sets the node value that identifies a point as a member of a hole [Default is NaN].
Sets the node value used to identify a point as a member of a hole [Default is NaN].

.. |Add_-R| replace:: This defines the subregion to be cut out. |Add_-R_links|
.. include:: explain_-R.rst_
Expand Down
26 changes: 25 additions & 1 deletion src/grdfill.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ struct GRDFILL_CTRL {
bool active;
unsigned int mode; /* 0 = region, 1 = polygons */
} L;
struct GRDFILL_N { /* -N<value> */
bool active;
float value;
} N;
};

static void *New_Ctrl (struct GMT_CTRL *GMT) { /* Allocate and initialize a new control structure */
Expand All @@ -80,7 +84,7 @@ static void Free_Ctrl (struct GMT_CTRL *GMT, struct GRDFILL_CTRL *C) { /* Deallo
static int usage (struct GMTAPI_CTRL *API, int level) {
const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE);
if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR);
GMT_Message (API, GMT_TIME_NONE, "usage: %s <ingrid> [-A<mode><options>] [-G<outgrid>] [-L[p]]\n\t[%s] [%s] [%s] [%s]\n\n",
GMT_Message (API, GMT_TIME_NONE, "usage: %s <ingrid> [-A<mode><options>] [-G<outgrid>] [-L[p]] [-N<val>\n\t[%s] [%s] [%s] [%s]\n\n",
name, GMT_Rgeo_OPT, GMT_V_OPT, GMT_f_OPT, GMT_PAR_OPT);

if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS);
Expand All @@ -97,6 +101,7 @@ static int usage (struct GMTAPI_CTRL *API, int level) {
GMT_Message (API, GMT_TIME_NONE, "\t-L Just list the subregions w/e/s/n of each hole.\n");
GMT_Message (API, GMT_TIME_NONE, "\t No grid fill takes place and -G is ignored.\n");
GMT_Message (API, GMT_TIME_NONE, "\t Append p to write polygons corresponding to these regions.\n");
GMT_Message (API, GMT_TIME_NONE, "\t-N Set alternate node value to indicate a hole [Default are NaN-nodes].\n");
GMT_Option (API, "R,V,f,.");

return (GMT_MODULE_USAGE);
Expand Down Expand Up @@ -169,6 +174,16 @@ static int parse (struct GMT_CTRL *GMT, struct GRDFILL_CTRL *Ctrl, struct GMT_OP
Ctrl->L.mode = 1;
break;

case 'N':
Ctrl->N.active = true;
if (opt->arg[0] && !strchr ("Nn", opt->arg[0]))
Ctrl->N.value = (float) atof (opt->arg);
else {
GMT_Report (API, GMT_MSG_ERROR, "Option -N: No value (or NaN) given\n");
n_errors++;
}
break;

default: /* Report bad options */
n_errors += gmt_default_error (GMT, opt->option);
break;
Expand All @@ -178,6 +193,7 @@ static int parse (struct GMT_CTRL *GMT, struct GRDFILL_CTRL *Ctrl, struct GMT_OP
n_errors += gmt_M_check_condition (GMT, !Ctrl->In.file, "Must specify input grid file\n");
n_errors += gmt_M_check_condition (GMT, !(Ctrl->A.active || Ctrl->L.active), "Must specify an algorithm with -A unless -L is used\n");
n_errors += gmt_M_check_condition (GMT, !(Ctrl->L.active || Ctrl->G.file), "Must specify output grid file\n");
n_errors += gmt_M_check_condition (GMT, !(Ctrl->A.active || Ctrl->L.active), "Must specify either -A or -L\n");

return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR);
}
Expand Down Expand Up @@ -522,6 +538,14 @@ EXTERN_MSC int GMT_grdfill (void *V_API, int mode, void *args) {
Return (API->error); /* Get all */
}

if (Ctrl->N.active) { /* User wants a specific value to indicate a hole instead of NaN; replace those values with NaNs since that is what is expected below */
gmt_M_grd_loop (GMT, Grid, row, col, node) { /* Loop over all grid nodes */
if (floatAlmostEqualZero (Grid->data[node], Ctrl->N.value))
Grid->data[node] = GMT->session.f_NaN;
}
}
/* Here any hole is identified as a patch of NaNs */

if (Ctrl->A.mode == ALG_NN) { /* Do Eric Xu's NN algorithm and bail */
int64_t radius = lrint (Ctrl->A.value);
struct GMT_GRID *New = NULL;
Expand Down