GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
geodesic.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <grass/gis.h>
3 #include "pi.h"
4 
5 
6 /*
7  * This code is preliminary. I don't know if it is even
8  * correct.
9  */
10 
11 /*
12  * From "Map Projections" by Peter Richardus and Ron K. Alder, 1972
13  * (526.8 R39m in Map & Geography Library)
14  * page 19, formula 2.17
15  *
16  * Formula is the equation of a geodesic from (lat1,lon1) to (lat2,lon2)
17  * Input is lon, output is lat (all in degrees)
18  *
19  * Note formula only works if 0 < abs(lon2-lon1) < 180
20  * If lon1 == lon2 then geodesic is the merdian lon1
21  * (and the formula will fail)
22  * if lon2-lon1=180 then the geodesic is either meridian lon1 or lon2
23  */
24 
25 /* TODO:
26  *
27  * integrate code from raster/r.surf.idw/ll.c
28  */
29 
30 
31 #define SWAP(a,b) temp=a;a=b;b=temp
32 
33 static int adjust_lat(double *);
34 static int adjust_lon(double *);
35 
36 static double A, B;
37 
38 
39 int G_begin_geodesic_equation(double lon1, double lat1, double lon2,
40  double lat2)
41 {
42  double sin21, tan1, tan2;
43 
44  adjust_lon(&lon1);
45  adjust_lon(&lon2);
46  adjust_lat(&lat1);
47  adjust_lat(&lat2);
48  if (lon1 > lon2) {
49  register double temp;
50 
51  SWAP(lon1, lon2);
52  SWAP(lat1, lat2);
53  }
54  if (lon1 == lon2) {
55  A = B = 0.0;
56  return 0;
57  }
58  lon1 = Radians(lon1);
59  lon2 = Radians(lon2);
60  lat1 = Radians(lat1);
61  lat2 = Radians(lat2);
62 
63  sin21 = sin(lon2 - lon1);
64  tan1 = tan(lat1);
65  tan2 = tan(lat2);
66 
67  A = (tan2 * cos(lon1) - tan1 * cos(lon2)) / sin21;
68  B = (tan2 * sin(lon1) - tan1 * sin(lon2)) / sin21;
69 
70  return 1;
71 }
72 
73 /* only works if lon1 < lon < lon2 */
74 
75 double G_geodesic_lat_from_lon(double lon)
76 {
77  adjust_lon(&lon);
78  lon = Radians(lon);
79 
80  return Degrees(atan(A * sin(lon) - B * cos(lon)));
81 }
82 
83 static int adjust_lon(double *lon)
84 {
85  while (*lon > 180.0)
86  *lon -= 360.0;
87  while (*lon < -180.0)
88  *lon += 360.0;
89 
90  return 0;
91 }
92 
93 static int adjust_lat(double *lat)
94 {
95  if (*lat > 90.0)
96  *lat = 90.0;
97  if (*lat < -90.0)
98  *lat = -90.0;
99 
100  return 0;
101 }
#define SWAP(a, b)
Definition: geodesic.c:31
int G_begin_geodesic_equation(double lon1, double lat1, double lon2, double lat2)
Definition: geodesic.c:39
#define Radians(x)
Definition: pi.h:6
#define Degrees(x)
Definition: pi.h:7
double G_geodesic_lat_from_lon(double lon)
Definition: geodesic.c:75