Skip to content

Commit

Permalink
Let inset begin take -R -J to determine inset size
Browse files Browse the repository at this point in the history
See #5875 for background.  This PR implements that suggestion and adds a new test inset2.sh to demonstrate it.
  • Loading branch information
PaulWessel committed Oct 25, 2021
1 parent 1eb1f11 commit 9db168f
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 13 deletions.
16 changes: 15 additions & 1 deletion doc/rst/source/inset.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Synopsis (begin mode)
[ |-F|\ *box* ]
[ |-M|\ *margins* ]
[ |-N| ]
[ |SYN_OPT-R| ]
[ |SYN_OPT-J| ]
[ |SYN_OPT-V| ]
[ |SYN_OPT--| ]

Expand All @@ -36,7 +38,9 @@ records the current region and projection so that we may return to the initial
plot environment when the inset is completed. The user may select any plot region
and projection once plotting in the inset, but if the first command uses a projection
that leaves off the scale or width then we supply a scale or width to fill the inset as best
as possible, given the inset size and margins (if selected).
as possible, given the inset size and margins (if selected). **Note**: If you wish to let
the inset dimensions be determined by the region and projection that will be used to draw in
the inset, then give these arguments on the **gmt inset begin** command.


Required Arguments (begin mode)
Expand Down Expand Up @@ -74,6 +78,11 @@ Optional Arguments (begin mode)

.. include:: explain_-F_box.rst_

.. |Add_-J| replace:: |Add_-J_links|
.. include:: explain_-J.rst_
:start-after: **Syntax**
:end-before: **Description**

.. _-M:

**-M**\ *margins*
Expand All @@ -87,6 +96,11 @@ Optional Arguments (begin mode)
**-N**
Do NOT clip features extruding outside map inset boundaries [Default will clip].

.. |Add_-R| replace:: This is useful when you want the inset **-R -J** to also determine the inset size. |Add_-R_links|
.. include:: explain_-R.rst_
:start-after: **Syntax**
:end-before: **Description**

.. |Add_-V| replace:: |Add_-V_links|
.. include:: explain_-V.rst_
:start-after: **Syntax**
Expand Down
76 changes: 64 additions & 12 deletions src/inset.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,9 @@ static int parse (struct GMT_CTRL *GMT, struct INSET_CTRL *Ctrl, struct GMT_OPTI
}

if (Ctrl->In.mode == INSET_BEGIN) {
/* Was -R -J given */
/* Was -R -J given? */
n_errors += gmt_M_check_condition (GMT, !Ctrl->D.active, "Option -D is required for gmt inset begin\n");
n_errors += gmt_M_check_condition (GMT, GMT->common.J.active && !GMT->common.R.active[RSET], "Option -J: Requires -R as well!\n");
if (!n_errors && GMT->common.J.active) { /* Compute map height */
if (gmt_map_setup (GMT, GMT->common.R.wesn)) n_errors++;
}
}
else { /* gmt inset end was given, when -D -F -M -N are not allowed */
if (Ctrl->D.active) {
Expand Down Expand Up @@ -219,12 +216,14 @@ static int parse (struct GMT_CTRL *GMT, struct INSET_CTRL *Ctrl, struct GMT_OPTI

EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {
int error = 0, fig, k;
bool exist;
char file[PATH_MAX] = {""}, ffile[PATH_MAX] = {""}, Bopts[GMT_LEN256] = {""};
bool exist, got_RJ = false;
char tag[GMT_LEN16] = {""}, file[PATH_MAX] = {""}, ffile[PATH_MAX] = {""}, Bopts[GMT_LEN256] = {""};
char inset_history[GMT_LEN256] = {""};
double dim[2] = {0.0, 0.0};
FILE *fp = NULL;
struct GMT_CTRL *GMT = NULL, *GMT_cpy = NULL;
struct PSL_CTRL *PSL = NULL; /* General PSL internal parameters */
struct GMT_OPTION *options = NULL;
struct GMT_OPTION *options = NULL, *R = NULL, *J = NULL;
struct INSET_CTRL *Ctrl = NULL;
struct GMTAPI_CTRL *API = gmt_get_api_ptr (V_API); /* Cast from void to GMTAPI_CTRL pointer */

Expand All @@ -240,6 +239,41 @@ EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {
bailout (GMT_NOT_MODERN_MODE);
}

/* Check if -R -J was given explicitly on the command line to define the inset size */
if ((R = GMT_Find_Option (API, 'R', options)) && (J = GMT_Find_Option (API, 'J', options))) { /* Yes they were */
/* Create a mapproject command with -R -J -W -Di to get the dimensions of the inset */
char ofile[GMT_VF_LEN] = {""}, cmd[GMT_LEN128] = {""};
struct GMT_DATASET *Out = NULL;

/* We also will need to make a special gmt.history file for commands to follow in the inset */
sprintf(inset_history, "# GMT 6 Session common arguments shelf\nBEGIN GMT %s\nJ\t%c\nJ%c\t%s\nR\t%s\n", GMT_version(), J->arg[0], J->arg[0], J->arg, R->arg);
/* Open Virtual file to hold the result from mapproject */
if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_OUT|GMT_IS_REFERENCE, NULL, ofile) == GMT_NOTSET)
bailout (API->error);
/* Build the mapproject command that takes no input but returns dimensions in inches. Turn off updating of history file */
sprintf (cmd, "-R%s -J%s -W -Di ->%s --GMT_HISTORY=false", R->arg, J->arg, ofile);
if (GMT_Call_Module (API, "mapproject", GMT_MODULE_CMD, cmd) != GMT_OK) /* Get the inset size via mapproject */
return (API->error);
/* Retrieve the answers */
if ((Out = GMT_Read_VirtualFile (API, ofile)) == NULL)
bailout (API->error);
/* Store the size in dim */
dim[GMT_X] = Out->table[0]->segment[0]->data[GMT_X][0];
dim[GMT_Y] = Out->table[0]->segment[0]->data[GMT_Y][0];
/* Close virtual file and free the Out dataset */
if (GMT_Close_VirtualFile (API, ofile) != GMT_NOERROR)
bailout (API->error);
if (GMT_Destroy_Data (API, &Out) != GMT_OK)
bailout (API->error);
/* Remove the -R -J options from the options list to process below (since we expect -R -J to come from history */
if (GMT_Delete_Option (API, R, &options))
bailout (API->error);
if (GMT_Delete_Option (API, J, &options))
bailout (API->error);
gmt_reload_history (API->GMT); /* Prevent gmt from copying previous -R -J history to this inset */
got_RJ = true; /* Meaning we got the -R -J to be used inside the inset before the inset was finalized */
}

/* Parse the command-line arguments */

if ((GMT = gmt_init_module (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_KEYS, THIS_MODULE_NEEDS, NULL, &options, &GMT_cpy)) == NULL) bailout (API->error); /* Save current state */
Expand All @@ -249,6 +283,8 @@ EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {

/*---------------------------- This is the inset main code ----------------------------*/

if (got_RJ) gmt_M_memcpy (Ctrl->D.inset.dim, dim, 2U, double); /* Copy the saved inset size determined from -R -J above */

fig = gmt_get_current_figure (API); /* Get current figure number */

if ((k = gmt_set_psfilename (GMT)) == GMT_NOTSET) { /* Get hidden file name for PS */
Expand All @@ -258,7 +294,7 @@ EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {

sprintf (file, "%s/gmt.inset.%d", API->gwf_dir, fig); /* Inset information file */

exist = !access (file, F_OK); /* Determine if inset information file exists */
exist = !access (file, F_OK); /* Determine if an inset information file exists */
if (Ctrl->In.mode == INSET_BEGIN && exist) { /* Inset information file already exists which is a failure */
GMT_Report (API, GMT_MSG_ERROR, "In begin mode but inset information file already exists: %s\n", file);
Return (GMT_RUNTIME_ERROR);
Expand All @@ -271,12 +307,17 @@ EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {
if ((PSL = gmt_plotinit (GMT, options)) == NULL) Return (GMT_RUNTIME_ERROR);

if (Ctrl->In.mode == INSET_BEGIN) { /* Determine and save inset attributes */
/* Here we need to compute dimensions and save those plus current -R -J to the inset information file,
* then inset a gsave command, translate origin to the inset, adjust for any margins, compute new scales/widths and maybe
* draw the panel. */
/* Here we need to compute dimensions and save those plus current plot -R -J to the inset information file,
* then inset a gsave command, translate origin to the inset, adjust for any margins, compute new scales/widths
* and maybe draw the panel. */

char *cmd = NULL;

/* Was -R -J given via history? */
if (GMT->common.J.active && gmt_map_setup (GMT, GMT->common.R.wesn)) { /* Compute map height */
Return (GMT_RUNTIME_ERROR);
}

/* OK, no other inset set for this figure (or panel). Save graphics state before we draw the inset */
PSL_command (PSL, "V %% Begin inset\n");

Expand Down Expand Up @@ -315,12 +356,23 @@ EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {
fclose (fp);
GMT_Report (API, GMT_MSG_DEBUG, "inset: Wrote inset settings to information file %s\n", file);
gmt_reset_history (GMT); /* Prevent gmt from copying previous -R -J history to this inset */

if (got_RJ) { /* Must write the given -R -J to inset history so subsequent commands can use them */
gmt_hierarchy_tag (API, GMT_HISTORY_FILE, GMT_OUT, tag);
sprintf (ffile, "%s/%s%s", API->gwf_dir, GMT_HISTORY_FILE, tag);
if ((fp = fopen (ffile, "w")) == NULL) { /* Not good */
GMT_Report (API, GMT_MSG_ERROR, "Cannot create inset history file %s\n", ffile);
Return (GMT_ERROR_ON_FOPEN);
}
fprintf (fp, "%s", inset_history); /* Write just the -R -J history */
fclose (fp);
}
}
else { /* INSET_END */
/* Here we need to finish the inset with a grestore and restate the original -R -J in the history file,
* and finally remove the inset information file */

char tag[GMT_LEN16] = {""}, legend_justification[4] = {""}, pen[GMT_LEN32] = {""}, fill[GMT_LEN32] = {""}, off[GMT_LEN32] = {""};
char legend_justification[4] = {""}, pen[GMT_LEN32] = {""}, fill[GMT_LEN32] = {""}, off[GMT_LEN32] = {""};
double legend_width = 0.0, legend_scale = 1.0;

if (gmt_get_legend_info (API, &legend_width, &legend_scale, legend_justification, pen, fill, off)) { /* Unplaced legend file */
Expand Down
19 changes: 19 additions & 0 deletions test/modern/inset2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# Test the alternative inset form where inset begin takes the -R -J to be used in the inset
# and uses it to determine -D. We plot a coast map in the inset using that size and plot
# a red cross in the middle of the inset and the original map after the inset completes to
# test that we are back to the original Mercator -R -J settings.
gmt begin inset2 ps
gmt grdimage @earth_relief_01m -R-48/-43/-26/-20 -JM16c -B -Cworld
gmt inset begin -DjBR+o0.2c -F+p1p,black -R-80/-28/-43/10 -JM6c
gmt coast -Wthin -Swhite -Ggray
gmt plot -A -Gwhite -W0.25p <<- EOF
-48 -26
-43 -26
-43 -20
-48 -20
EOF
echo 45:30W 23S | gmt plot -Sx4p -W0.25p,red
gmt inset end
echo 45:30W 23S | gmt plot -Sx12p -W1p,red
gmt end show

0 comments on commit 9db168f

Please sign in to comment.