.\" .\" Copyright (c) 2004 Gordon D. Carrie. All rights reserved. .\" .\" Licensed under the Open Software License version 2.1 .\" .\" Please address questions and feedback to user0@tkgeomap.org .\" .\" @(#) $Id: geography.3,v 1.11 2007/04/20 15:08:58 tkgeomap Exp $ .\" .so man.macros .TH geography 3 2 Geography "Geography C functions" .SH NAME REarth, SetREarth, BadAngle, AngleIsOK, AngleIsBad, AngleFmDeg, AngleToDeg, AngleFmRad, AngleToRad, ISin, ICos, GeoPtSetDeg, GeoPtSetRad, GeoPtGetDeg, GeoPtGetRad, GeoPtIsSomewhere, GeoPtIsNowhere, GeoPtNowhere, MapPtIsSomewhere, MapPtIsNowhere, MapPtNowhere, ScaleMapPt, GeoStep, GeoDistance, GeoQuickDistance, Azimuth, GCircleX, DomainLat, DomainLon, GwchLon, DomainLonPt, GwchLonPt, LonCmp, LatCmp, AngleCmp, LonBtwn, LonBtwn1, Rotation, NewRotation, SetRotation, GetRotation, DeleteRotation, Rotate, GeoTime_CalSet, GeoTime_JulSet, GeoTime_CalToJul, GeoTime_JulToCal, GeoTime_Incr, GeoTime_Cmp, GeoTime_Diff \- basic geographic calculations and comparisons. .SH SYNOPSIS .nf \fB#include \fR .sp \fBdouble REarth(\fIvoid\fB);\fR \fBvoid SetREarth(double \fIr\fB);\fR .sp \fBAngle AngleFmDeg(double \fIdeg\fB);\fR \fBdouble AngleToDeg(Angle \fIa\fB);\fR \fBAngle AngleFmRad(double \fIrad\fB);\fR \fBdouble AngleToRad(Angle \fIa\fB);\fR \fBAngle BadAngle(\fIvoid\fB);\fR \fBint AngleIsOK(Angle \fIa\fB);\fR \fBint AngleIsBad(Angle \fIa\fB);\fR \fBdouble ISin(Angle \fIa\fB);\fR \fBdouble ICos(Angle \fIa\fB);\fR \fBGeoPt GeoPtFmDeg(double \fIdLat\fB, double \fIdLon\fB);\fR \fBGeoPt GeoPtFmRad(double \fIdLat\fB, double \fIdLon\fB);\fR \fBvoid GeoPtGetDeg(GeoPt \fIgeoPt\fB, double *\fIdLatPtr\fB, double *\fIdLonPtr\fB);\fR \fBvoid GeoPtGetRad(GeoPt \fIgeoPt\fB, double *\fIdLatPtr\fB, double *\fIdLonPtr\fB);\fR \fBCartPt LatLonToCart(GeoPt \fIgeoPt\fB);\fR \fBint GeoPtIsSomewhere(GeoPt \fIgeoPt\fB);\fR \fBint GeoPtIsNowhere(GeoPt \fIgeoPt\fB);\fR \fBGeoPt GeoPtNowhere(\fIvoid\fB);\fR \fBint MapPtIsSomewhere(MapPt \fImapPt\fB);\fR \fBint MapPtIsNowhere(MapPt \fImapPt\fB);\fR \fBMapPt MapPtNowhere(\fIvoid\fB);\fR .sp \fBMapPt ScaleMapPt(MapPt \fImapPt\fB, double \fIscale\fB);\fR \fBGeoPt GeoStep(GeoPt \fIgeoPt\fB, Angle \fIdir\fB, Angle \fIdist\fB);\fR \fBAngle GeoDistance(GeoPt \fIp1\fB, GeoPt \fIp2\fB);\fR \fBdouble GeoQuickDistance(GeoPt \fIp1\fB, GeoPt \fIp2\fB);\fR \fBAngle Azimuth(GeoPt \fIp1\fB, GeoPt \fIp2\fB);\fR \fBGeoPt GCircleX(GeoPt \fIln1pt1\fB, GeoPt \fIln1pt2\fB, GeoPt \fIln2pt1\fB, GeoPt \fIln2pt2\fB);\fR .sp \fBAngle DomainLat(Angle \fIlat\fB);\fR \fBAngle DomainLon(Angle \fIlon\fB, Angle \fIrefLon\fB);\fR \fBAngle GwchLon(Angle \fIlon\fB);\fR \fBGeoPt DomainLonPt(GeoPt \fIgeoPt\fB, Angle \fIrefLon\fB);\fR \fBGeoPt GwchLonPt(GeoPt \fIgeoPt\fB);\fR \fBenum LonSgn LonCmp(Angle \fIlon0\fB, Angle \fIlon1\fB);\fR \fBenum LatSgn LatCmp(Angle \fIlat0\fB, Angle \fIlat1\fB);\fR \fBint AngleCmp(Angle \fId0\fB, Angle \fId1\fB);\fR \fBint LonBtwn(Angle \fIlon\fB, Angle \fIlon0\fB, Angle \fIlon1\fB);\fR \fBint LonBtwn1(Angle \fIlon\fB, Angle \fIlon0\fB, Angle \fIlon1\fB);\fR .sp \fBRotation NewRotation(double \fIangle\fB);\fR \fBvoid SetRotation(Rotation \fIrxn\fB, double \fIangle\fB);\fR \fBvoid DeleteRotation(Rotation \fIrxn\fB);\fR \fBdouble GetRotation(Rotation \fIrxn\fB);\fR \fBMapPt Rotate(MapPt \fImapPt\fB, Rotation \fIrxn\fB);\fR .sp \fBstruct GeoTime_Cal\fR \fBGeoTime_CalSet\fR(\fBint\fR \fIyear\fR, \fBint\fR \fImonth\fR, \fBint\fR \fIday\fR, \fBint\fR \fIhour\fR, \fBint\fR \fIminute\fR, \fBfloat\fR \fIsecond\fR); \fBstruct GeoTime_Jul\fR \fBGeoTime_JulSet\fR(\fBint\fR \fIday\fR, \fBfloat\fR \fIsecond\fR); \fBstruct GeoTime_Jul\fR \fBGeoTime_CalToJul\fR(\fBstruct GeoTime_Cal\fR \fIcal\fR); \fBstruct GeoTime_Cal\fR \fBGeoTime_JulToCal\fR(\fBstruct GeoTime_Jul\fR \fIjul\fR); \fBvoid\fR \fBGeoTime_Incr\fR(\fBstruct GeoTime_Jul\fR *\fIjul\fR, \fBdouble\fR \fIds\fR); \fBint\fR \fBGeoTime_Cmp\fR(\fBstruct GeoTime_Jul\fR \fIjul1\fR, \fBstruct GeoTime_Jul\fR \fIjul2\fR); \fBfloat\fR \fBGeoTime_Diff\fR(\fBstruct\fR \fBGeoTime_Jul\fR \fIjul1\fR, \fBstruct\fR \fBGeoTime_Jul\fR \fIjul2\fR); .fi .SH DESCRIPTION These functions do calculations with geographic locations. Unless otherwise noted, latitudes and longitudes are measured in degrees, distances in great circle degrees, azimuths (directions) in degrees clockwise from north, and distances on the plane in meters. Calculations assume a spherical Earth. .PP Most geography functions require that angles be given as the Angle data type. Functions should convert between double values giving degree and radian measurements and Angle values using the \fBAngleFmDeg\fR, \fBAngleToDeg\fR, \fBRadFmDeg\fR, and \fBRadToDeg\fR functions described below. Currently, the Angle data type is an integer giving the angle in microdegrees. Using integers helps reduce round off errors. A microdegree of latitude is about 0.11 meters. .PP A geographic point is a latitude-longitude pair. It is represented by the GeoPt data type, declared as follows: .CS typedef struct { Angle \fIlat\fR; Angle \fIlon\fR; } GeoPt; .CE .PP "Map point" refers to an abscissa-ordinate pair on a 2D map. It is represented by the \fBMapPt\fR data type, declared as follows: .CS typedef struct { float \fIabs\fR; float \fIord\fR; } MapPt; .CE .PP The \fBBadAngle\fR procedure returns a bogus Angle value. It can be used to indicate an error condition. \fBAngleIsOK\fR returns true if \fIa\fR is not the value returned by \fBBadAngle\fR. \fBAngleIsBad\fR returns true if \fIa\fR is the value returned by \fBBadAngle\fR. .PP \fBAngleFmDeg\fR returns the Angle corresponding to \fIdeg\fR degrees. It returns \fBBadAngle()\fR if \fIdeg\fR is out of range. \fBAngleToDeg\fR returns the degree measure corresponding to Angle \fIa\fR. \fBAngleFmRad\fR returns the Angle corresponding to \fIrad\fR radians. It returns \fBBadAngle()\fR if \fIrad\fR is out of range. \fBAngleToRad\fR returns the radian measure corresponding to Angle \fIa\fR. .PP \fBREarth\fR returns the radius of the Earth, in meters. \fBSetREarth\fR sets the radius of the Earth to new value \fIr\fR assumed to be given in meters. .PP \fBGeoPtFmDeg\fR returns a geopoint with latitude \fIlat\fR and longitude \fIlon\fR, given as decimal degrees. It returns \fBGeoPtNowhere()\fR if either \fIlat\fR or \fIlon\fR is out of range for the Angle data type. .PP \fBGeoPtGetDeg\fR puts the latitude and longitude values from \fIgeoPt\fR into \fIlatPtr\fR and \fIlonPtr\fR as decimal degrees. .PP \fBGeoPtFmRad\fR returns a geopoint with latitude \fIlat\fR and longitude \fIlon\fR, given as decimal radians. It returns \fBGeoPtNowhere()\fR if either \fIlat\fR or \fIlon\fR is out of range for the Angle data type. .PP \fBGeoPtGetRad\fR puts the latitude and longitude values from \fIgeoPt\fR into \fIlatPtr\fR and \fIlonPtr\fR as decimal radians. .PP \fBGeoPtNowhere\fR returns a bogus geographic point. Functions should return \fBGeoPtNowhere()\fR when asked to perform undefined calculations, such as finding the intersection of parallel lines. \fBGeoPointIsSomewhere\fR and \fBGeoPtIsNowhere\fR test for bogus points. \fBGeoPtIsNowhere\fR returns true if given the result of \fBGeoPtNowhere\fR, otherwise false. \fBGeoPtIsSomewhere\fR returns false if given the result of \fBGeoPtNowhere\fR, otherwise true. .PP \fBMapPtNowhere\fR returns a bogus map point. It serves the same purpose as \fBGeoPtNowhere\fR. \fBMapPtIsNowhere\fR returns true if given the result of \fBMapPtNowhere\fR, otherwise false. \fBMapPtIsSomewhere\fR returns false if given the result of \fBMapPtNowhere\fR, otherwise true. .PP \fBScale\fR scales the abscissa and ordinate of \fImapPt \fR by the given value and returns the scaled map point. .PP \fBGeoStep\fR returns a geographic point at distance \fIdist\fR and direction \fIdir\fR from geographic point \fIgeoPt\fR . .PP \fBGeoDistance\fR returns the distance between two geographic points \fIp1\fR and \fIp2\fR. .PP \fBGeoQuickDistance\fR returns the absolute distance between geographic points \fIp1\fR and \fIp2\fR in 3D Cartesian space with origin at Earth's center and in which Earth has unit radius. This is faster than computing the distance in great circle degrees, making it useful for repeated comparisons. .PP \fBAzimuth\fR returns the azimuth from geographic point \fIp1\fR to geographic point \fIp2\fR clockwise from North. .PP \fBGCircleX\fR returns the intersection of two great circles, identified by two points on each. The first great circle contains points \fIln1pt1\fR and \fIln1pt2\fR. The second great circle contains points \fIln2pt1\fR and \fIln2pt2\fR. Great circles intersect at two points. \fBGCircleX\fR returns the intersection closer to the average position of the four given points. It returns \fBGeoPtNowhere()\fR if all four points are on the same great circle. .SH ANGLE COMPARISONS .PP The following functions compare latitude and longitude values or modify them so that they are more appropriate for geographic calculations. Note that angle arguments are given with the Angle data type. Angles can be converted between the internal representation and double degree values with the \fBAngleToDeg\fR and \fBAngleFmDeg\fR functions declared in \fBgeography.h\fR. .PP Comparison results have values .CS enum LatSgn {\fBNorth\fR, \fBEq\fR, \fBSouth\fR}; enum LonSgn {\fBWest\fR, \fBPrMd\fR, \fBEast\fR}; .CE where \fBNorth\fR and \fBEast\fR mean more positive, \fBEq\fR (Equator) and \fBPrMD\fR (Prime Meridian) mean equal, and \fBSouth\fR and \fBWest\fR mean more negative. The comparison functions should be used when comparing latitudes and longitudes to reduce the effect of round off errors and to take account of discontinuities on the globe (e.g. 170 E is usually considered to be west of 170 W). .PP \fBDomainLat\fR returns a latitude value with the same sine as \fIlat\fR in the range .CS -pi / 2 <= latitude <= pi / 2 .CE .PP \fBDomainLon\fR returns a longitude value equivalent to \fIlon\fR in the range .CS rLon - pi <= longitude <= rLon + pi .CE \fBGwchLon\fR(\fIlon\fR) is the same as \fBDomainLon\fR(\fIlon\fR, \fB0\fR). \fBDomainLonPt\fR(\fIgeoPt, rLon\fR) returns a point at the same location as \fIgeoPt\fR with a longitude value within 180 degrees of rLon. \fBGwchLonPt\fR(\fIgeoPt\fR) is the same as \fBDomainLonPt\fR(\fIgeoPt\fR, \fB0\fI). .PP \fBLonCmp\fR returns \fBEast\fR if \fIlon0\fR is east of \fIlon1\fR, \fBPrMd\fR if \fIlon0\fR and \fIlon1\fR are on the same meridian, and \fBWest\fR if \fIlon0\fR is west of \fIlon1\fR. It makes the comparison on the smaller arc connecting the meridians for \fIlon0\fR and \fIlon1\fR. .PP \fBLatCmp\fR returns \fBNorth\fR if \fIlat0\fR is north of \fIlat1\fR, \fBEq\fR if \fIlat0\fR is the same latitude as \fIlat1\fR, and \fBSouth\fR if \fIlat0\fR is south of \fIlat1\fR. .PP \fBAngleCmp\fR returns -1 if \fId0\fR < \fId1\fR, 0 if \fId0\fR == \fId1\fR, and 1 if \fId0\fR > \fId1\fR .PP \fBLonBtwn\fR returns true if longitude \fIlon\fR is between \fIlon0\fR and \fIlon1\fR. Otherwise it returns false. .PP \fBLonBtwn1\fR returns true if \fIlon\fR is between \fIlon0\fR and \fIlon1\fR, or \fIlon\fR is equal to \fIlon0\fR, or \fIlon\fR is equal to \fIlon1\fR. Otherwise it returns false. .SH ROTATING MAP POINTS The following functions rotate map points about the origin. Rotation information is stored in objects of type \fBRotation\fR. .PP \fBNewRotation\fR creates a new \fBRotation\fR structure. It returns the new rotation, or \fBNULL\fR if there is a failure. When no longer needed, the rotation should be destroyed with a call to \fBDeleteRotation\fR. .PP \fBDeleteRotation\fR eliminates \fIrxn\fR and associated storage. .PP \fBSetRotation\fR changes the rotation angle of \fIrxn\fR to \fIangle\fR. .PP \fBGetRotation\fR returns the rotation angle currently residing in \fIrxn\fR. .SH TIME VALUES The GeoTime functions store and manipulate time values stored in either of two structures. Structures of form: .CS struct GeoTime_Jul { int day; float second; }; .CE store a time instant as a Julian day and seconds within that day. \fBGeoTime_JulSet\fR returns a \fBGeoTime_Jul\fR struct with the given \fIday\fR and \fIsecond\fR values. Structures of form: .CS struct GeoTime_Cal { int year; int month; int day; int hour; int minute; float second; }; .CE store a time instant with its calendar and clock values. \fBGeoTime_CalSet\fR returns a structure containing the given \fIyear\fR, \fImonth\fR, \fIday\fR, \fIhour\fR, \fIminute\fR, and \fIsecond\fR. \fBGeoTime_CalToJul\fR returns the Julian representation of a given calendar time. \fBGeoTime_JulToCal\fR returns the calendar representation of a given Julian time. \fBGeoTime_Incr\fR increments \fIjul\fR by \fIds\fR seconds. \fBGeoTime_Cmp\fR returns \fB-1\fR if \fIjul1\fR is before \fIjul2\fR, \fB1\fR if \fIjul1\fR is after \fIjul2\fR or \fB0\fR if \fIjul1\fR and \fIjul2\fR are the same time. \fBGeoTime_Diff\fR returns \fIjul1\fR minus \fIjul2\fR in seconds. .SH "SEE ALSO" geoProj(3) .SH KEYWORDS geography, geographic point, map point, distance, azimuth .SH AUTHOR Gordon Carrie (user0@tkgeomap.org)