MCPcopy Create free account
hub / github.com/GenericMappingTools/gmt / gmtplot_geo_polygon

Function gmtplot_geo_polygon

src/gmt_plot.c:4380–4617  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4378#endif
4379
4380GMT_LOCAL uint64_t gmtplot_geo_polygon (struct GMT_CTRL *GMT, double *lon, double *lat, uint64_t n, bool init, const char *comment) {
4381 /* When geographic data are plotted, polygons that cross the west map boundary will
4382 * sometimes appear on the area bounded by the east map boundary - they "wrap around".
4383 * This usually means we have a global map with (east-west) = 360.
4384 * This function solves this by determining the polygon outline three times:
4385 * First time: Truncate polygon between left and right border
4386 * Second time: Find where the polygon jumps and set all the points between jumps to
4387 * the point on the west boundary at the same latitude.
4388 * Third time: Find where the polygon jumps and set all the points between jumps to
4389 * the point on the east boundary at the same latitude.
4390 * In reality it depends on the nature of the first jump in which order we do the
4391 * west and east truncation above.
4392 * If the polygon is clipped or wraps around at a periodic boundary then we must
4393 * be careful how we draw the outline (if selected). This function only lays down
4394 * the paths; filling/outline is controlled by higher powers (gmt_geo_polygons).
4395 */
4396
4397#define JUMP_L 0
4398#define JUMP_R 1
4399#define JUMP_B 0
4400#define JUMP_T 1
4401
4402 uint64_t total = 0;
4403 double *xp = NULL, *yp = NULL;
4404 struct PSL_CTRL *PSL= GMT->PSL;
4405
4406 if (gmt_M_eq (PSL->current.rgb[PSL_IS_FILL][0], -1.0)) {
4407 /* Just draw optional outline, no fill, nor pattern */
4408 }
4409 else if (gmt_M_is_azimuthal (GMT) || !GMT->current.map.is_world) { /* Testing without !is_world map to rediscover the original issue */
4410 /* Because points way outside the map might get close to the antipode we must
4411 * clip the polygon first. The new radial clip handles this by excluding points
4412 * beyond the horizon and adding arcs along the boundary between exit points
4413 */
4414
4415 if ((GMT->current.plot.n = gmt_clip_to_map (GMT, lon, lat, n, &xp, &yp)) == 0) return 0; /* All points are outside region */
4416 //gmtplot_dumpfile (GMT, GMT->current.plot.x, GMT->current.plot.y, GMT->current.plot.pen, GMT->current.plot.n, "raw.txt");
4417
4418 if (init) {
4419 PSL_comment (PSL, "Temporarily set FO to P for complex polygon building\n");
4420 PSL_command (PSL, "/FO {P}!\n"); /* Temporarily replace FO so we can build a complex path of closed polygons using {P} */
4421 }
4422 PSL_comment (PSL, comment);
4423 PSL_plotpolygon (PSL, xp, yp, (unsigned int)GMT->current.plot.n); /* Fill Cartesian polygon and possibly draw outline */
4424 /* Free the memory we are done with */
4425 gmt_M_free (GMT, xp);
4426 gmt_M_free (GMT, yp);
4427 total = GMT->current.plot.n;
4428 }
4429 else if (GMT->current.proj.projection_GMT == GMT_TM && gmt_M_360_range (GMT->common.R.wesn[XLO], GMT->common.R.wesn[XHI])) { /* Here, any jumps are in the y-direction */
4430 uint64_t k, first, i;
4431 int jump_dir = JUMP_B;
4432 bool jump, plot_main = true;
4433 double y_on_border[2] = {GMT->current.proj.rect[YHI], GMT->current.proj.rect[YLO]};
4434
4435 /* Here we come for the periodic Transverse Mercator projection where longitude wrapping happens in the y-direction */
4436
4437 if ((GMT->current.plot.n = gmt_geo_to_xy_line (GMT, lon, lat, n)) == 0) return 0; /* Convert to (x,y,pen) - return if nothing to do */

Callers 2

Calls 7

gmt_clip_to_mapFunction · 0.85
PSL_commentFunction · 0.85
PSL_commandFunction · 0.85
PSL_plotpolygonFunction · 0.85
gmt_geo_to_xy_lineFunction · 0.85
GMT_ReportFunction · 0.85
gmt_half_map_widthFunction · 0.85

Tested by

no test coverage detected