1 /*
2  * geography.h --
3  *
4  *	This header file declares general structures, constants, and functions
5  *	for basic geographic calculations.  See the Geography(3) man page
6  *	for more information.
7  *
8  * Copyright (c) 2004 Gordon D. Carrie.  All rights reserved.
9  *
10  * Licensed under the Open Software License version 2.1
11  *
12  * Please address questions and feedback to user0@tkgeomap.org
13  *
14  * @(#) $Id: geography.h,v 1.14 2009/10/23 20:37:24 tkgeomap Exp $
15  *
16  ********************************************
17  *
18  */
19 
20 
21 /*
22  * Note:
23  * Default distance units (unless otherwise noted):
24  *   great circle degrees on sphere
25  *   meters on Earth's surface
26  *   meters on plane
27  */
28 
29 #ifndef _GEOGRAPHY_H_
30 #define _GEOGRAPHY_H_
31 
32 #include <float.h>
33 #include <math.h>
34 #include <tcl.h>
35 
36 /*
37  * For C++ compilers, use extern "C"
38  */
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /*
45  * Macro for prototypes, from tcl.h
46  */
47 
48 #undef _ANSI_ARGS_
49 #if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) || defined(USE_PROTOTYPE)
50 #   define _USING_PROTOTYPES_ 1
51 #   define _ANSI_ARGS_(x)	x
52 #   define CONST const
53 #else
54 #   define _ANSI_ARGS_(x)	()
55 #   define CONST
56 #endif
57 
58 /*
59  * EXTERN macro for C++, from tcl.h
60  */
61 
62 #ifdef EXTERN
63 #undef EXTERN
64 #endif
65 
66 #ifdef __cplusplus
67 #   define EXTERN extern "C"
68 #else
69 #   define EXTERN extern
70 #endif
71 
72 /*
73  * Constants for Windows
74  */
75 
76 #if defined(__WIN32__)
77 #ifndef M_PI
78 #define M_PI     3.1415926535897932384626433832795
79 #endif
80 #ifndef M_PI_2
81 #define M_PI_2   1.5707963267948966192313216916398
82 #endif
83 #ifndef M_PI_4
84 #define M_PI_4   0.78539816339744830961566084581988
85 #endif
86 #endif
87 
88 /*
89  * Distance units
90  */
91 
92 #define NMI 1852.0
93 #define SMI 1609.344
94 
95 /*
96  * Angle conversion factors
97  */
98 
99 #define MPERDEG (REarth() * M_PI / 180.0)
100 #define DEGPERM (180.0 / (REarth() * M_PI))
101 #define NMIPERDEG (MPERDEG / NMI)
102 #define SMIPERDEG (MPERDEG / SMI)
103 #define KMPERDEG (MPERDEG / 1000.0)
104 #define RADPERDEG 0.017453292519943294892
105 #define DEGPERRAD 57.29577951308232088
106 #define DEG_INV 0.002777777777777778
107 
108 /*
109  * The following data type stores angle measurements.
110  */
111 
112 typedef int Angle;
113 
114 /*
115  * This structure stores a geopoint - point on the Earth's surface.
116  */
117 
118 typedef struct
119 {
120   Angle			lat;		/* Latitude */
121   Angle			lon;		/* Longitude */
122 } GeoPt;
123 
124 /*
125  * This structure stores a map-point - a point on a 2D map.
126  */
127 
128 typedef struct
129 {
130   float			abs;		/* Abscissa */
131   float			ord;		/* Ordinate */
132 } MapPt;
133 
134 /*
135  * A point in a 3D Cartesian coordinate system with origin at the Earth's,
136  * center, in which Earth has a radius of 1.0.
137  */
138 
139 typedef struct
140 {
141   double		x;
142   double		y;
143   double		z;
144 } CartPt;
145 
146 /*
147  * Global functions
148  */
149 
150 #define CKALLOC Tcl_Alloc
151 #define CKFREE Tcl_Free
152 #define CKREALLOC Tcl_Realloc
153 
154 EXTERN double	REarth _ANSI_ARGS_((void));
155 EXTERN void	SetREarth _ANSI_ARGS_((double r));
156 EXTERN Angle	AngleFmDeg _ANSI_ARGS_((double deg));
157 EXTERN double	AngleToDeg _ANSI_ARGS_((Angle a));
158 EXTERN Angle	AngleFmRad _ANSI_ARGS_((double rad));
159 EXTERN double	AngleToRad _ANSI_ARGS_((Angle a));
160 EXTERN Angle	BadAngle _ANSI_ARGS_((void));
161 EXTERN int	AngleIsOK _ANSI_ARGS_((Angle a));
162 EXTERN int	AngleIsBad _ANSI_ARGS_((Angle a));
163 EXTERN double	ISin _ANSI_ARGS_((Angle a));
164 EXTERN double	ICos _ANSI_ARGS_((Angle a));
165 EXTERN GeoPt	GeoPtFmDeg _ANSI_ARGS_((double dLat, double dLon));
166 EXTERN GeoPt	GeoPtFmRad _ANSI_ARGS_((double dLat, double dLon));
167 EXTERN void	GeoPtGetDeg _ANSI_ARGS_((GeoPt geoPt, double *dLatPtr,
168 			double *dLonPtr));
169 EXTERN void	GeoPtGetRad _ANSI_ARGS_((GeoPt geoPt, double *dLatPtr,
170 			double *dLonPtr));
171 EXTERN CartPt	LatLonToCart _ANSI_ARGS_((GeoPt geoPt));
172 EXTERN int	GeoPtIsSomewhere _ANSI_ARGS_((GeoPt geoPt));
173 EXTERN int	GeoPtIsNowhere _ANSI_ARGS_((GeoPt geoPt));
174 EXTERN GeoPt	GeoPtNowhere _ANSI_ARGS_((void));
175 EXTERN int	MapPtIsSomewhere _ANSI_ARGS_((MapPt mapPt));
176 EXTERN int	MapPtIsNowhere _ANSI_ARGS_((MapPt mapPt));
177 EXTERN MapPt	MapPtNowhere _ANSI_ARGS_((void));
178 EXTERN MapPt	ScaleMapPt _ANSI_ARGS_((MapPt mapPt, double scale));
179 EXTERN GeoPt	GeoStep _ANSI_ARGS_((GeoPt geoPt, Angle dir, Angle dist));
180 EXTERN Angle	GeoDistance _ANSI_ARGS_((GeoPt p1, GeoPt p2));
181 EXTERN double	GeoQuickDistance _ANSI_ARGS_((GeoPt p1, GeoPt p2));
182 EXTERN Angle	Azimuth _ANSI_ARGS_((GeoPt p1, GeoPt p2));
183 EXTERN GeoPt	GCircleX _ANSI_ARGS_((GeoPt ln1pt1, GeoPt ln1pt2, GeoPt ln2pt1,
184 	    		GeoPt ln2pt2));
185 
186 /*
187  * These constants specify relative Cardinal directions.
188  */
189 
190 enum LatSgn {North, Eq, South};
191 enum LonSgn {West, PrMd, East};
192 
193 /*
194  * Global functions for comparing angles and putting them into domains.
195  */
196 
197 EXTERN Angle	DomainLat _ANSI_ARGS_((Angle lat));
198 EXTERN Angle	DomainLon _ANSI_ARGS_((Angle lon, Angle refLon));
199 EXTERN Angle	GwchLon _ANSI_ARGS_((Angle lon));
200 EXTERN GeoPt	DomainLonPt _ANSI_ARGS_((GeoPt geoPt, Angle refLon));
201 EXTERN GeoPt	GwchLonPt _ANSI_ARGS_((GeoPt geoPt));
202 EXTERN enum	LonSgn LonCmp _ANSI_ARGS_((Angle lon0, Angle lon1));
203 EXTERN enum	LatSgn LatCmp _ANSI_ARGS_((Angle lat0, Angle lat1));
204 EXTERN int	AngleCmp _ANSI_ARGS_((Angle d0, Angle d1));
205 EXTERN int	LonBtwn _ANSI_ARGS_((Angle lon, Angle lon0, Angle lon1));
206 EXTERN int	LonBtwn1 _ANSI_ARGS_((Angle lon, Angle lon0, Angle lon1));
207 
208 /*
209  * This structure stores a time instant as a Julian day and seconds
210  * since midnight.
211  */
212 
213 struct GeoTime_Jul {
214     int   day;		/* Julian day */
215     double second;	/* Seconds since midnight */
216 };
217 
218 /*
219  * This structure stores a time instant as a calendar date and clock time.
220  */
221 
222 struct GeoTime_Cal {
223     int year;
224     int month;
225     int day;
226     int hour;
227     int minute;
228     double second;
229 };
230 
231 /*
232  * The following functions convert between time representations.
233  */
234 
235 struct GeoTime_Cal GeoTime_CalSet(int year, int month, int day, int hour,
236 	int minute, double second);
237 struct GeoTime_Jul GeoTime_JulSet(int day, double second);
238 struct GeoTime_Jul GeoTime_CalToJul(struct GeoTime_Cal cal);
239 struct GeoTime_Cal GeoTime_JulToCal(struct GeoTime_Jul jul);
240 void GeoTime_Incr(struct GeoTime_Jul *jul, double ds);
241 int GeoTime_Cmp(struct GeoTime_Jul jul1, struct GeoTime_Jul jul2);
242 double GeoTime_Diff(struct GeoTime_Jul jul1, struct GeoTime_Jul jul2);
243 
244 /*
245  * end block for C++
246  */
247 
248 #ifdef __cplusplus
249 }
250 #endif
251 
252 #endif
253