From a9c8bcf9542e097473301798e1bec7dd614e0952 Mon Sep 17 00:00:00 2001 From: Esteban82 Date: Thu, 25 Jun 2026 16:29:02 -0300 Subject: [PATCH] Update files --- doc/rst/source/explain_symbols.rst_ | 21 ++++++++++++++++ src/gmt_init.c | 20 +++++++++++++++- src/gmt_plot.h | 2 ++ src/psxy.c | 37 +++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/doc/rst/source/explain_symbols.rst_ b/doc/rst/source/explain_symbols.rst_ index 0c3b4d36879..89d0eb2b467 100644 --- a/doc/rst/source/explain_symbols.rst_ +++ b/doc/rst/source/explain_symbols.rst_ @@ -256,6 +256,27 @@ Multi-band bars require |-C| with one color per band (CPT z-values must be 0, 1, ..., *nx* - 1). Thus, input records are either (*x1 y x2 ... xn*) or (*dx1 y dx2 ... dxn*). + .. rubric:: Infinite Lines + + The next type of symbol draws an infinite straight line through a single coordinate, + spanning the entire map frame in either the vertical or horizontal direction: + + **-SY**\ [*size*] + Infinite vertical line through *x*. Only the *x*-coordinate is read from the + input (no *y* column is required); the line is drawn from the bottom to the + top of the map frame at that *x* position. The optional *size* sets the pen + width if not controlled via |-W|. **Note**: Not supported with geographic + coordinates or a polar (**-Jp**\|\ **P**) projection, since "vertical" has + no consistent meaning under those projections. + + **-SX**\ [*size*] + Infinite horizontal line through *y*. Only the *y*-coordinate is read from the + input (no *x* column is required); the line is drawn from the left to the + right of the map frame at that *y* position. The optional *size* sets the pen + width if not controlled via |-W|. **Note**: Not supported with geographic + coordinates or a polar (**-Jp**\|\ **P**) projection, since "horizontal" has + no consistent meaning under those projections. + .. rubric:: Vectors The next family of symbols are all different types of *vectors*. Apart from requiring parameters diff --git a/src/gmt_init.c b/src/gmt_init.c index f78022483e5..c25d4b9e162 100644 --- a/src/gmt_init.c +++ b/src/gmt_init.c @@ -17250,7 +17250,7 @@ int gmt_parse_symbol_option (struct GMT_CTRL *GMT, char *text, struct GMT_SYMBOL unsigned int ju, col; char symbol_type, txt_a[GMT_LEN256] = {""}, txt_b[GMT_LEN256] = {""}, txt_c[GMT_LEN256] = {""}, txt_d[GMT_LEN256] = {""}; char text_cp[GMT_LEN256] = {""}, diameter[GMT_LEN32] = {""}, *c = NULL; - static char *allowed_symbols[2] = {"~=-+AaBbCcDdEefGgHhIiJjMmNnpPqRrSsTtVvWwxy", "=-+AabCcDdEefGgHhIiJjMmNnOopPqRrSsTtUuVvWwxy"}; + static char *allowed_symbols[2] = {"~=-+AaBbCcDdEefGgHhIiJjMmNnpPqRrSsTtVvWwXxYy", "=-+AabCcDdEefGgHhIiJjMmNnOopPqRrSsTtUuVvWwxy"}; static char *bar_symbols[2] = {"Bb", "-BbOoUu"}; if (cmd) { p->base = GMT->session.d_NaN; @@ -17413,6 +17413,16 @@ int gmt_parse_symbol_option (struct GMT_CTRL *GMT, char *text, struct GMT_SYMBOL p->size_x = p->given_size_x = gmt_M_to_inch (GMT, arg), check = false; } } + else if (text[0] == 'X') { /* Infinite horizontal line: -SX, no size or extra column involved */ + symbol_type = 'X'; + p->size_x = p->size_y = p->given_size_x = p->given_size_y = 0.0; + check = false; + } + else if (text[0] == 'Y') { /* Infinite vertical line: -SY, no size or extra column involved */ + symbol_type = 'Y'; + p->size_x = p->size_y = p->given_size_x = p->given_size_y = 0.0; + check = false; /* This symbol never reads a size from file or command line */ + } else if (strchr (allowed_symbols[mode], (int) text[0]) && text[1] && strchr (GMT_DIM_UNITS, (int) text[1])) { /* Symbol, but no size given (size assumed given on command line), only unit information */ sscanf (text, "%c", &symbol_type); @@ -18208,9 +18218,17 @@ int gmt_parse_symbol_option (struct GMT_CTRL *GMT, char *text, struct GMT_SYMBOL case '+': p->symbol = PSL_PLUS; break; + case 'X': + p->symbol = GMT_SYMBOL_HLINE; /* Infinite horizontal line at given x value; only needs one coordinate */ + p->n_required = 0; + break; case 'x': p->symbol = PSL_CROSS; break; + case 'Y': + p->symbol = GMT_SYMBOL_VLINE; /* Infinite vertical line at given y value; only needs one coordinate */ + p->n_required = 0; + break; case 'y': p->symbol = PSL_YDASH; break; diff --git a/src/gmt_plot.h b/src/gmt_plot.h index 33ea45fd5e4..e095653bc92 100644 --- a/src/gmt_plot.h +++ b/src/gmt_plot.h @@ -39,6 +39,8 @@ #define GMT_SYMBOL_COLUMN ((int)'o') #define GMT_SYMBOL_QUOTED_LINE ((int)'q') #define GMT_SYMBOL_CUBE ((int)'u') +#define GMT_SYMBOL_HLINE ((int)'X') +#define GMT_SYMBOL_VLINE ((int)'Y') #define GMT_SYMBOL_ZDASH ((int)'z') #define GMT_SYMBOL_DECORATED_LINE ((int)'~') #define GMT_SYMBOL_VECTOR_V4 999 diff --git a/src/psxy.c b/src/psxy.c index 24f771c3ecb..5741f252107 100644 --- a/src/psxy.c +++ b/src/psxy.c @@ -631,7 +631,14 @@ static int usage (struct GMTAPI_CTRL *API, int level) { "[Note: if -C is selected then 3rd means 4th column, etc.]. " "Symbols A, C, D, G, H, I, N, S, T are adjusted to have same area " "as a circle of the specified diameter."); - + GMT_Usage (API, 2, "\n%s Horizontal line: -SX", GMT_LINE_BULLET); + GMT_Usage (API, -3, "Draw a horizontal line across the entire Cartesian plot at the specified y coordinate. " + "If no fixed coordinate is given, the y value is read from the first input column. " + "Not supported with geographic or polar coordinates."); + GMT_Usage (API, 2, "\n%s Vertical line: -SY", GMT_LINE_BULLET); + GMT_Usage (API, -3, "Draw a vertical line across the entire Cartesian plot at the specified x coordinate. " + "If no fixed coordinate is given, the x value is read from the first input column. " + "Not supported with geographic or polar coordinates."); GMT_Usage (API, 2, "\n%s Bar: -Sb|B[[c|i|p|q]][+b|B[]][+v|i][+s[]]", GMT_LINE_BULLET); GMT_Usage (API, -3, "Place horizontal or vertical bars. Use upper case -SB for horizontal bars " "( then refers to x and width may be in y-units) [Default is vertical]. Append size " @@ -1263,6 +1270,15 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) { nominal_pen = Ctrl->W.pen; /* Do we plot actual symbols, or lines */ not_line = !(S.symbol == GMT_SYMBOL_FRONT || S.symbol == GMT_SYMBOL_QUOTED_LINE || S.symbol == GMT_SYMBOL_DECORATED_LINE || S.symbol == GMT_SYMBOL_LINE); + if (S.symbol == GMT_SYMBOL_VLINE || S.symbol == GMT_SYMBOL_HLINE) { /* Infinite vertical/horizontal line only needs one coordinate */ + n_cols_start = 1; + if (gmt_M_is_geographic (GMT, GMT_IN) || GMT->current.proj.projection == GMT_POLAR) { + GMT_Report (API, GMT_MSG_ERROR, "Symbol -S%c is not yet supported with geographic or polar coordinates yet.\n", + (S.symbol == GMT_SYMBOL_VLINE) ? 'Y' : 'X'); + Return (GMT_RUNTIME_ERROR); + } + } + if (Ctrl->E.active) { /* Set error bar parameters */ j = 2; /* Normally, error bar related columns start in column 2 */ if (Ctrl->E.xbar != EBAR_NONE) { xy_errors[GMT_X] = j; j += error_cols[Ctrl->E.xbar]; error_type[GMT_X] = Ctrl->E.xbar;} @@ -1796,7 +1812,7 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) { gmt_illuminate (GMT, in[icol], current_fill.rgb); } - if (!Ctrl->N.active && !Ctrl->E.active && S.symbol != GMT_SYMBOL_BARX && S.symbol != GMT_SYMBOL_BARY) { + if (!Ctrl->N.active && !Ctrl->E.active && S.symbol != GMT_SYMBOL_BARX && S.symbol != GMT_SYMBOL_BARY && S.symbol != GMT_SYMBOL_VLINE && S.symbol != GMT_SYMBOL_HLINE) { /* Skip points outside map */ gmt_map_outside (GMT, in[GMT_X], in[GMT_Y]); may_intrude_inside = false; @@ -1830,6 +1846,13 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) { } outline_setting = 1; } + if (S.symbol == GMT_SYMBOL_VLINE) { /* in[GMT_X] holds the line's x; Y is not read from file, use a safe mid-range value for the generic geo_to_xy check below */ + in[GMT_Y] = 0.5 * (GMT->common.R.wesn[YLO] + GMT->common.R.wesn[YHI]); + } + else if (S.symbol == GMT_SYMBOL_HLINE) { /* in[GMT_X] actually holds the line's y; use a safe mid-range x for the generic geo_to_xy check below */ + in[GMT_Y] = in[GMT_X]; + in[GMT_X] = 0.5 * (GMT->common.R.wesn[XLO] + GMT->common.R.wesn[XHI]); + } if (gmt_geo_to_xy (GMT, in[GMT_X], in[GMT_Y], &plot_x, &plot_y)) continue; /* NaNs on input */ if (gmt_M_is_dnan (plot_x)) { /* Transformation of x yielded a NaN (e.g. log (-ve)) */ @@ -2052,6 +2075,16 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) { } } break; + case GMT_SYMBOL_HLINE: + gmt_geo_to_xy (GMT, GMT->common.R.wesn[XLO], in[GMT_Y], &x_1, &y_1); + gmt_geo_to_xy (GMT, GMT->common.R.wesn[XHI], in[GMT_Y], &x_2, &y_2); + PSL_plotsegment (PSL, x_1, y_1, x_2, y_2); + break; + case GMT_SYMBOL_VLINE: + gmt_geo_to_xy (GMT, in[GMT_X], GMT->common.R.wesn[YLO], &x_1, &y_1); + gmt_geo_to_xy (GMT, in[GMT_X], GMT->common.R.wesn[YHI], &x_2, &y_2); + PSL_plotsegment (PSL, x_1, y_1, x_2, y_2); + break; case PSL_CROSS: case PSL_PLUS: case PSL_DOT: