From 013b07a905e9fadbec1d796f8fd96ff8c99b5bf9 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Wed, 19 Jul 2023 11:54:56 +0200 Subject: [PATCH] WIP allow leading zeros in degree annotations See #5153. --- src/gmt_io.c | 48 ++++++++++++++++++++++++++++++----------------- src/gmt_io.h | 1 + src/gmt_support.c | 17 +++++++++++------ 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/gmt_io.c b/src/gmt_io.c index 551ffd1281f..db43c2bdb8c 100644 --- a/src/gmt_io.c +++ b/src/gmt_io.c @@ -2172,6 +2172,7 @@ GMT_LOCAL int gmtio_get_dms_order (struct GMT_CTRL *GMT, char *text, struct GMT_ S->decimal = S->no_sign = false; S->wesn = 0; +fprintf (stderr, "Xtring = %s\n", text); i1 = strlen (text) - 1; for (i = order = 0; i <= i1; i++) { switch (text[i]) { @@ -2184,10 +2185,19 @@ GMT_LOCAL int gmtio_get_dms_order (struct GMT_CTRL *GMT, char *text, struct GMT_ if (i != 0) error++; /* Only valid as first flag */ break; case 'D': /* Want to use decimal degrees using FORMAT_FLOAT_OUT [Default] */ - S->decimal = true; - if (i > 1) error++; /* Only valid as first or second flag */ + if (S->order[0] < 0) /* First time we encounter a D */ + S->order[0] = order++; + else if (text[i-1] != 'D') /* Done it before, previous char must be D */ + error++; n_DD++; break; + case 'd': /* Degree */ + if (S->order[0] < 0) /* First time we encounter a d */ + S->order[0] = order++; + else if (text[i-1] != 'd') /* Done it before, previous char must be d */ + error++; + n_d++; + break; case 'F': /* Want to use WESN to encode sign */ S->wesn = (i == 0) ? -1 : 1; if (S->no_sign) error++; /* Cannot mix A and F */ @@ -2202,13 +2212,6 @@ GMT_LOCAL int gmtio_get_dms_order (struct GMT_CTRL *GMT, char *text, struct GMT_ S->no_sign = true; if (i != i1 || S->wesn) error++; /* Only valid as last flag */ break; - case 'd': /* Degree */ - if (S->order[0] < 0) /* First time we encounter a d */ - S->order[0] = order++; - else if (text[i-1] != 'd') /* Done it before, previous char must be y */ - error++; - n_d++; - break; case 'm': /* Minute */ if (S->order[1] < 0) /* First time we encounter a m */ S->order[1] = order++; @@ -2249,6 +2252,14 @@ GMT_LOCAL int gmtio_get_dms_order (struct GMT_CTRL *GMT, char *text, struct GMT_ } } + if (n_DD > 1) { /* Leading zeros flag */ + S->leading_zeros = true; + n_d = 3; + } + else + S->decimal = true; +fprintf (stderr, "n_DD = %d n_d = %d\n", n_DD, n_d); + if (S->decimal) return (GMT_NOERROR); /* Easy formatting choice */ /* Then get the actual order by inverting table */ @@ -2271,7 +2282,6 @@ GMT_LOCAL int gmtio_get_dms_order (struct GMT_CTRL *GMT, char *text, struct GMT_ error += (n_x && n_dec != 1); /* .xxx is the proper form */ error += (n_x == 0 && n_dec); /* Period by itself and not delimiter? */ error += (n_dec > 1); /* Only one period with xxx */ - error += (n_DD > 1); /* Only one occurrence of D */ error += ((n_F > 1) || (n_G > 1)); /* Only one occurrence of F or G */ error += ((n_G + n_F) > 1); /* Only one of either F or G */ S->n_sec_decimals = n_x; @@ -7067,8 +7077,9 @@ int gmtlib_geo_C_format (struct GMT_CTRL *GMT) { /*! . */ int gmtlib_plot_C_format (struct GMT_CTRL *GMT) { - unsigned int i, j, length; + unsigned int i, j, length, id = 0; struct GMT_GEO_IO *S = &GMT->current.plot.calclock.geo; + char *d_fmt[2] = {"%d", "%3.3d"}; /* Determine the plot geographic location formats. */ @@ -7078,6 +7089,9 @@ int gmtlib_plot_C_format (struct GMT_CTRL *GMT) { if (gmtio_get_dms_order (GMT, GMT->current.setting.format_geo_map, S)) return GMT_PARSE_ERROR; /* Get the order of degree, min, sec in output formats */ + id = (S->leading_zeros) ? 1 : 0; + fprintf (stderr, "Leading = %d\n", id); + if (S->decimal) { /* Plain decimal degrees */ int len; /* Here we depend on FORMAT_FLOAT_OUT being set. This will not be true when FORMAT_GEO_MAP is parsed but will be @@ -7100,13 +7114,13 @@ int gmtlib_plot_C_format (struct GMT_CTRL *GMT) { /* Level 0: degrees only. index 0 is integer degrees, index 1 is [possibly] fractional degrees */ - strcat (GMT->current.plot.format[0][0], "%d"); /* ddd */ + strcat (GMT->current.plot.format[0][0], d_fmt[id]); /* ddd */ if (S->order[1] == GMT_NOTSET && S->n_sec_decimals > 0) { /* ddd.xxx format */ snprintf (fmt, GMT_LEN256, "%%d.%%%d.%dd", S->n_sec_decimals, S->n_sec_decimals); strcat (GMT->current.plot.format[0][1], fmt); } else /* ddd format */ - strcat (GMT->current.plot.format[0][1], "%d"); /* ddd */ + strcat (GMT->current.plot.format[0][1], d_fmt[id]); /* ddd */ if (GMT->current.setting.map_degree_symbol != gmt_none) { /* But we want the degree symbol appended */ snprintf (fmt, GMT_LEN256, "%c", (int)GMT->current.setting.ps_encoding.code[GMT->current.setting.map_degree_symbol]); @@ -7116,8 +7130,8 @@ int gmtlib_plot_C_format (struct GMT_CTRL *GMT) { /* Level 1: degrees and minutes only. index 0 is integer minutes, index 1 is [possibly] fractional minutes */ - strcat (GMT->current.plot.format[1][0], "%d"); /* ddd */ - strcat (GMT->current.plot.format[1][1], "%d"); + strcat (GMT->current.plot.format[1][0], d_fmt[id]); /* ddd */ + strcat (GMT->current.plot.format[1][1], d_fmt[id]); if (GMT->current.setting.map_degree_symbol != gmt_none) { /* We want the degree symbol appended */ sprintf (fmt, "%c", (int)GMT->current.setting.ps_encoding.code[GMT->current.setting.map_degree_symbol]); @@ -7142,8 +7156,8 @@ int gmtlib_plot_C_format (struct GMT_CTRL *GMT) { /* Level 2: degrees, minutes, and seconds. index 0 is integer seconds, index 1 is [possibly] fractional seconds */ - strcat (GMT->current.plot.format[2][0], "%d"); - strcat (GMT->current.plot.format[2][1], "%d"); + strcat (GMT->current.plot.format[2][0], d_fmt[id]); + strcat (GMT->current.plot.format[2][1], d_fmt[id]); if (GMT->current.setting.map_degree_symbol != gmt_none) { /* We want the degree symbol appended */ sprintf (fmt, "%c", (int)GMT->current.setting.ps_encoding.code[GMT->current.setting.map_degree_symbol]); diff --git a/src/gmt_io.h b/src/gmt_io.h index 5e78522a6ca..bf3c8bc497b 100644 --- a/src/gmt_io.h +++ b/src/gmt_io.h @@ -202,6 +202,7 @@ struct GMT_GEO_IO { /* For geographic output and plotting */ int order[3]; /* The relative order of degree, minute, seconds in form (-ve if unused) */ bool decimal; /* true if we want to use the FORMAT_FLOAT_OUT for decimal degrees only */ bool no_sign; /* true if we want absolute values (plot only) */ + bool leading_zeros; /* True to get leading zeros in degrees */ char x_format[GMT_LEN64]; /* Actual C format used to plot/output longitude */ char y_format[GMT_LEN64]; /* Actual C format used to plot/output latitude */ char delimiter[2][2]; /* Delimiter strings in date, e.g. "-" */ diff --git a/src/gmt_support.c b/src/gmt_support.c index 17305f84a2c..421a26cd18f 100644 --- a/src/gmt_support.c +++ b/src/gmt_support.c @@ -15792,6 +15792,7 @@ void gmtlib_get_annot_label (struct GMT_CTRL *GMT, double val, char *label, bool unsigned int k, n_items, level, type; bool zero_fix = false, lat_special = (lonlat == 3), deg_special = (lonlat == 4); char hemi_pre[GMT_LEN16] = {""}, hemi_post[GMT_LEN16] = {""}, text[GMT_LEN64] = {""}; + char use_format[GMT_LEN64] = {""}; /* Must override do_minutes and/or do_seconds if format uses decimal notation for that item */ @@ -15862,24 +15863,28 @@ void gmtlib_get_annot_label (struct GMT_CTRL *GMT, double val, char *label, bool zero_fix = true; } if (hemi_pre[0]) strcpy (label, hemi_pre); + strncpy (use_format, GMT->current.plot.format[level][type], GMT_LEN64); + if (lonlat & 1) + gmt_strrep (use_format, "%3.3d", "%2.2d"); + sprintf(stderr, "lonlat, use_format = %d %s\n", lonlat, use_format); switch (2*level+type) { case 0: - sprintf (text, GMT->current.plot.format[level][type], d, hemi_post); + sprintf (text, use_format, d, hemi_post); break; case 1: - sprintf (text, GMT->current.plot.format[level][type], d, m_sec, hemi_post); + sprintf (text, use_format, d, m_sec, hemi_post); break; case 2: - sprintf (text, GMT->current.plot.format[level][type], d, m, hemi_post); + sprintf (text, use_format, d, m, hemi_post); break; case 3: - sprintf (text, GMT->current.plot.format[level][type], d, m, m_sec, hemi_post); + sprintf (text, use_format, d, m, m_sec, hemi_post); break; case 4: - sprintf (text, GMT->current.plot.format[level][type], d, m, s, hemi_post); + sprintf (text, use_format, d, m, s, hemi_post); break; case 5: - sprintf (text, GMT->current.plot.format[level][type], d, m, s, m_sec, hemi_post); + sprintf (text, use_format, d, m, s, m_sec, hemi_post); break; } if (zero_fix) text[1] = '0'; /* Undo the fix above */