• Antelope Release 5.10 Linux CentOS release 7.6.1810 (Core) 3.10.0 2020-05-12

 

NAME

gshhsmap - GSHHS file reading utilities

SYNOPSIS

#include "gshhsmap.h"

int
gshhs_unstuff_hdr(GSHHSHdr **gshhs, char **stream)

int
gshhs_skip_pts(GSHHSHdr *gshhs, char **stream)

int
gshhsmap_open(void **handle)

int
gshhsmap_select(void *handle, char *types,
	char *resolution, double bb_lonwest,
	double bb_loneast, double bb_latsouth,
	double bb_latnorth, double bb_lonref,
	double bb_latref)

int
gshhsmap_nextseg(void *handle, int *npts,
	int *bufsize, float **lon, float **lat,
	char *type, int *level, int *antipode)

DESCRIPTION

These subroutines provide an interface to the GSHHS format coastline boundary vector data that is included in the Antelope distribution map data directory in $ANTELOPE/data/maps/mappts. These files, named gshhs_c.b, gshhs_f.b, gshhs_h.b, gshhs_i.b, and gshhs_l.b, are exact copies of the same data that can be obtained from the web site at http://www.ngdc.noaa.gov/mgg/shorelines/gshhs.html. The GSSHS vector coastline data, which stands for Global Self-consistent Hierarchical High-resolution Shoreline database, is an extensively processed data set that is available in the public domain from NOAA's National Geophysical Data Center. According to their web site "The data have undergone extensive processing and are free of internal inconsistencies such as erratic points and crossing segments". The data are also arranged as hierarchical closed polygons which is a prerequisite for graphical rendering of these polygons as filled solids.

The subroutines in this utility form two interfaces into the GSHHS files; a generic file unstuffing interface, provided by gshhs_unstuff_hdr and gshhs_skip_pts, and a specialized map coordinate retrieval interface, provided by gshhsmap_open, gshhsmap_select and gshhsmap_nextseg, similar to the gmtmap(3) utility.

GSHHS data files are composed of binary SUN network byte order data arranged as a list of polygon blocks. Each polygon block consists of a binary header block followed by the binary vector polygon boundary data. gshhs_unstuff_header will unstuff a GSHHS polygon block header into an internal C-structure. stream is the byte stream that represents the GSHHS file and can be conveniently obtained with the mapfile(3) subroutine. The header is returned in gshhs which will be either malloc'ed, if the input value is NULL, or reused, if the input value is not NULL. A -1 return value indicates an error. The GSHHSHdr structure is defined in gshhsmap.h as follows:


typedef struct gshhs_hdr_ {	/* Global Self-consistant Hierarchical High-resolution Shorelines Header */
        int id;	                        /* Unique polygon id number, starting at 0 */
        int n;                          /* Number of points in this polygon */
        int level;                      /* 1 land, 2 lake, 3 island_in_lake, 4 pond_in_island_in_lake */
        int west, east, south, north;   /* min/max extent in micro-degrees */
        int area;                       /* Area of polygon in 1/10 km^2 */
        short int greenwich;            /* Greenwich is 1 if Greenwich is crossed */
        short int source;               /* 0 = CIA WDBII, 1 = WVS */
} GSHHSHdr;

After return from gshhs_unstuff_header, the stream pointer is positioned at the start of the vector data portion of the polygon block. A call to gshhs_skip_pts will advance the stream pointer to the next polygon block header.

The gshhsmap_... subroutines are hardwired to look for the particular GSHHS files that are contained in the Antelope distribution. A gshhsmap object must first be created and initialized with a call to gshhsmap_open, which returns a pointer to the object in handle. The new object is malloc'ed if the input handle value is NULL and the object is reused otherwise.

After opening the gshhsmap object, a set of map coordinates can be selected with a call to gshhsmap_select. One or more map types (for this case either coastline boundary or filled land/water mass) and map levels (a map level for these data refers to the level land/water embeddedness, for instance, level 1 coastlines refer to ocean shorelines, level 2 refer to inland lake or sea shorelines, level 3 refer to island-within-lake shorelines, etc.) can be specified in the types string which must be one to four whitespace delimited type-levelbitmap specifications in the form "<type1>:<levelbitmap1> [<type2>:<levelbitmap2> [...]]". The <typeX> specifications must be "c", for coastline boundary, or "f, for filled land/water mass. The <levelbitmapX> specifications are bitmaps in which the LSB corresponds to level 1, etc. Each set bit will cause the return of map coordinates at that level. For example, the types string for map coordinates of filled land/water masses at both the continental and major inland lake/sea levels and also coastline boundaries at only the continental level would be "f:3 c:1". Note that if the <levelbitmapX> specification is set to 0, then no levels and no coordinates will be returned. The desired resolution of the map coordinates is specified with the resolution argument which must be one of "f", for full, "h", for high, "i", for intermediate, "l" for low and "c", for crude. A latitude-longitude bounding box can be specified with the bb_lonwest, ... arguments which will limit the returned map coordinates to those within the bounding box.

Although the actual data points for the c and f map types are the same, the way in which they are ordered are different, so that the f, or filled, map type will produce highly ordered and layered sets of points that are suitable for immediate complex polygon fill rendering. This is supported by the bb_lonref and bb_latref arguments to gshhsmap_select, which should be specified as a geographic coordinate that will be within the rendered map and, for equal distance projections, should be the reference coordinate used to compute the projection. Although no projections are done in these subroutines, the bb_latref,bb_lonref coordinates are used to unwind the map longitude coordinates and to specify an antipodal coordinate (the antipode is compute as -bb_latref, 180.0+bb_lonref). The antipodal coordinate is needed for filled map types in order to determine if it is within a land mass or water mass which is needed to determine what fill color (land or water) to start with in rendering an equal distance projection map.

After the map is selected, then the coordinates can be retrieved with calls to gshhsmap_nextseg. Each call will return the value 1 and fill in the next contiguous set of map coordinates. When there are no more segments for the current map selection, then gshhsmap_nextseg will return 0. After all of the segments have been retrieved, another call to gshhsmap_select can be made to select another set of coordinates and gshhsmap_nextseg can be called again to process the segments from the new selection. The number of points for a particular segment are returned in npts. The map coordinates themselves are returned in the lat and lon floating arrays. The memory for these arrays is dynamically allocated or reused according to the incoming values of lat and lon, along with the bufsize argument. If the input values of lat and lon are NULL, then they are malloc'ed and bufsize is set to the size of the buffers in units of floats. If the input values of lat and lon are not NULL, then they are reused and potentially realloc'ed according to npts and the input value of bufsize. For each segment, the map type ("f" or "c") and level are returned in type and level. For filled map types the antipode returned value indicates if the antipode to the reference coordinate is inside a water mass (returned as 0) or land mass (returned at 1).

EXAMPLE



% cat testgshhs.c

#include <stdlib.h>

#include "brttutil.h"
#include "stock.h"

#include "gshhsmap.h"

int
main (int argc, char **argv)

{
        void *handle = NULL;
        int nsegs, i, j, ret;
        int npts, bufsize = 0;
        float *lat=NULL;
        float *lon=NULL;
        char type[4];
        int level;
        int antipode;

        if (argc != 3) {
                fprintf (stderr, "usage: testgshhs types resolution\n");
                exit (1);
        }

        /* open the gshhsmap */

        if (gshhsmap_open (&handle) < 0) {
                die (0, "gshhsmap_open() error.\n");
        }

        /* select the map */

        nsegs = gshhsmap_select (handle, argv[1], argv[2],
                              -180.0, 180.0, -90.0, 90.0, 0.0, 0.0);
        if (nsegs < 0) {
                die (0, "gshhsmap_select(%s,%s) error.\n", argv[1], argv[2] );
        }

        printf ("gshhsmap_select(%s,%s) returns %d segments\n",
                                        argv[1], argv[2], nsegs);

        /* parse through the first few segments and print
           out a few coordinates */

        for (i=0; i<nsegs; i++) {
                if (i > 3) {
                        printf ("...\n");
                        break;
                }
                ret = gshhsmap_nextseg (handle, &npts, &bufsize,
                                           &lon, &lat, type, &level, &antipode);
                if (ret < 0) {
                        die (0, "gshhsmap_nextseg(%d) fatal error.\n", i);
                }
                if (ret == 0) break;

                printf ("gshhsmap_nextseg(%d) returns %d points for type/level %s:%d%d:\n",
                                                             i, npts, type, level, antipode);
                for (j=0; j<npts; j++) {
                        if (j >= 10) {
                                printf ("\t...\n");
                                break;
                        }
                        printf ("\t%9.4f %8.4f\n", lon[j], lat[j]);
                }
        }

        exit (0);
}

% cat Makefile
BIN = testgshhs

MAN1 =

PF =

ldlibs= -lmappts -lbrttutil -lstock -ldeviants

include $(ANTELOPEMAKE)
DIRS=

OBJS= \
        testgshhs.o

testgshhs : $(OBJS)
        $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)

% testgshhs f:3 c
gshhsmap_select(f:3,c) returns 1840 segments
gshhsmap_nextseg(0) returns 1240 points for type/level l:1:0:
         180.0000  68.9938
         176.0816  69.8837
         173.2232  69.7654
         170.5499  70.1196
         170.1624  69.5975
         171.1792  69.0300
         170.4816  68.7637
         168.3216  69.2221
         167.8084  69.7645
         166.8734  69.4621
        ...
gshhsmap_nextseg(1) returns 969 points for type/level l:1:0:
         286.6383 -53.0004
         287.0224 -53.0824
         287.0732 -52.5563
         288.4549 -52.5689
         288.6508 -53.1275
         288.0333 -53.5788
         288.1449 -53.2313
         287.5158 -53.3950
         288.7166 -53.9004
         289.1171 -52.7390
        ...
gshhsmap_nextseg(2) returns 292 points for type/level l:1:0:
         315.3007  59.9950
         315.8866  60.3529
         316.8609  60.0717
         315.7807  60.5525
         317.1284  60.5462
         316.4708  60.8117
         317.2958  61.0558
         316.3708  61.1241
         317.3616  61.0854
         316.7491  61.3267
        ...
gshhsmap_nextseg(3) returns 197 points for type/level l:1:0:
         360.0000 -68.9258
         358.8521 -68.9460
         359.3480 -69.5892
         357.6267 -70.2006
         352.1315 -70.6533
         350.9827 -70.4266
         347.7882 -71.3590
         347.1135 -72.0321
         344.8961 -72.0800
         342.6167 -72.6742
        ...
 ...

LIBRARY

-lmappts

AUTHOR

Danny Harvey
Printer icon