1
- /* $PostgreSQL: pgsql/contrib/earthdistance/earthdistance.c,v 1.14 2008/04/20 01:05:52 tgl Exp $ */
1
+ /* $PostgreSQL: pgsql/contrib/earthdistance/earthdistance.c,v 1.15 2008/04/21 01:11:43 tgl Exp $ */
2
2
3
3
#include "postgres.h"
4
4
@@ -17,10 +17,6 @@ PG_MODULE_MAGIC;
17
17
static const double EARTH_RADIUS = 3958.747716 ;
18
18
static const double TWO_PI = 2.0 * M_PI ;
19
19
20
- PG_FUNCTION_INFO_V1 (geo_distance );
21
-
22
- Datum geo_distance (PG_FUNCTION_ARGS );
23
-
24
20
25
21
/******************************************************
26
22
*
@@ -37,26 +33,22 @@ degtorad(double degrees)
37
33
return (degrees / 360.0 ) * TWO_PI ;
38
34
}
39
35
40
-
41
36
/******************************************************
42
37
*
43
- * geo_distance - distance between points
38
+ * geo_distance_internal - distance between points
44
39
*
45
40
* args:
46
41
* a pair of points - for each point,
47
42
* x-coordinate is longitude in degrees west of Greenwich
48
43
* y-coordinate is latitude in degrees above equator
49
44
*
50
- * returns: float8
45
+ * returns: double
51
46
* distance between the points in miles on earth's surface
52
47
******************************************************/
53
48
54
- Datum
55
- geo_distance ( PG_FUNCTION_ARGS )
49
+ static double
50
+ geo_distance_internal ( Point * pt1 , Point * pt2 )
56
51
{
57
- Point * pt1 = PG_GETARG_POINT_P (0 );
58
- Point * pt2 = PG_GETARG_POINT_P (1 );
59
- float8 result ;
60
52
double long1 ,
61
53
lat1 ,
62
54
long2 ,
@@ -81,7 +73,57 @@ geo_distance(PG_FUNCTION_ARGS)
81
73
cos (lat1 ) * cos (lat2 ) * sin (longdiff / 2. ) * sin (longdiff / 2. ));
82
74
if (sino > 1. )
83
75
sino = 1. ;
84
- result = 2. * EARTH_RADIUS * asin (sino );
85
76
77
+ return 2. * EARTH_RADIUS * asin (sino );
78
+ }
79
+
80
+
81
+ /******************************************************
82
+ *
83
+ * geo_distance - distance between points
84
+ *
85
+ * args:
86
+ * a pair of points - for each point,
87
+ * x-coordinate is longitude in degrees west of Greenwich
88
+ * y-coordinate is latitude in degrees above equator
89
+ *
90
+ * returns: float8
91
+ * distance between the points in miles on earth's surface
92
+ *
93
+ * If float8 is passed-by-value, the oldstyle version-0 calling convention
94
+ * is unportable, so we use version-1. However, if it's passed-by-reference,
95
+ * continue to use oldstyle. This is just because we'd like earthdistance
96
+ * to serve as a canary for any unintentional breakage of version-0 functions
97
+ * with float8 results.
98
+ ******************************************************/
99
+
100
+ #ifdef USE_FLOAT8_BYVAL
101
+
102
+ Datum geo_distance (PG_FUNCTION_ARGS );
103
+ PG_FUNCTION_INFO_V1 (geo_distance );
104
+
105
+ Datum
106
+ geo_distance (PG_FUNCTION_ARGS )
107
+ {
108
+ Point * pt1 = PG_GETARG_POINT_P (0 );
109
+ Point * pt2 = PG_GETARG_POINT_P (1 );
110
+ float8 result ;
111
+
112
+ result = geo_distance_internal (pt1 , pt2 );
86
113
PG_RETURN_FLOAT8 (result );
87
114
}
115
+
116
+ #else /* !USE_FLOAT8_BYVAL */
117
+
118
+ double * geo_distance (Point * pt1 , Point * pt2 );
119
+
120
+ double *
121
+ geo_distance (Point * pt1 , Point * pt2 )
122
+ {
123
+ double * resultp = palloc (sizeof (double ));
124
+
125
+ * resultp = geo_distance_internal (pt1 , pt2 );
126
+ return resultp ;
127
+ }
128
+
129
+ #endif /* USE_FLOAT8_BYVAL */
0 commit comments