diff --git a/src/gmt_api.c b/src/gmt_api.c index 1dc901e8e1b..12f42136889 100644 --- a/src/gmt_api.c +++ b/src/gmt_api.c @@ -1984,7 +1984,6 @@ GMT_LOCAL int gmtapi_init_matrix (struct GMTAPI_CTRL *API, uint64_t dim[], doubl /* If range = inc = NULL then add dimensioning is set via dim: ncols, nrow, nlayers, type. * else, ncols,nrows is set via range and inc and registration. dim, if not null, sets dim[2] = nlayers [1] and dim[3] = type [double] */ - double off = 0.5 * registration; int error; unsigned int dims = (M->n_layers > 1) ? 3 : 2; size_t size = 0; @@ -1999,8 +1998,8 @@ GMT_LOCAL int gmtapi_init_matrix (struct GMTAPI_CTRL *API, uint64_t dim[], doubl if (!inc || (inc[GMT_X] == 0.0 && inc[GMT_Y] == 0.0)) return (GMT_VALUE_NOT_SET); gmt_M_memcpy (M->range, range, 2 * dims, double); gmt_M_memcpy (M->inc, inc, dims, double); - M->n_rows = gmt_M_get_n (API->GMT, range[YLO], range[YHI], inc[GMT_Y], off); - M->n_columns = gmt_M_get_n (API->GMT, range[XLO], range[XHI], inc[GMT_X], off); + M->n_rows = gmt_M_get_n (API->GMT, range[YLO], range[YHI], inc[GMT_Y], registration); + M->n_columns = gmt_M_get_n (API->GMT, range[XLO], range[XHI], inc[GMT_X], registration); M->dim = (M->shape == GMT_IS_ROW_FORMAT) ? M->n_columns : M->n_rows; /* Matrix layout order */ } return (GMT_NOERROR); @@ -2016,11 +2015,12 @@ GMT_LOCAL int gmtapi_init_matrix (struct GMTAPI_CTRL *API, uint64_t dim[], doubl if (!inc || (inc[GMT_X] == 0.0 && inc[GMT_Y] == 0.0)) return (GMT_VALUE_NOT_SET); gmt_M_memcpy (M->range, range, 2 * dims, double); gmt_M_memcpy (M->inc, inc, dims, double); - M->n_rows = gmt_M_get_n (API->GMT, range[YLO], range[YHI], inc[GMT_Y], off); - M->n_columns = gmt_M_get_n (API->GMT, range[XLO], range[XHI], inc[GMT_X], off); + M->n_rows = gmt_M_get_n (API->GMT, range[YLO], range[YHI], inc[GMT_Y], registration); + M->n_columns = gmt_M_get_n (API->GMT, range[XLO], range[XHI], inc[GMT_X], registration); } M->type = (dim == NULL) ? GMT_DOUBLE : dim[3]; /* Use selected data type for export or default to double */ M->dim = (M->shape == GMT_IS_ROW_FORMAT) ? M->n_columns : M->n_rows; + M->registration = registration; size = M->n_rows * M->n_columns * ((size_t)M->n_layers); /* Size in bytes of the initial matrix allocation */ if ((mode & GMT_CONTAINER_ONLY) == 0) { /* Must allocate data memory */ struct GMT_MATRIX_HIDDEN *MH = gmt_get_M_hidden (M); @@ -2042,7 +2042,7 @@ GMT_LOCAL uint64_t gmtapi_vector_nrows (uint64_t dim[], double *range, double *i if (dim && dim[GMTAPI_DIM_ROW]) return dim[GMTAPI_DIM_ROW]; /* Gave the dimension directly */ if (dir == GMT_IN && (!inc || inc[GMT_X] == 0.0)) return ((uint64_t)GMT_NOTSET); if (dir == GMT_IN && (!range || (range[XLO] == 0.0 && range[XHI] == 0.0))) return ((uint64_t)GMT_NOTSET); - if (range && inc) return (gmt_M_get_n (API->GMT, range[XLO], range[XHI], inc[GMT_X], 0.5 * registration)); + if (range && inc) return (gmt_M_get_n (API->GMT, range[XLO], range[XHI], inc[GMT_X], registration)); return (0); /* When dir == GMT_OUT */ } diff --git a/src/testapi_matrix_as_grid.c b/src/testapi_matrix_as_grid.c new file mode 100644 index 00000000000..2eed6b762d1 --- /dev/null +++ b/src/testapi_matrix_as_grid.c @@ -0,0 +1,41 @@ +#include "gmt_dev.h" + +/* Test passing a gridline and pixel-registered matrix as grids to grdimage. + * the two plots should be identical. This tests was made to demonstrate a + * bug in the API that was fixed in https://github.com/GenericMappingTools/gmt/pull/3503. + * The problem was an error in gmt_M_get_n and failure to set M->registration for matrices. + */ + +int main () { + unsigned int mode = GMT_SESSION_EXTERNAL; + struct GMT_MATRIX *M_p = NULL, *M_g = NULL; + char input_p[GMT_VF_LEN] = {""}, input_g[GMT_VF_LEN] = {""}; + char args_p[128] = {""}, args_g[128]= {""}; + struct GMTAPI_CTRL *API = NULL; + + double inc[2] = {1.0, 1.0}; + double coord[9] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; + + API = GMT_Create_Session ("test", 2U, mode, NULL); + + /* pass matrix as gridline-registered grid */ + double range_g[4] = {0.0, 2.0, 0.0, 2.0}; + if ((M_g = GMT_Create_Data (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_CONTAINER_ONLY, NULL, range_g, inc, GMT_GRID_NODE_REG, 0, NULL)) == NULL) return (EXIT_FAILURE); + GMT_Put_Matrix (API, M_g, GMT_DOUBLE, 0, coord); + GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, M_g, input_g); + sprintf (args_g, "%s -R-1/3/-1/3 -JX6c -Baf -BWSen+tGridline -K -P > api_matrix_as_grid.ps", input_g); + GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args_g); + GMT_Close_VirtualFile (API, input_g); + + /* pass matrix as pixel-registered grid */ + double range_p[4] = {-0.5, 2.5, -0.5, 2.5}; + if ((M_p = GMT_Create_Data (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_CONTAINER_ONLY, NULL, range_p, inc, GMT_GRID_PIXEL_REG, 0, NULL)) == NULL) return (EXIT_FAILURE); + GMT_Put_Matrix (API, M_p, GMT_DOUBLE, 0, coord); + GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, M_p, input_p); + sprintf (args_p, "%s -R-1/3/-1/3 -JX6c -Baf -BWSen+tPixel -O -X8c >> api_matrix_as_grid.ps", input_p); + GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args_p); + GMT_Close_VirtualFile (API, input_p); + + if (GMT_Destroy_Session (API)) return EXIT_FAILURE; + exit (0); +} diff --git a/test/api/api_matrix_as_grid.ps b/test/api/api_matrix_as_grid.ps new file mode 100644 index 00000000000..423919092b3 Binary files /dev/null and b/test/api/api_matrix_as_grid.ps differ diff --git a/test/api/apigrdpix.sh b/test/api/apigrdpix.sh new file mode 100755 index 00000000000..591fdbe7aad --- /dev/null +++ b/test/api/apigrdpix.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# +# Test the C API for passing matrices to grdimage as grids +ps=api_matrix_as_grid.ps +testapi_matrix_as_grid