Skip to content

Commit

Permalink
Add the testapi code to plot vectors (#3528)
Browse files Browse the repository at this point in the history
* Add the testapi code

* Fix resampling of readonly memory

* Add a bash test for testapi_vector_plot.c

Co-authored-by: Paul Wessel <[email protected]>
  • Loading branch information
seisman and PaulWessel authored Jun 28, 2020
1 parent 2a1a680 commit 5b11244
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 13 deletions.
22 changes: 16 additions & 6 deletions src/psxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,10 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) {

SH = gmt_get_DS_hidden (L);

duplicate = (DH->alloc_mode == GMT_ALLOC_EXTERNALLY && (polygon || gmt_trim_requested (GMT, &current_pen) || GMT->current.map.path_mode == GMT_RESAMPLE_PATH));
if (duplicate) /* Must duplicate externally allocated segment since it needs to be resampled below */
L = gmt_duplicate_segment (GMT, D->table[tbl]->segment[seg]);

resampled = false;
if (!polygon && gmt_trim_requested (GMT, &current_pen)) { /* Needs a haircut */
if (L->n_rows == 2) { /* Given endpoints we need to resample in order to trim */
Expand All @@ -1950,7 +1954,11 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) {
gmt_set_seg_minmax (GMT, D->geometry, 2, L); /* Update min/max of x/y only */
resampled = true; /* To avoid doing it twice */
}
if (gmt_trim_line (GMT, &L->data[GMT_X], &L->data[GMT_Y], &L->n_rows, &current_pen)) continue; /* Trimmed away completely */
if (gmt_trim_line (GMT, &L->data[GMT_X], &L->data[GMT_Y], &L->n_rows, &current_pen)) {
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &L);
continue; /* Trimmed away completely */
}
}

if (D->n_tables > 1)
Expand Down Expand Up @@ -1978,11 +1986,11 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) {
change = gmt_parse_segment_header (GMT, L->header, P, &fill_active, &current_fill, &default_fill, &outline_active, &current_pen, &default_pen, default_outline, SH->ogr);
outline_setting = outline_active ? 1 : 0;
}
if (P && PH->skip) continue; /* Chosen CPT indicates skip for this z */

duplicate = (DH->alloc_mode == GMT_ALLOC_EXTERNALLY && ((polygon && gmt_polygon_is_open (GMT, L->data[GMT_X], L->data[GMT_Y], L->n_rows)) || GMT->current.map.path_mode == GMT_RESAMPLE_PATH));
if (duplicate) /* Must duplicate externally allocated segment since it needs to be resampled below */
L = gmt_duplicate_segment (GMT, D->table[tbl]->segment[seg]);
if (P && PH->skip) {
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &L);
continue; /* Chosen CPT indicates skip for this z */
}

if (L->header && L->header[0]) {
PSL_comment (PSL, "Segment header: %s\n", L->header);
Expand Down Expand Up @@ -2024,6 +2032,8 @@ EXTERN_MSC int GMT_psxy (void *V_API, int mode, void *args) {
GMT_Report (API, GMT_MSG_ERROR, "Segment header did not supply enough parameters for -S~; skipping this segment\n");
else
GMT_Report (API, GMT_MSG_ERROR, "Segment header did not supply enough parameters for -Sq; skipping this segment\n");
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &L);
continue;
}
if (Ctrl->I.active) {
Expand Down
18 changes: 16 additions & 2 deletions src/psxyz.c
Original file line number Diff line number Diff line change
Expand Up @@ -1622,10 +1622,12 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
gmt_reset_meminc (GMT);
}
else { /* Line/polygon part */
bool duplicate = false;
int outline_setting;
uint64_t seg;
struct GMT_DATASET *D = NULL; /* Pointer to GMT segment table(s) */
struct GMT_DATASEGMENT_HIDDEN *SH = NULL;
struct GMT_DATASET_HIDDEN *DH = NULL;

if (GMT_Init_IO (API, GMT_IS_DATASET, geometry, GMT_IN, GMT_ADD_DEFAULT, 0, options) != GMT_NOERROR) { /* Establishes data input */
Return (API->error);
Expand All @@ -1637,6 +1639,7 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
GMT_Report (API, GMT_MSG_ERROR, "Input data have %d column(s) but at least 3 are needed\n", (int)D->n_columns);
Return (GMT_DIM_TOO_SMALL);
}
DH = gmt_get_DD_hidden (D);

if (Zin) { /* Check that the Z file matches our polygon file */
if (Zin->n_records < D->n_segments) {
Expand Down Expand Up @@ -1684,6 +1687,10 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
else
GMT_Report (API, GMT_MSG_INFORMATION, "Plotting segment %" PRIu64 "\n", seg);

duplicate = (DH->alloc_mode == GMT_ALLOC_EXTERNALLY && GMT->current.map.path_mode == GMT_RESAMPLE_PATH && psxyz_no_z_variation (GMT, L));
if (duplicate) /* Must duplicate externally allocated segment since it needs to be resampled below */
L = gmt_duplicate_segment (GMT, D->table[tbl]->segment[seg]);

/* We had here things like: x = D->table[tbl]->segment[seg]->data[GMT_X];
* but reallocating x below lead to disasters. */

Expand All @@ -1706,7 +1713,11 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
outline_setting = outline_active ? 1 : 0;
}

if (P && PH->skip) continue; /* Chosen CPT indicates skip for this z */
if (P && PH->skip) {
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &L);
continue; /* Chosen CPT indicates skip for this z */
}

if (L->header && L->header[0]) {
PSL_comment (PSL, "Segment header: %s\n", L->header);
Expand All @@ -1732,6 +1743,8 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
GMT_Report (API, GMT_MSG_ERROR, "Segment header did not supply enough parameters for -Sf; skipping this segment\n");
else
GMT_Report (API, GMT_MSG_ERROR, "Segment header did not supply enough parameters for -Sq; skipping this segment\n");
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &L);
continue;
}

Expand Down Expand Up @@ -1765,7 +1778,6 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
gmt_set_seg_minmax (GMT, D->geometry, 2, L); /* Update min/max of x/y only */
}


n = (int)L->n_rows; /* Number of points in this segment */
xp = gmt_M_memory (GMT, NULL, n, double);
yp = gmt_M_memory (GMT, NULL, n, double);
Expand Down Expand Up @@ -1895,6 +1907,8 @@ EXTERN_MSC int GMT_psxyz (void *V_API, int mode, void *args) {
gmt_draw_front (GMT, GMT->current.plot.x, GMT->current.plot.y, GMT->current.plot.n, &S.f);
if (S.f.f_pen == 0) gmt_setpen (GMT, &current_pen); /* Reinstate current pen */
}
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &L);

gmt_M_free (GMT, xp);
gmt_M_free (GMT, yp);
Expand Down
15 changes: 11 additions & 4 deletions src/sphdistance.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ static int parse (struct GMT_CTRL *GMT, struct SPHDISTANCE_CTRL *Ctrl, struct GM
#define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); bailout (code);}

EXTERN_MSC int GMT_sphdistance (void *V_API, int mode, void *args) {
bool first = false, periodic, duplicate_col;
bool first = false, periodic, duplicate_col, duplicate = false;
int error = 0, s_row, south_row, north_row, w_col, e_col;

unsigned int row, col, p_col, west_col, east_col, nx1, n_in = 0;
Expand Down Expand Up @@ -479,15 +479,21 @@ EXTERN_MSC int GMT_sphdistance (void *V_API, int mode, void *args) {
duplicate_col = (periodic && Grid->header->registration == GMT_GRID_NODE_REG); /* E.g., lon = 0 column should match lon = 360 column */
gmt_set_inside_mode (GMT, NULL, GMT_IOO_SPHERICAL);

if (Ctrl->Q.active) /* Pre-chewed, just get number of nodes */
if (Ctrl->Q.active) { /* Pre-chewed, just get number of nodes */
struct GMT_DATASET_HIDDEN *QH = gmt_get_DD_hidden (Qin);
n = Table->n_segments;
duplicate = (QH->alloc_mode == GMT_ALLOC_EXTERNALLY);
}
else
V = &T.V;

for (node = 0; node < n; node++) {
GMT_Report (API, GMT_MSG_INFORMATION, "Processing polygon %7ld\r", node);
if (Ctrl->Q.active) { /* Just point to next polygon */
P = Table->segment[node];
if (duplicate) /* Must duplicate externally allocated segment since it needs to be resampled below */
P = gmt_duplicate_segment (GMT, Table->segment[node]);
else
P = Table->segment[node];
}
else { /* Obtain current polygon from Voronoi listings */
if (P == NULL) { /* Need a single polygon structure that we reuse for each polygon */
Expand Down Expand Up @@ -529,7 +535,6 @@ EXTERN_MSC int GMT_sphdistance (void *V_API, int mode, void *args) {
case SPHD_VALUES: f_val = z_val[node]; break;
default: break; /* Must compute distances below */
}

}

/* Here we have the polygon in P */
Expand Down Expand Up @@ -576,6 +581,8 @@ EXTERN_MSC int GMT_sphdistance (void *V_API, int mode, void *args) {
}
}
}
if (duplicate) /* Free duplicate segment */
gmt_free_segment (GMT, &P);
}
GMT_Report (API, GMT_MSG_INFORMATION, "Processing polygon %7ld\n", node);

Expand Down
29 changes: 29 additions & 0 deletions src/testapi_vector_plot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "gmt.h"
int main () {
void *API = NULL; /* The API control structure */
struct GMT_VECTOR *V = NULL; /* Structure to hold input dataset as vectors */
char input[GMT_VF_LEN] = {""}; /* String to hold virtual input filename */
char args[128] = {""}; /* String to hold module command arguments */

uint64_t dim[4] = {2, 2, 1, 0};
double x[2] = {5.0, 5.0};
double y[2] = {3.0, 8.0};

/* Initialize the GMT session */
API = GMT_Create_Session ("test", 2U, GMT_SESSION_EXTERNAL, NULL);
/* Create a dataset */
if ((V = GMT_Create_Data (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_CONTAINER_ONLY, dim, NULL, NULL, 0, 0, NULL)) == NULL) return (EXIT_FAILURE);
/**/
GMT_Put_Vector(API, V, 0, GMT_DOUBLE, x);
GMT_Put_Vector(API, V, 1, GMT_DOUBLE, y);
/* Associate our data table with a virtual file */
//GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, V, input);
GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, V, input);
/* Prepare the module arguments */
sprintf (args, "%s -JX10c -R0/10/0/10 -Baf -W1p,black+ve0.2c -P", input);
/* Call the psxy module */
GMT_Call_Module (API, "psxy", GMT_MODULE_CMD, args);
GMT_Close_VirtualFile (API, input);
/* Destroy the GMT session */
if (GMT_Destroy_Session (API)) return EXIT_FAILURE;
};
Binary file added test/api/apivectorplot.ps
Binary file not shown.
6 changes: 6 additions & 0 deletions test/api/apivectorplot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
#
# Test the C API for plotting lines with arrows
# See https://github.com/GenericMappingTools/gmt/pull/3528
ps=apivectorplot.ps
testapi_vector_plot > $ps
3 changes: 2 additions & 1 deletion test/gmtest.in
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ for apiprog in \
testgrdio \
testapi_imageshading \
testapi_matrix_as_grid \
testapi_vector_strings
testapi_vector_strings \
testapi_vector_plot
do
eval "${apiprog}() { valgrind_wrapper \"@GMT_BINARY_DIR@/src/${apiprog}\" \"\$@\"; }"
done
Expand Down

0 comments on commit 5b11244

Please sign in to comment.