-# $Header: /cvsroot/pgsql/contrib/earthdistance/Makefile,v 1.11 2001/09/06 10:49:29 petere Exp $
+# $Header: /cvsroot/pgsql/contrib/earthdistance/Makefile,v 1.12 2002/09/20 03:47:22 momjian Exp $
subdir = contrib/earthdistance
top_builddir = ../..
MODULES = earthdistance
DATA_built = earthdistance.sql
DOCS = README.earthdistance
+REGRESS = earthdistance
include $(top_srcdir)/contrib/contrib-global.mk
+---------------------------------------------------------------------
+I corrected a bug in the geo_distance code where two double constants
+were declared as int. I changed the distance function to use the
+haversine formula which is more accurate for small distances.
+I added a regression test to the package. I added a grant statement
+to give execute access for geo_distance to public.
+
+Bruno Wolff III
+September 2002
+---------------------------------------------------------------------
Date: Wed, 1 Apr 1998 15:19:32 -0600 (CST)
From: Hal Snyder <hal@vailsys.com>
To: vmehr@ctp.com
/* Earth's radius is in statute miles. */
-const int EARTH_RADIUS = 3958.747716;
-const int TWO_PI = 2.0 * M_PI;
+const double EARTH_RADIUS = 3958.747716;
+const double TWO_PI = 2.0 * M_PI;
double *geo_distance(Point *pt1, Point *pt2);
long2,
lat2;
double longdiff;
+ double sino;
double *resultp = palloc(sizeof(double));
/* convert degrees to radians */
if (longdiff > M_PI)
longdiff = TWO_PI - longdiff;
- *resultp = EARTH_RADIUS * acos
- (sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(longdiff));
+ sino = sqrt(sin(fabs(lat1-lat2)/2.)*sin(fabs(lat1-lat2)/2.) +
+ cos(lat1) * cos(lat2) * sin(longdiff/2.)*sin(longdiff/2.));
+ if (sino > 1.) sino = 1.;
+ *resultp = 2. * EARTH_RADIUS * asin(sino);
return resultp;
}
+begin;
--------------- geo_distance
-DROP FUNCTION geo_distance (point, point);
-CREATE FUNCTION geo_distance (point, point) RETURNS float8
- AS 'MODULE_PATHNAME' LANGUAGE 'c'
- WITH (isstrict);
-
-SELECT geo_distance ('(1,2)'::point, '(3,4)'::point);
+CREATE OR REPLACE FUNCTION geo_distance (point, point) RETURNS float8
+ LANGUAGE 'c' IMMUTABLE STRICT AS 'MODULE_PATHNAME';
--------------- geo_distance as operator <@>
-DROP OPERATOR <@> (point, point);
CREATE OPERATOR <@> (
leftarg = point,
rightarg = point,
commutator = <@>
);
--- ( 87.6, 41.8) is in Chicago
--- (106.7, 35.1) is in Albuquerque
--- The cities are about 1100 miles apart
-SELECT '(87.6,41.8)'::point <@> '(106.7,35.1)'::point;
+--
+-- By default this function is made executable by anyone. To restrict
+-- access by default, comment out the following grant command.
+--
+
+grant execute on function geo_distance(point, point) to public;
+
+commit;