Skip to content

Commit fdcb590

Browse files
authored
Try to get matrix as grid to work with changing central meridian (#3813)
* Try to get matrix as grid to work with changing central meridian This effort runs into trouble with the function gmt_grd_setregion that determins what region of the grid we should use. * Adjust projected limits * Update globalgrid.ps * Fix columns * Update gmt_api.c
1 parent a096c1c commit fdcb590

File tree

6 files changed

+27
-8
lines changed

6 files changed

+27
-8
lines changed

src/gmt_api.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5204,7 +5204,7 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
52045204

52055205
int item, new_item, new_ID;
52065206
bool done = true, new = false, row_by_row;
5207-
uint64_t row, col, i0, i1, j0, j1, ij, ij_orig;
5207+
uint64_t row, col, kol, i0, i1, j0, j1, ij, ij_orig;
52085208
size_t size;
52095209
unsigned int both_set = (GMT_CONTAINER_ONLY | GMT_DATA_ONLY);
52105210
unsigned int method;
@@ -5231,7 +5231,7 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
52315231
GMT_Report (API, GMT_MSG_ERROR, "Can only use method GMT_IS_FILE when row-by-row reading of grid is selected\n");
52325232
return_null (API, GMT_NOT_A_VALID_METHOD);
52335233
}
5234-
if ((mode & GMT_CONTAINER_ONLY) && S_obj->region) {
5234+
if ((mode & GMT_CONTAINER_ONLY) && S_obj->region && S_obj->method == GMT_IS_FILE) {
52355235
GMT_Report (API, GMT_MSG_ERROR, "Cannot request a subset when just inquiring about the grid header\n");
52365236
return_null (API, GMT_SUBSET_NOT_ALLOWED);
52375237
}
@@ -5466,8 +5466,9 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
54665466

54675467
for (row = j0; row <= j1; row++) {
54685468
for (col = i0; col <= i1; col++, ij++) {
5469-
ij_orig = GMT_2D_to_index (row, col, M_obj->dim); /* Position of this (row,col) in input matrix organization */
5470-
ij = gmt_M_ijp (G_obj->header, row, col); /* Position of this (row,col) in output grid organization */
5469+
kol = col % M_obj->n_columns;
5470+
ij_orig = GMT_2D_to_index (row, kol, M_obj->dim); /* Position of this (row,col) in input matrix organization */
5471+
ij = gmt_M_ijp (G_obj->header, row, kol); /* Position of this (row,col) in output grid organization */
54715472
api_get_val (&(M_obj->data), ij_orig, &d); /* Get the next item from the matrix */
54725473
G_obj->data[ij] = (gmt_grdfloat)d;
54735474
if (gmt_M_is_dnan (d))
@@ -5478,6 +5479,10 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
54785479
}
54795480
}
54805481
}
5482+
if (gmt_M_is_geographic (GMT, GMT_IN) && gmt_M_360_range (M_obj->range[XLO], M_obj->range[XHI]) && gmt_M_360_range (G_obj->header->wesn[XLO], G_obj->header->wesn[XHI])) {
5483+
/* Global grids passed via matrix are not rotated to fit the desired global region, so we need to correct the wesn for this grid to match the matrix */
5484+
gmt_M_memcpy (G_obj->header->wesn, M_obj->range, 4U, double);
5485+
}
54815486
gmt_BC_init (GMT, G_obj->header); /* Initialize grid interpolation and boundary condition parameters */
54825487
if (gmt_M_err_pass (GMT, gmt_grd_BC_set (GMT, G_obj, GMT_IN), "Grid memory"))
54835488
return_null (API, GMT_GRID_BC_ERROR); /* Set boundary conditions */
@@ -5492,7 +5497,7 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
54925497
//if (S_obj->region) return_null (API, GMT_SUBSET_NOT_ALLOWED);
54935498
/* This method requires the input data to be a GMT_GRD_FORMAT matrix - otherwise we should be DUPLICATING */
54945499
MH = gmt_get_M_hidden (M_obj);
5495-
if (!(M_obj->shape == GMT_IS_ROW_FORMAT && M_obj->type == GMT_GRDFLOAT && MH->alloc_mode == GMT_ALLOC_EXTERNALLY && (mode & GMT_GRID_IS_COMPLEX_MASK) == 0))
5500+
if (!(M_obj->shape == GMT_IS_ROW_FORMAT && M_obj->type == GMT_GRDFLOAT && (mode & GMT_GRID_IS_COMPLEX_MASK) == 0))
54965501
return_null (API, GMT_NOT_A_VALID_IO_ACCESS);
54975502
if (grid == NULL) { /* Only allocate when not already allocated. Note cannot have pad since input matrix wont have one */
54985503
uint64_t dim[3] = {M_obj->n_rows, M_obj->n_columns, 1};

src/gmt_grdio.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2170,13 +2170,16 @@ int gmt_grd_setregion (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *h, double *
21702170
/* Periodic grid with 360 degree range is easy */
21712171

21722172
if (grid_global) {
2173+
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]));
21732174
wesn[XLO] = h->wesn[XLO] + floor ((wesn[XLO] - h->wesn[XLO]) * HH->r_inc[GMT_X] + GMT_CONV4_LIMIT) * h->inc[GMT_X];
21742175
wesn[XHI] = h->wesn[XLO] + ceil ((wesn[XHI] - h->wesn[XLO]) * HH->r_inc[GMT_X] - GMT_CONV4_LIMIT) * h->inc[GMT_X];
21752176
/* For the odd chance that xmin or xmax are outside the region: bring them in */
2176-
if (wesn[XHI] - wesn[XLO] >= 360.0) {
2177+
if ((wesn[XHI] - wesn[XLO]) >= 360.0) {
21772178
while ((wesn[XLO]) < GMT->common.R.wesn[XLO]) wesn[XLO] += h->inc[GMT_X];
21782179
while ((wesn[XHI]) > GMT->common.R.wesn[XHI]) wesn[XHI] -= h->inc[GMT_X];
21792180
}
2181+
if (true_global_region && (wesn[XHI] - wesn[XLO]) < 360.0) /* Need to enforce 360 range since that is what it should be */
2182+
wesn[XHI] = wesn[XLO] + 360.0;
21802183
return (1);
21812184
}
21822185
if (GMT->current.map.is_world) {

src/grdimage.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,13 @@ GMT_LOCAL void grdimage_set_proj_limits (struct GMT_CTRL *GMT, struct GMT_GRID_H
567567
r->wesn[YLO] = GMT->current.proj.rect[YLO]; r->wesn[YHI] = GMT->current.proj.rect[YHI];
568568
}
569569
}
570+
else if (gmt_M_x_is_lon (GMT, GMT_IN)) { /* Extra check for non-projected longitudes that wrap */
571+
double x1;
572+
gmt_geo_to_xy (GMT, g->wesn[XHI]-g->inc[GMT_X], g->wesn[YHI], &x1, &y);
573+
gmt_geo_to_xy (GMT, g->wesn[XHI], g->wesn[YHI], &x, &y);
574+
if (x < x1) /* Wrapped around because end of pixel is outside east; use plot width instead */
575+
r->wesn[XHI] = r->wesn[XLO] + GMT->current.proj.rect[XHI];
576+
}
570577
}
571578

572579
GMT_LOCAL int grdimage_set_rgb_three_grids (struct GMT_GRID *Grid_proj[], uint64_t node, double *NaN_rgb, double *rgb) {

src/testapi_matrix_360.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int main () {
1313

1414
API = GMT_Create_Session ("test", 2U, mode, NULL);
1515

16-
/* Read in earth_relief_01d as a matrix from text file and set correct region, inc, registartion */
16+
/* Read in earth_relief_01d as a matrix from text file and set correct region, inc, registration */
1717
M = GMT_Read_Data (API, GMT_IS_MATRIX, GMT_IS_FILE, GMT_IS_SURFACE, GMT_READ_NORMAL, NULL, "@earth_relief_01d.txt", NULL);
1818
M->range[0] = -180; M->range[1] = 180; M->range[2] = -90; M->range[3] = 90.0;
1919
M->inc[0] = M->inc[1] = 1.0;
@@ -24,8 +24,12 @@ int main () {
2424
sprintf (args, "%s -Rg -JH0/6i -Bg30 -K -Cgeo -P", input);
2525
GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args);
2626
GMT_Init_VirtualFile (API, 0, input);
27+
/* Call grdimage with central longitude 98.75W, which is arbitrary */
28+
sprintf (args, "%s -R -JH98.7/6i -Bg30 -K -Cgeo -O -Y3.25i", input);
29+
GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args);
30+
GMT_Init_VirtualFile (API, 0, input);
2731
/* Call grdimage with central longitude 180 which means grid needs to be rotated 180 */
28-
sprintf (args, "%s -R -JH180/6i -Bg30 -O -Cgeo -Y3.5i", input);
32+
sprintf (args, "%s -R -JH180/6i -Bg30 -O -Cgeo -Y3.25i", input);
2933
GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args);
3034
GMT_Close_VirtualFile (API, input);
3135

test/api/apimat_360.ps

426 KB
Binary file not shown.

test/grdimage/globalgrid.ps

-21 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)