Skip to content

Commit 572db41

Browse files
authored
Let us have the Spilhaus projection accessible from pscoast.c (#8745)
* Let us have the Spilhaus projection accessible from pscoast.c For this, it was necessary to add the -g option to pscoast and make a gap detection in gmt_geo_to_xy_line(). We can not yet do the interrupted graticule nor plot a frame. * Use a default -g in pscoast when proj is Spilhaus * Fix issues with scale and frame drawing. Now we can use -B * Document -g in pscoast. Make Spilhaus parameters as #defines. Shut up (avoid them) PROJ warnings.
1 parent 0bd8acb commit 572db41

File tree

9 files changed

+232
-126
lines changed

9 files changed

+232
-126
lines changed

doc/rst/source/coast.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Synopsis
3636
[ |SYN_OPT-Y| ]
3737
[ |SYN_OPT-bo| ]
3838
[ |SYN_OPT-d| ]
39+
[ |SYN_OPT-g| ]
3940
[ |SYN_OPT-p| ]
4041
[ |SYN_OPT-t| ]
4142
[ |SYN_OPT--| ]
@@ -290,6 +291,15 @@ Optional Arguments
290291
.. |Add_-d| unicode:: 0x20 .. just an invisible code
291292
.. include:: explain_-d.rst_
292293

294+
.. _-g:
295+
296+
**-gD**\ *dist*
297+
Short version of the global **-g** option. Here it is used to set the _dist_ distance, in map units,
298+
higher then which we consider to have a gap. Useful for the Spilhaus projection (though we automatically set it)
299+
and when line wrapping on dateline was not correctly detected. As an example of this, see for instance
300+
the old issue `#3667 <https://github.com/GenericMappingTools/gmt/issues/3667>`_ that can be fixed
301+
by adding **-gD**\ 1 to the command line.
302+
293303
.. |Add_perspective| unicode:: 0x20 .. just an invisible code
294304
.. include:: explain_perspective.rst_
295305

doc/rst/source/pscoast.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Synopsis
3737
[ |SYN_OPT-X| ]
3838
[ |SYN_OPT-Y| ]
3939
[ |SYN_OPT-bo| ]
40+
[ |SYN_OPT-g| ]
4041
[ |SYN_OPT-p| ]
4142
[ |SYN_OPT-t| ]
4243
[ |SYN_OPT--| ]

src/gmt_init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18546,7 +18546,7 @@ int gmt_parse_common_options (struct GMT_CTRL *GMT, char *list, char option, cha
1854618546
if (GMT->current.gdal_read_in.hCT_inv) OCTDestroyCoordinateTransformation(GMT->current.gdal_read_in.hCT_inv);
1854718547
GMT->current.gdal_read_in.hCT_fwd = gmt_OGRCoordinateTransformation (GMT, source, dest);
1854818548
GMT->current.gdal_read_in.hCT_inv = gmt_OGRCoordinateTransformation (GMT, dest, source);
18549-
GMT->current.proj.projection = GMT_PROJ4_PROJS; /* This now make it use the proj4 lib */
18549+
GMT->current.proj.projection = strstr(dest, "spilhaus") ? GMT_PROJ4_SPILHAUS : GMT_PROJ4_PROJS; /* Special case for spilhaus */
1855018550
GMT->common.J.active = true;
1855118551
if (GMT->current.gdal_read_in.hCT_fwd == NULL || GMT->current.gdal_read_in.hCT_inv == NULL)
1855218552
error = 1;

src/gmt_map.c

Lines changed: 179 additions & 118 deletions
Large diffs are not rendered by default.

src/gmt_plot.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3029,7 +3029,8 @@ GMT_LOCAL void gmtplot_map_boundary (struct GMT_CTRL *GMT) {
30293029
if ((way = gmtlib_adjust_we_if_central_lon_set (GMT, &w, &e)))
30303030
GMT_Report (GMT->parent, GMT_MSG_DEBUG, "W/E boundaries shifted by %d\n", way * 360);
30313031

3032-
PSL_comment (PSL, "Start of map frame\n");
3032+
if (!PSL->internal.comments) PSL_command(PSL, "\n%%Start of map frame\n");
3033+
PSL_comment(PSL, "Start of map frame\n");
30333034

30343035
gmt_setpen (GMT, &GMT->current.setting.map_frame_pen);
30353036
PSL_setcolor (PSL, GMT->current.setting.map_frame_pen.rgb, PSL_IS_STROKE);
@@ -3088,8 +3089,13 @@ GMT_LOCAL void gmtplot_map_boundary (struct GMT_CTRL *GMT) {
30883089
case GMT_VANGRINTEN:
30893090
gmtplot_basic_map_boundary (GMT, PSL, w, e, s, n);
30903091
break;
3092+
case GMT_PROJ4_SPILHAUS:
3093+
gmtplot_linear_map_boundary(GMT, PSL, w, e, s, n);
3094+
break;
30913095
}
3092-
PSL_comment (PSL, "End of map frame\n");
3096+
3097+
PSL_comment(PSL, "End of map frame\n");
3098+
if (!PSL->internal.comments) PSL_command(PSL, "\n%%End of map fram\n");
30933099
}
30943100

30953101
/* gmt_map_basemap will create a basemap for the given area.

src/gmt_proj.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@
9090
#define GMT_PROJ_CONV_LIMIT 1e-9
9191
#define gmt_M_proj_is_zero(x) (fabs (x) < GMT_PROJ_CONV_LIMIT)
9292

93+
/* The Spilhaus proj is f. The points bellow were obtained by projecting a global grid at 1
94+
deg resolution with gdalwarp and inverting the UL and LR coordinates. But even those
95+
had to be moved a bit to inside (by trial en error). Couldn't do the same to the other
96+
two corners because permanently got Inf's. This could probably still be refined a tinny bit.
97+
They are good for global maps, but will be in excess for some local -R. However, given
98+
the complexity of the projection, it is not worth the effort to determine them for all
99+
cases. Anyway, the beauty of the Spilhaus projection is when applyied to the whole world,
100+
so it is not a big deal.
101+
*/
102+
#define GMT_PROJ_SPILH_LON_UL -113.0447807067042
103+
#define GMT_PROJ_SPILH_LAT_UL 49.56674656682158
104+
#define GMT_PROJ_SPILH_LON_LR -113.06804976730443
105+
#define GMT_PROJ_SPILH_LAT_LR 49.553963054590234
106+
93107
GMT_LOCAL double gmtproj_robinson_spline (struct GMT_CTRL *GMT, double xp, double *x, double *y, double *c) {
94108
/* Returns the interpolated value y(xp) from the Robinson coefficients */
95109

src/gmt_project.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ enum gmt_enum_misc {GMT_MOLLWEIDE = 400,
120120
GMT_WINKEL};
121121

122122
/* All projections from proj.4 lib */
123-
enum gmt_enum_allprojs {GMT_PROJ4_PROJS = 500};
123+
#define gmt_M_is_proj4(C) (C->current.proj.projection / 100 == 5)
124+
enum gmt_enum_allprojs {GMT_PROJ4_PROJS = 500,
125+
GMT_PROJ4_SPILHAUS,
126+
};
124127

125128
/*! The various GMT measurement units */
126129
enum gmt_enum_units {GMT_IS_METER = 0,

src/grdimage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1518,7 +1518,7 @@ EXTERN_MSC int GMT_grdimage(void *V_API, int mode, void *args) {
15181518

15191519
/* Determine if grid/image is to be projected */
15201520
need_to_project = (gmt_M_is_nonlinear_graticule (GMT) || Ctrl->E.dpi > 0);
1521-
if (need_to_project && GMT->current.proj.projection == GMT_PROJ4_PROJS) {
1521+
if (need_to_project && gmt_M_is_proj4(GMT)) {
15221522
if (GMT->current.proj.is_proj4)
15231523
if (strstr(GMT->common.J.proj4string, "longlat") || strstr(GMT->common.J.proj4string, "lonlat") || strstr(GMT->common.J.proj4string, "latlon"))
15241524
need_to_project = false;

src/pscoast.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
#define THIS_MODULE_PURPOSE "Plot continents, countries, shorelines, rivers, and borders"
6060
#define THIS_MODULE_KEYS ">?},>DE-lL"
6161
#define THIS_MODULE_NEEDS "JR"
62-
#define THIS_MODULE_OPTIONS "->BJKOPRUVXYbdptxy" GMT_OPT("Zc")
62+
#define THIS_MODULE_OPTIONS "->BJKOPRUVXYbdgptxy" GMT_OPT("Zc")
6363

6464
#define LAKE 0
6565
#define RIVER 1
@@ -199,10 +199,10 @@ static int usage (struct GMTAPI_CTRL *API, int level) {
199199
if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR);
200200
GMT_Usage (API, 0, "usage: %s %s %s [%s] [%s] [-C<fill>[+l|r]] [-D<resolution>[+f]] [-E%s] "
201201
"[-G[<fill>]] [-F%s] [-I<feature>[/<pen>]] %s [-L%s] [-M] [-N<feature>[/<pen>]] %s%s[-Q] [-S[<fill>]] "
202-
"[-Td%s] [-Tm%s] [%s] [%s] [-W[<feature>/][<pen>]] [%s] [%s] [%s] %s[%s] [%s] [%s] [%s]%s [%s]\n",
202+
"[-Td%s] [-Tm%s] [%s] [%s] [-W[<feature>/][<pen>]] [%s] [%s] [%s] [%s] %s[%s] [%s] [%s] [%s]%s [%s]\n",
203203
name, GMT_J_OPT, GMT_Rgeoz_OPT, GMT_A_OPT, GMT_B_OPT, DCW_OPT, GMT_PANEL, API->K_OPT, GMT_SCALE, API->O_OPT,
204204
API->P_OPT, GMT_TROSE_DIR, GMT_TROSE_MAG, GMT_U_OPT, GMT_V_OPT, GMT_X_OPT, GMT_Y_OPT, GMT_bo_OPT, API->c_OPT,
205-
GMT_do_OPT, GMT_p_OPT, GMT_t_OPT, GMT_colon_OPT, dbg, GMT_PAR_OPT);
205+
GMT_do_OPT, GMT_g_OPT, GMT_p_OPT, GMT_t_OPT, GMT_colon_OPT, dbg, GMT_PAR_OPT);
206206

207207
if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS);
208208

@@ -268,6 +268,9 @@ static int usage (struct GMTAPI_CTRL *API, int level) {
268268
GMT_Usage (API, 3, "4: Lake in island in lake shores.");
269269
GMT_Usage (API, -2, "Note: When feature-specific pens are used, those not set are deactivated.");
270270
GMT_Option (API, "X,bo,c,do,p,t");
271+
GMT_Usage (API, 1, "\n-gD<dist> Short version of the global -g option. Here it is used to set the distance, in map "
272+
"units, above which we consider to have a gap. Useful for the Spilhaus projection (though we automatically set it) "
273+
"and when line wrapping on dateline was not correctly detected.");
271274
#ifdef DEBUG
272275
GMT_Usage (API, 1, "\n-+<bin> (repeatable up to 16 times)");
273276
GMT_Usage (API, -2, "Plot only the specified bins (debug option).");
@@ -533,6 +536,14 @@ static int parse (struct GMT_CTRL *GMT, struct PSCOAST_CTRL *Ctrl, struct GMT_OP
533536
}
534537
}
535538

539+
/* If Spilhaus projection and no -g used, set a default value. */
540+
if (!GMT->common.g.active && GMT->current.proj.projection == GMT_PROJ4_SPILHAUS) {
541+
gmt_parse_g_option(GMT, "D1");
542+
GMT->common.g.active = true;
543+
if (!((GMT->common.R.wesn[XHI] - GMT->common.R.wesn[XLO]) == 360 && GMT->common.R.wesn[YLO] == -90 && GMT->common.R.wesn[YHI] == 90))
544+
GMT_Report(API, GMT_MSG_WARNING, "Using a non-global region with Spilhaus projection has unknown effects.\n");
545+
}
546+
536547
if ((error = gmt_DCW_list (GMT, &(Ctrl->E.info)))) { /* This is either success or failure... */
537548
if (error != GMT_DCW_LIST)
538549
return (1); /* Not good */

0 commit comments

Comments
 (0)