Skip to content

Commit

Permalink
Let inset begin optionally take -R -J to determine inset size instead…
Browse files Browse the repository at this point in the history
… of via -D (#5903)

* Let inset begin take -R -J to determine inset size

See #5875 for background.  This PR implements that suggestion and adds a new test inset2.sh to demonstrate it.

* Create inset2.ps

Add original for inset2.sh test

* Update inset.c

* Clarify margin units
  • Loading branch information
PaulWessel committed Nov 1, 2021
1 parent 81e5779 commit 2cf8546
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 15 deletions.
19 changes: 17 additions & 2 deletions 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,19 +78,30 @@ 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*
This is clearance that is added around the inside of the inset. Plotting will take place
within the inner region only. The margins can be a single value, a pair of values separated by slashes
(for setting separate horizontal and vertical margins), or the full set of four margins (for setting
separate left, right, bottom, and top margins) [no margins].
separate left, right, bottom, and top margins) [no margins]. Append units as desired [Default is set
by :term:`PROJ_LENGTH_UNIT`].

.. _-N:

**-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
3 changes: 2 additions & 1 deletion doc/rst/source/subplot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ Optional Arguments (begin mode)
to the automatic space added for tick marks, annotations, and labels. The margins can be specified as
a single value (for same margin on all sides), a pair of values separated by slashes
(for setting separate horizontal and vertical margins), or the full set of four slash-separated margins
(for setting separate left, right, bottom, and top margins). The actual gap created is always a sum of
(for setting separate left, right, bottom, and top margins). Append units as desired [Default is set
by :term:`PROJ_LENGTH_UNIT`]. The actual gap created is always a sum of
the margins for the two opposing sides (e.g., east plus west or south plus north margins) [Default is
half the primary annotation font size, giving the full annotation font size as the default gap].

Expand Down
82 changes: 70 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,14 @@ EXTERN_MSC int GMT_inset (void *V_API, int mode, void *args) {

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

if (got_RJ) { /* Copy the saved inset size determined from -R -J above */
if (Ctrl->D.inset.dim[GMT_X] > 0.0 || Ctrl->D.inset.dim[GMT_Y] > 0.0) {
GMT_Report (API, GMT_MSG_ERROR, "Cannot define inset size both via -D..,+w as well as -R -J\n");
Return (GMT_RUNTIME_ERROR);
}
gmt_M_memcpy (Ctrl->D.inset.dim, dim, 2U, double);
}

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 +300,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 +313,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 +362,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
Binary file added test/modern/inset2.ps
Binary file not shown.
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 2cf8546

Please sign in to comment.