Skip to content

Commit 1d0b52e

Browse files
committed
Addres limitation with global pixel grids and lack of projection
See #4440 for background. This implements the solution of adjusting -R in the rare case we cannot plot a rotated grid.
1 parent 92c5676 commit 1d0b52e

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/gmt_grdio.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,12 +2182,13 @@ int gmt_grd_setregion (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *h, double *
21822182

21832183
if (grid_global) {
21842184
bool true_global_region = (gmt_M_360_range (h->wesn[XLO], h->wesn[XHI]) && gmt_M_360_range (GMT->common.R.wesn[XLO], GMT->common.R.wesn[XHI]));
2185+
double x_noise = GMT_CONV4_LIMIT * h->inc[GMT_X];
21852186
wesn[XLO] = h->wesn[XLO] + floor ((wesn[XLO] - h->wesn[XLO]) * HH->r_inc[GMT_X] + GMT_CONV4_LIMIT) * h->inc[GMT_X];
21862187
wesn[XHI] = h->wesn[XLO] + ceil ((wesn[XHI] - h->wesn[XLO]) * HH->r_inc[GMT_X] - GMT_CONV4_LIMIT) * h->inc[GMT_X];
21872188
/* For the odd chance that xmin or xmax are outside the region: bring them in */
21882189
if ((wesn[XHI] - wesn[XLO]) >= 360.0) {
2189-
while ((wesn[XLO]) < GMT->common.R.wesn[XLO]) wesn[XLO] += h->inc[GMT_X];
2190-
while ((wesn[XHI]) > GMT->common.R.wesn[XHI]) wesn[XHI] -= h->inc[GMT_X];
2190+
while ((wesn[XLO] + x_noise) < GMT->common.R.wesn[XLO]) wesn[XLO] += h->inc[GMT_X];
2191+
while ((wesn[XHI]- x_noise) > GMT->common.R.wesn[XHI]) wesn[XHI] -= h->inc[GMT_X];
21912192
}
21922193
if (true_global_region && (wesn[XHI] - wesn[XLO]) < 360.0) /* Need to enforce 360 range since that is what it should be */
21932194
wesn[XHI] = wesn[XLO] + 360.0;

src/grdimage.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,38 @@ GMT_LOCAL void grdimage_img_color_with_intensity (struct GMT_CTRL *GMT, struct G
10751075
}
10761076
}
10771077

1078+
GMT_LOCAL bool grdimage_adjust_R_consideration (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *h, bool force) {
1079+
/* As per https://github.com/GenericMappingTools/gmt/issues/4440, when the user wants
1080+
* to plot a pixel-registered global grid using a lon-lat scaling with periodic boundaries
1081+
* and a central meridian that is not a multiple of the grid increment, we must actually
1082+
* adjust the plot domain -R to be such a multiple. That, or require projection.
1083+
* Pass force as true if we are to bypass the other checks that normally come first.
1084+
* For instance, if grdimage -Edpi is set then we must always project, so force -> true. */
1085+
1086+
double delta;
1087+
1088+
if (!gmt_M_is_geographic (GMT, GMT_IN)) return false; /* No geographic */
1089+
if (!force) { /* See what we have */
1090+
if (h->registration == GMT_GRID_NODE_REG) return false; /* gridline-registration has the repeated column needed */
1091+
if (gmt_M_is_nonlinear_graticule (GMT)) return true; /* Always have to project when given most projections except -JQ */
1092+
if (!gmt_M_360_range (GMT->common.R.wesn[XLO], GMT->common.R.wesn[XHI])) return false; /* No repeating columns would be visible */
1093+
}
1094+
delta = remainder (h->wesn[XLO] - GMT->common.R.wesn[XLO], h->inc[GMT_X]);
1095+
if (gmt_M_is_zero (delta)) return false; /* No need to project if it is lining up */
1096+
/* Here we need to adjust plot region */
1097+
GMT_Report (GMT->parent, GMT_MSG_WARNING, "Your grid is pixel-registered, the projection is simply longlat, and plot region is a full 360 degrees in longitude.\n");
1098+
GMT_Report (GMT->parent, GMT_MSG_WARNING, "Due to lack of repeated boundary nodes, -Rw/e must be given in multiples of the grid increment (%g)\n", h->inc[GMT_X]);
1099+
GMT_Report (GMT->parent, GMT_MSG_WARNING, "Current region (-R) setting in longitude is %g to %g\n", GMT->common.R.wesn[XLO], GMT->common.R.wesn[XHI]);
1100+
GMT->common.R.wesn[XLO] += delta;
1101+
GMT->common.R.wesn[XHI] += delta;
1102+
if (GMT->common.R.wesn[XHI] <= 0.0) {
1103+
GMT->common.R.wesn[XLO] += 360.0;
1104+
GMT->common.R.wesn[XHI] += 360.0;
1105+
}
1106+
GMT_Report (GMT->parent, GMT_MSG_WARNING, "Adjusted region (-R) setting in longitude is %g to %g\n", GMT->common.R.wesn[XLO], GMT->common.R.wesn[XHI]);
1107+
return false;
1108+
}
1109+
10781110
#define bailout(code) {gmt_M_free_options (mode); return (code);}
10791111
#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_M_free (GMT, Conf); gmt_end_module (GMT, GMT_cpy); bailout (code);}
10801112

@@ -1212,7 +1244,7 @@ EXTERN_MSC int GMT_grdimage (void *V_API, int mode, void *args) {
12121244

12131245
if (use_intensity_grid && GMT->common.R.active[RSET]) {
12141246
/* Make sure the region of the intensity grid and -R are in agreement within a noise threshold */
1215-
double xnoise = Intens_orig->header->inc[GMT_X]*GMT_CONV4_LIMIT, ynoise = Intens_orig->header->inc[GMT_Y]*GMT_CONV4_LIMIT;
1247+
double xnoise = Intens_orig->header->inc[GMT_X]*GMT_CONV4_LIMIT, ynoise = Intens_orig->header->inc[GMT_Y]*GMT_CONV4_LIMIT;
12161248
if (GMT->common.R.wesn[XLO] < (Intens_orig->header->wesn[XLO]-xnoise) || GMT->common.R.wesn[XHI] > (Intens_orig->header->wesn[XHI]+xnoise) ||
12171249
GMT->common.R.wesn[YLO] < (Intens_orig->header->wesn[YLO]-ynoise) || GMT->common.R.wesn[YHI] > (Intens_orig->header->wesn[YHI]+ynoise)) {
12181250
GMT_Report (API, GMT_MSG_ERROR, "Requested region exceeds illumination extent\n");
@@ -1302,6 +1334,8 @@ EXTERN_MSC int GMT_grdimage (void *V_API, int mode, void *args) {
13021334
if (!GMT->common.R.active[RSET] && got_z_grid) /* -R was not set so we use the grid domain */
13031335
gmt_set_R_from_grd (GMT, Grid_orig->header);
13041336

1337+
grdimage_adjust_R_consideration (GMT, header_work, Ctrl->E.dpi); /* SPecial check for global pixel-registered plots */
1338+
13051339
/* Initialize the projection for the selected -R -J */
13061340
if (gmt_map_setup (GMT, GMT->common.R.wesn)) Return (GMT_PROJECTION_ERROR);
13071341

0 commit comments

Comments
 (0)