Skip to content

Commit e729a9b

Browse files
authored
Save any default CPT for remote datasets in hidden grid header (#6178)
* Save any default CPT in hidden grid header This addresses #6167 when we cut a subset from, sa, earth_relief_10m and then no longer know what the CPT should be. * use allocated string cpt instead * Init remote_id to -1 * polish * Fix save CPT and highpass * Update gmt_support.c * Add small tests * formatting * Remove boundary annotations * Save the current CPT from grdcut if modern mode
1 parent 58234c5 commit e729a9b

19 files changed

+98
-29
lines changed

src/gmt_api.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8198,11 +8198,12 @@ void * GMT_Create_Session (const char *session, unsigned int pad, unsigned int m
81988198

81998199
if ((API = calloc (1, sizeof (struct GMTAPI_CTRL))) == NULL) return_null (NULL, GMT_MEMORY_ERROR); /* Failed to allocate the structure */
82008200
API->verbose = (mode >> 16); /* Pick up any -V settings from gmt.c */
8201-
API->pad = pad; /* Preserve the default pad value for this session */
8201+
API->remote_id = GMT_NOTSET; /* Not read a remote grid yet */
8202+
API->pad = pad; /* Preserve the default pad value for this session */
82028203
API->print_func = (print_func == NULL) ? gmtapi_print_func : print_func; /* Pointer to the print function to use in GMT_Message|Report */
82038204
API->do_not_exit = mode & GMT_SESSION_NOEXIT; /* Deprecated, we no longer call exit anywhere in the API (gmt_api.c) */
8204-
API->external = (mode & GMT_SESSION_EXTERNAL) ? 1 : 0; /* if false|0 then we don't list read and write as modules */
8205-
if (API->external && mode & GMT_SESSION_NOGDALCLOSE) API->external = 2; /* Avoid calling GDALDestroyDriverManager */
8205+
API->external = (mode & GMT_SESSION_EXTERNAL) ? 1 : 0; /* if false|0 then we don't list read and write as modules */
8206+
if (API->external && mode & GMT_SESSION_NOGDALCLOSE) API->external = 2; /* Avoid calling GDALDestroyDriverManager */
82068207
API->shape = (mode & GMT_SESSION_COLMAJOR) ? GMT_IS_COL_FORMAT : GMT_IS_ROW_FORMAT; /* if set then we must use column-major format [row-major] */
82078208
API->runmode = mode & GMT_SESSION_RUNMODE; /* If nonzero we set up modern GMT run-mode, else classic */
82088209
API->no_history = mode & GMT_SESSION_NOHISTORY; /* If nonzero we disable the gmt.history mechanism (shorthands) entirely */

src/gmt_dev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ extern "C" {
129129
#include "gmt_common_math.h" /* Shared math functions */
130130
#include "gmt.h" /* All GMT high-level API */
131131
#include "gmt_private.h" /* API declaration needed by libraries */
132+
#include "gmt_constants.h" /* All basic constant definitions */
132133
#include "gmt_hidden.h" /* Hidden bookkeeping structure for API containers */
133134

134135
struct GMT_CTRL; /* forward declaration of GMT_CTRL */
135136

136137
#include "gmt_notposix.h" /* Non-POSIX extensions */
137138

138-
#include "gmt_constants.h" /* All basic constant definitions */
139139
#include "gmt_modern.h" /* Modern mode constant definitions */
140140
#include "gmt_macros.h" /* All basic macros definitions */
141141
#include "gmt_dimensions.h" /* Constant definitions created by configure */

src/gmt_grdio.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ void gmt_copy_gridheader (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *to, stru
756756
if (Hto->title) gmt_M_str_free (Hto->title); /* Since we will duplicate via from */
757757
if (Hto->command) gmt_M_str_free (Hto->command); /* Since we will duplicate via from */
758758
if (Hto->remark) gmt_M_str_free (Hto->remark); /* Since we will duplicate via from */
759+
if (Hto->cpt) gmt_M_str_free (Hto->cpt); /* Since we will duplicate via from */
759760
gmt_M_memcpy (to, from, 1, struct GMT_GRID_HEADER); /* Copies full contents but also duplicates the hidden address */
760761
to->hidden = Hto; /* Restore the original hidden address in to */
761762
gmt_M_memcpy (to->hidden, from->hidden, 1, struct GMT_GRID_HEADER_HIDDEN); /* Copies full contents of hidden area */
@@ -766,6 +767,7 @@ void gmt_copy_gridheader (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *to, stru
766767
if (Hfrom->title) Hto->title = strdup (Hfrom->title);
767768
if (Hfrom->command) Hto->command = strdup (Hfrom->command);
768769
if (Hfrom->remark) Hto->remark = strdup (Hfrom->remark);
770+
if (Hfrom->cpt) Hto->cpt = strdup (Hfrom->cpt);
769771
}
770772

771773
/*! gmt_grd_is_global returns true for a geographic grid with exactly 360-degree range (with or without repeating column) */
@@ -2112,6 +2114,7 @@ void gmt_grd_init (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *header, struct
21122114
if (HH->command) gmt_M_str_free (HH->command); /* Free previous string */
21132115
if (HH->title) gmt_M_str_free (HH->title); /* Free previous string */
21142116
if (HH->remark) gmt_M_str_free (HH->remark); /* Free previous string */
2117+
if (HH->cpt) gmt_M_str_free (HH->cpt); /* Free previous string */
21152118
gmt_M_memcpy (mem, header->mem_layout, 4, char);
21162119
gmt_M_memset (header, 1, struct GMT_GRID_HEADER);
21172120
HH->index_function = ptr;
@@ -2932,6 +2935,7 @@ void gmt_free_header (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER **header) {
29322935
if (HH->title) gmt_M_str_free (HH->title);
29332936
if (HH->command) gmt_M_str_free (HH->command);
29342937
if (HH->remark) gmt_M_str_free (HH->remark);
2938+
if (HH->cpt) gmt_M_str_free (HH->cpt);
29352939
gmt_M_free (GMT, h->hidden);
29362940
gmt_M_free (GMT, *header);
29372941
}

src/gmt_hidden.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ struct GMT_GRID_HEADER_HIDDEN {
159159
char name[GMT_GRID_NAME_LEN256]; /* Actual name of the file after any ?<varname> and =<stuff> has been removed */
160160
char varname[GMT_GRID_VARNAME_LEN80];/* NetCDF: variable name */
161161
char *title; /* Title string not limited to GMT_GRID_TITLE_LEN80 characters */
162+
char *cpt; /* Name of default CPT for a remote grid subset written via grdcut */
162163
char *command; /* Command/history string not limited to GMT_GRID_TITLE_LEN80 characters */
163164
char *remark; /* Remark/description string not limited to GMT_GRID_REMARK_LEN160 characters */
164165
int row_order; /* NetCDF: k_nc_start_south if S->N, k_nc_start_north if N->S */

src/gmt_init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15561,6 +15561,7 @@ struct GMT_CTRL *gmt_init_module (struct GMTAPI_CTRL *API, const char *lib_name,
1556115561
wesn[YHI] = ceil ((wesn[YHI] / d_inc) - GMT_CONV8_LIMIT) * d_inc;
1556215562
gmt_M_memcpy (API->tile_wesn, wesn, 4, double); /* Retain this knowledge in case it was obtained via map_setup for an oblique area */
1556315563
API->got_remote_wesn = true; /* In case we need to use this subset when reading a grid or image */
15564+
API->remote_id = k_data2;
1556415565
}
1556515566
if (dry_run)
1556615567
goto dry_run;

src/gmt_io.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4742,8 +4742,9 @@ int gmtlib_nc_get_att_text (struct GMT_CTRL *GMT, int ncid, int varid, char *nam
47424742
/*! . */
47434743
int gmtlib_nc_get_att_vtext (struct GMT_CTRL *GMT, int ncid, int varid, char *name, struct GMT_GRID_HEADER *h, char *text, size_t textlen) {
47444744
/* Similar to gmtlib_nc_get_att_text and used for title, history, and remark which, if longer than what can fit in header
4745-
* are stored as allocated strings in the struct GMT_GRID_HEADER_HIDDEN structure.
4745+
* are stored as allocated strings in the struct GMT_GRID_HEADER_HIDDEN structure. We also place cpt in the hidden struct if found.
47464746
* ncid, varid, name, text : as in nc_get_att_text
4747+
* If text is NULL then we do not access it
47474748
* h : the pointer to the grid header structure
47484749
* textlen : maximum number of characters to copy to string text
47494750
*/
@@ -4752,9 +4753,13 @@ int gmtlib_nc_get_att_vtext (struct GMT_CTRL *GMT, int ncid, int varid, char *na
47524753
size_t attlen, trunclen;
47534754
char *att = NULL;
47544755

4756+
if (name == NULL) {
4757+
GMT_Report (GMT->parent, GMT_MSG_ERROR, "Attribute name passed to gmtlib_nc_get_att_vtext is NULL\n");
4758+
return GMT_RUNTIME_ERROR;
4759+
}
47554760
status = nc_inq_attlen (ncid, varid, name, &attlen);
47564761
if (status != NC_NOERR) { /* No such attribute */
4757-
*text = '\0';
4762+
if (text) text[0] = '\0';
47584763
return status;
47594764
}
47604765
att = calloc (attlen+1, sizeof (char)); /* Allocate the memory for the full string plus text terminator */
@@ -4777,13 +4782,20 @@ int gmtlib_nc_get_att_vtext (struct GMT_CTRL *GMT, int ncid, int varid, char *na
47774782
HH->remark = att;
47784783
wipe = false;
47794784
}
4785+
else if (strcmp (name, "cpt") == 0) {
4786+
if (HH->cpt) gmt_M_str_free (HH->cpt); /* Free previous string */
4787+
HH->cpt = att;
4788+
wipe = false;
4789+
}
4790+
}
4791+
if (text) { /* Only copy over if text was passed */
4792+
trunclen = MIN (attlen, textlen-1); /* attlen does not include terminating '\0') */
4793+
strncpy (text, att, trunclen); /* Copy att to text */
4794+
text[trunclen] = '\0'; /* Terminate string */
47804795
}
4781-
trunclen = MIN (attlen, textlen-1); /* attlen does not include terminating '\0') */
4782-
strncpy (text, att, trunclen); /* Copy att to text */
4783-
text[trunclen] = '\0'; /* Terminate string */
47844796
}
4785-
else /* Not successful, set ouput string to empty */
4786-
*text = '\0';
4797+
else if (text) /* Not successful, set output string to empty unless NULL */
4798+
text[0] = '\0';
47874799
if (wipe) gmt_M_str_free (att); /* Free since not placed in hidden structure */
47884800
return status;
47894801
}

src/gmt_nc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,9 @@ GMT_LOCAL int gmtnc_grd_info (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *head
896896
/* Valid range is already in packed units, so do not convert */
897897
header->z_min = dummy[0], header->z_max = dummy[1];
898898
}
899+
if (gmtlib_nc_get_att_vtext (GMT, ncid, z_id, "cpt", header, NULL, 0)) /* Found cpt attribute */
900+
GMT_Report (GMT->parent, GMT_MSG_INFORMATION, "netCDF grid %s has a default CPT %s.\n", HH->cpt);
901+
899902
if (gmt_M_is_dnan (header->z_min) && gmt_M_is_dnan (header->z_max)) {
900903
GMT_Report (GMT->parent, GMT_MSG_INFORMATION, "netCDF grid %s information has zmin = zmax = NaN. Reset to 0/0.\n", HH->name);
901904
header->z_min = header->z_max = 0.0;
@@ -1029,6 +1032,10 @@ GMT_LOCAL int gmtnc_grd_info (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *head
10291032

10301033
/* Define z variable. Attempt to remove "scale_factor" or "add_offset" when no longer needed */
10311034
gmtnc_put_units (ncid, z_id, header->z_units);
1035+
if (GMT->parent->remote_info && GMT->parent->remote_id != GMT_NOTSET && GMT->parent->remote_info[GMT->parent->remote_id].CPT[0] != '-') { /* Subset of remote grid with default CPT, save name as an attribute */
1036+
HH->cpt = strdup (GMT->parent->remote_info[GMT->parent->remote_id].CPT);
1037+
gmt_M_err_trap (nc_put_att_text (ncid, z_id, "cpt", strlen (HH->cpt), HH->cpt));
1038+
}
10321039

10331040
if (header->z_scale_factor != 1.0) {
10341041
gmt_M_err_trap (nc_put_att_double (ncid, z_id, "scale_factor", NC_DOUBLE, 1U, &header->z_scale_factor));

src/gmt_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ struct GMTAPI_CTRL {
209209
char *O_OPT, *K_OPT, *P_OPT, *c_OPT;
210210
/* structure array of remote file information (sorted alphabetically) */
211211
int n_remote_info; /* How many remote server files we know of */
212+
int remote_id; /* Currently used remote ID or -1 */
212213
struct GMT_DATA_INFO *remote_info;
213214
bool server_announced; /* Set to true after we have announced which GMT data server we are using */
214215
struct GMT_COMMON *common_snapshot; /* Holds the latest GMT common option settings after a module completes. */

src/gmt_prototypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ EXTERN_MSC int gmt_find_macro (char *arg, unsigned int n_macros, struct GMT_MATH
659659
EXTERN_MSC int gmt_load_macros (struct GMT_CTRL *GMT, char *mtype, struct GMT_MATH_MACRO **M);
660660
EXTERN_MSC struct GMT_OPTION * gmt_substitute_macros (struct GMT_CTRL *GMT, struct GMT_OPTION *options, char *mfile);
661661
EXTERN_MSC void gmt_free_macros (struct GMT_CTRL *GMT, unsigned int n_macros, struct GMT_MATH_MACRO **M);
662-
EXTERN_MSC char * gmt_cpt_default (struct GMTAPI_CTRL *API, char *cpt, char *file);
662+
EXTERN_MSC char * gmt_cpt_default (struct GMTAPI_CTRL *API, char *cpt, char *file, struct GMT_GRID_HEADER *h);
663663
EXTERN_MSC void gmt_sort_array (struct GMT_CTRL *GMT, void *base, uint64_t n, unsigned int type);
664664
EXTERN_MSC bool gmt_polygon_is_open (struct GMT_CTRL *GMT, double x[], double y[], uint64_t n);
665665
EXTERN_MSC int gmt_polygon_centroid (struct GMT_CTRL *GMT, double *x, double *y, uint64_t n, double *Cx, double *Cy);

src/gmt_remote.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ void gmt_set_unspecified_remote_registration (struct GMTAPI_CTRL *API, char **fi
477477
ext = gmt_chop_ext (infile);
478478
/* If the remote file is found then there is nothing to do */
479479
if ((k_data = gmt_remote_dataset_id (API, infile)) == GMT_NOTSET) goto clean_up;
480+
API->remote_id = k_data;
480481
L = strlen (API->remote_info[k_data].dir) - 1; /* Length of dir minus trailing slash */
481482
strncpy (dir, API->remote_info[k_data].dir, L); dir[L] = '\0'; /* Duplicate dir without slash */
482483
p = strrchr (dir, '/') + 1; /* Start of final subdirectory (skipping over the slash we found) */
@@ -498,6 +499,7 @@ void gmt_set_unspecified_remote_registration (struct GMTAPI_CTRL *API, char **fi
498499
}
499500
gmt_M_str_free (*file_ptr);
500501
*file_ptr = strdup (newfile);
502+
API->remote_id = k_data;
501503
goto clean_up;
502504
}
503505
}

0 commit comments

Comments
 (0)