Using The EMAPF Functions (C)

The EMAPF functions are an extension of the Cmapf functions to accommodate Ellipsoidal Geoids. The Cmapf functions are a library of C-language functions which process geographic and dynamic data between grids and geographical coordinates on a family of conformal map projections. The CMAPF functions assume a spherical shape to the Earth, and map this shape onto Lambert Conformal, Polar Stereographic or Mercator Projections. The EMAPF functions do the same to an ellipsoidal shape for the Earth, which may be chosen from a collection of geoids that have been used for the Earth, including WGS84 currently used by the United States, or the user may specify his own ellipsoidal shape.

The figure of the Earth (its “geoid”) is generally considered to be an ellipsoid, formed by rotating an ellipse, whose minor axis lies along the Earth’s axis, around that same axis. The equator is then a circle, whose radius ARAD is half the major axis of the ellipse, and the half-length of the minor axis, BRAD, may be thought of as the polar radius.

Note: in all cases, North latitudes will be given as positive degrees, South latitudes negative degrees, East longitudes positive degrees and West longitudes negative degrees.

Parameters determining the shape of the geoid, and the scale and orientation of the projection itself, are set in the maparam structure by means of the following three-stage initialization procedure:

Initializing (configuring) the maparam structure:

First Stage – Specifying a Geoid.
NOTE: It is VITAL to FIRST select a geoid. If other routines are given maparam structures with inconsistent geoids, they will return error codes and invalid results.

We can specify the geoid in one of two ways:

  1. Predefined Geoids:
    We have provided a hardwired standard set of Geoids. A listing of the Geoids can be obtained by using the command “listGeoid”, which is a part of the emapf package. It will list on stdout all the geoids in the emapf package by name and by Emapf Index. To specify in your program which geoid to use,

       #include emapf.h
       maparam stcprm;
       char fname[]="WGS84";
       int rc;
         rc = useGeoid(&stcprm, fname) ;

    will place in stcprm the dimensions and eccentricity of the WGS84 geoid, i.e. the standard geoid established as the World Geodetic System in 1984, currently the international standard geoid. Other standard geoids are the International, or HAYFORD, adopted internationally from 1924 to 1967, and the IUGG of 1967, adopted from 1967 to 1984. The name given must match the name of one of the geoids known to useGeoid. Case is ignored. If the specified geoid is not found, useGeoid returns 1, otherwise it returns 0.

  2. User-defined Geoids:
    A user can define his own geoid by providing two of these three items:

    1. arad – Radius of the Equator
    2. brad – Radius from Earth center to Pole
    3. flattening – the ratio (arad-brad)/arad or, equivalently,
      eccentricity – the ratio sqrt((arad^2-brad^2))/arad
       #include emapf.h
       maparam stcprm;
       double arad = 6367.47,eccen = .08;
       double arg1 = arad, arg2 = eccen;
       GSpecType mode = AE;
       int rc;
         rc=mkGeoid(&stcprm, mode, arg1, arg2);

    will place the dimensions and eccentricity for a geoid of the indicated size in stcprm. The function returns zero if successful, one if the data are invalid. The Geoid Specification type GSpecType indicate the nature of the last two arguments provided to mkGeoid. Valid values are:

    • AB: arg1 = arad, arg2 = brad
    • AE: arg1 = arad, arg2 = eccentricity
    • AF: arg1 = arad, arg2 = flattening
    • BE: arg1 = brad, arg2 = eccentricity
    • TST: evaluates consistency of the geoid data already contained in stcprm. Returns 0 if valid and 1 if invalid. arg1 and arg2 will be ignored.

    Note: Most commonly, published geoid parameters will be arad and flattening, the flattening being specified in the form 1.0/###.####. Thus:

         mkGeoid(&stcprm, AF, 6378.1234, 1./298.2);

    To specify a sphere of radius R, use any one of

         mkGeoid(&stcprm, AB, R, R);
         mkGeoid(&stcprm, AF, R, 0);
         mkGeoid(&stcprm, AE, R, 0);
Second Stage – Selecting a Map Projection
After selecting a geoid, a map projection may be selected. To initialize a maparam structure with a Lambert Conformal Projection:

     #include emapf.h
     maparam stcprm;
     double reflon, tnglat;
     int rc;
       useGeoid (&stcprm, "wgs84");
       reflon = -75.; tnglat = 40.;
       rc = stlmbr(&stcprm, tnglat, reflon);

will initialize stcprm to a Lambert Conformal Projection on cone tangent to a WGS 84 Geoid, at latitude 40°N, centered at longitude 75° West. Return Codes: stlmbr will return 0 if the geoid terms in stcprm are consistent, 1 if they are not (e.g. because mkGeoid or useGeoid were not invoked).

Types of projection are determined by the value of tnglat, which ranges from -90° to +90°. If tnglat = 0, the projection is a Mercator Projection. If tnglat = 90 or ‑90, the projection is a Polar Stereographic Projection, centered at the North or South Pole, respectively. For other values of tnglat, the projection is a Lambert Conic Projection which is tangent to the geoid at latitude tnglat. tnglat also defines the width of the cone: it is the angle between the cone and its axis.

Most published maps using the Lambert Conformal Projection do not specify tnglat. Rather, they specify a nominal scale and two reference latitudes. Contrary to popular misconception, these latitudes do not specify circles on the geoid through which the projection cone can be made to pass.

Instead, these are the two latitudes at which the actual scale on the map matches the nominal scale, and consequently are two latitudes where the scale at one is the same as at the other.
For each pair of latitudes, there is only one projection cone which allows this to be true, and that cone is slightly wider (tnglat has greater magnitude) than the cone that passes through the two latitude circles.

The function eqvlat is provided to find the tangent latitude corresponding to the cone for which the scale at each reference latitude is equal to the scale at the other. We have not provided a similar function to determine the alternate cone that passes through the two latitude circles themselves. To compute the tnglat corresponding to two reference latitudes and the geoid configured in stcprm, use:

     maparam stcprm;
     double reflat1, reflat2, tnglat, reflon;
     int rc;
       tnglat = eqvlat(&stcprm, reflat1, reflat2);
       rc = stlmbr(&stcprm, tnglat, reflon);

stcprm is then configured to the projection cone appropriate to the two reference latitudes. It is important to have already partially configured stcprm by selecting a geoid in Stage 1, as the actual value of eqvlat depends on the flattening of the geoid.

Special cases – In the event reflat1 = reflat2, eqvlat returns their common value, corresponding to a cone tangent at that latitude circle. If reflat1 = -reflat2, eqvlat returns 0, corresponding to a cylinder, i.e. to a Mercator projection. If either reflat1 or reflat2 is +90. (or -90.), eqvlat returns +90. (or -90.), corresponding to a polar stereographic projection tangent at the appropriate pole.

Third Stage – Laying out a grid on a selected map projection.
This stage configures the maparam structure with the information to locate the points of a grid on the selected map projection as unrolled onto a flat surface. This allows the emapf routines to relate the X,Y (or (I,J)) coordinates of the grid with the latitude-longitude coordinates of the Earth. Note that the first three configuration stages must be performed before
this final stage.Two alternative means are provided: EitherOne-Point specification or Two-Point specification.

  1. Two-Point Specification:
         double x1, y1,lat1, lon1, x2, y2,lat2, lon2; 
           stcm2p(&stcprm, x1, y1, lat1, lon1, x2, y2, lat2, lon2); 

    configures stcprm so that the grid point with grid coordinates x1,y1 will be located on the map at latitude lat1, longitude lon1, while the grid point x2,y2 is located on the map at lat2, lon2. The two points must be different.

    This specification is sufficient to locate all other grid points, which are assumed to be arranged on the projection with equal spacing in the x- and y- directions.

    The two points will often be chosen as opposite corners of the intended grid with a view to minimize rounding errors in the rest of the grid. But often, a different choice of grid points will be preferred. For example, in a Mercator projection, it is better to choose two points of the same latitude or the same longitude, to ensure exact N-S orientation of the grid. Alternatively, several subgrids of an overall grid may be guaranteed compatibility by using the same two points of the overall grid, even if neither of the points lie in the subgrid at all.

  2. One-Point Specification:
         double x1, y1, lat1, lon1, scalat, scalon, gsize, orient; 
           stcm1p(&stcprm, x1, y1, lat1, lon1, scalat, scalon, gsize, orient); 

    configures stcprm so that the grid point with grid coordinates x1,y1 will be located on the map at latitude lat1, longitude lon1. The information needed to space and orient all other points on the grid is provided at the scaling point whose latitude and longitude are scalat, scalon. At that point, and incidentally every point on the latitude circle scalat, the size of a grid cell is gsize kilometers in both the x- and y- directions, from which the subroutines can compute the grid spacing at all other latitudes. Finally, to orient the other grid points on the map projection, the y-lines of the grid make an angle of “orient” degrees clockwise (East) of the scalon meridian at the scaling point. From this, the orientation of all other grid lines at all other points can be calculated, fully determining the grid on the projection.

    The x1, y1 coordinates can be thought of as “pinning” that grid point to the map at lat1,lon1, the gsize value can be thought of as “zooming” the grid in and out until the desired size is attained, and the “orient” specification can be thought of as rotating the grid about the pinned point until the grid has the wanted orientation.

    Hint:   frequently, a grid will be published as having an “lov” value of a longitude intended to be vertical. For such grids, scalon = lov and orient = 0.

Using the configured maparams:

Once stcprm has been configured to the desired geoid, projection, and grid layout, the following routines will perform two-way transformations of coordinates and wind vectors, and illuminate useful geometry for modelers:

Coordinate transforms:
     maparam stcprm;
     double x, y, lat, lon; 

       cll2xy(&stcprm, lat, lon, &x, &y); 

will return grid coordinates x,y according to the grid configured as stcprm, for the point whose latitude and longitude are lat,lon. Longitude values are adjusted to fit between reflon-180. and reflon+180., so that nearby points on the globe remain nearby points on the map, unless they straddle the “cut” at longitude reflon+180., and find themselves on opposite edges of an unrolled cylinder or cone.

       cxy2ll(&stcprm, x, y, &lat, &lon);

will return latitude and longitude parameters according to the grid configured as stcprm, for the point whose grid coordinates are x,y. Longitude values will be returned in the range from -180. to +180.

If the point x,y corresponds to the North or South Pole, where longitude is undefined, the returned longitude will be 180. for the North Pole, 0. for the South Pole, for compatibility with the WMO standard for reporting winds there. (In an earlier version of CMAPF, the value of reflon was returned here.)

Wind Vector transforms:
     maparam stcprm;
     double x, y, lat, lon; 
     double ue, vn, ug, vg;	
       cc2gll(&stcprm, lat, lon, ue, vn, &ug, &vg);				 
       cg2cll(&stcprm, lat, lon, ug, vg, &ue, &vn);

will convert the East- and North- components ue,vn (Cartographic components) of the wind to and from components ug, vg of the wind in the x- and y- directions of the grid (Grid components). The first transfers from cartographic components to grid components, the second does the reverse. In both cases, the wind is that observed at the specified cartographic coordinates lat, lon.

At the poles (lat = 90. or lat = -90.), the direction of “North”, which determines the meaning of ue and vn, is based on the nominal value of longitude. The direction of North will agree with that perceived by an observer stationed a short distance away on the lon meridian. Thus, if lat,lon = 90.,-70., “North” will be assigned to the direction of the 110°E meridian.

       cc2gxy(&stcprm, x, y, ue, vn, &ug, &vg); 
       cg2cxy(&stcprm, x, y, ug, vg, &ue, &vn); 

will convert the East- and North- components ue,vn (Cartographic components) of the wind to and from components ug, vg of the wind in the x- and y- directions of the grid (Grid components). The first transfers from cartographic components to grid components, the second does the reverse. In both cases, the wind is that observed at the specified grid coordinates x,y.

If x,y refers to the North or to the South pole, the orientation of “North” is defined according to World Meteorological Organization (WMO) code 878. The direction of “North” is that of the Greenwich meridian, which is the equivalent of using lat = 90.,lon = 180. for the North Pole, and lat = -90.,lon = 0. for the South Pole.

     cw2gll(&stcprm, lat, lon, ue, vn, &ug, &vg);
     cg2wll(&stcprm, lat, lon, ug, vg, &ue, &vn); 
     cw2gxy(&stcprm, x, y, ue, vn, &ug, &vg);		  
     cg2wxy(&stcprm, x, y, ug, vg, &ue, &vn);  

perform the same services as the above transforms, except that within 1° (111km or 60nm) or either pole, ue and vn are interpreted according to WMO code 878 above. In an earlier version of CMAPF, this was the definition of the c2g and g2c functions, above.

Gridsize Evaluation:
The scale of the projection varies from one latitude to another, and therefore, the size of each cell of the grid laid out on the projection changes from one point to another. The functions

     maparam stcprm; 
     double x, y, lat, lon, gsize; 
       gsize = cgszll(&stcprm, lat, lon); 
       gsize = cgszxy(&stcprm, x, y); 

return the size, in kilometers, of a grid cell at the indicated  point.
Curvature Vector:
The functions

     maparam stcprm; 
     double x, y, lat, lon, gx, gy; 
       ccrvxy(&stcprm, x, y, &gx, &gy); 
       ccrvll (&stcprm, lat, lon, &gx, &gy); 

return, in gx and gy, the logarithmic gradient of the scale. Units are in radians per kilometer on the Earth’s surface. If a path is drawn on the map that appears to be a straight line, it represents a path on the Earth that may, in fact, be curved. The component of this vector, perpendicular to that path, represents the actual curvature of the path on the Earth. See the paper for details on this vector’s usage in equations.

North Direction Vector and Coriolis evaluations:
     maparam stcprm; 
     double x, y, lat, lon, enx, eny, enz; 
       cpolxy (&stcprm, x, y, &enx, &eny, &enz); 
       cpolll (&stcprm, lat, lon, &enx, &eny, &enz); 

return, in enx, eny, and enz the components of a unit vector in the direction of the Earth’s axis. Components enx and eny provide the local direction of North aligned with grid coordinates, while enz is proportional to the local Coriolis parameter.