~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to contrib/earthdistance/earthdistance.sql.in

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $PostgreSQL$ */
 
2
 
 
3
-- Adjust this setting to control where the objects get created.
 
4
SET search_path = public;
 
5
 
 
6
-- The earth functions rely on contrib/cube having been installed and loaded.
 
7
 
 
8
-- earth() returns the radius of the earth in meters. This is the only
 
9
-- place you need to change things for the cube base distance functions
 
10
-- in order to use different units (or a better value for the Earth's radius).
 
11
 
 
12
CREATE OR REPLACE FUNCTION earth() RETURNS float8
 
13
LANGUAGE SQL IMMUTABLE
 
14
AS 'SELECT ''6378168''::float8';
 
15
 
 
16
-- Astromers may want to change the earth function so that distances will be
 
17
-- returned in degrees. To do this comment out the above definition and
 
18
-- uncomment the one below. Note that doing this will break the regression
 
19
-- tests.
 
20
--
 
21
-- CREATE OR REPLACE FUNCTION earth() RETURNS float8
 
22
-- LANGUAGE SQL IMMUTABLE
 
23
-- AS 'SELECT 180/pi()';
 
24
 
 
25
-- Define domain for locations on the surface of the earth using a cube
 
26
-- datatype with constraints. cube provides 3D indexing.
 
27
-- The cube is restricted to be a point, no more than 3 dimensions
 
28
-- (for less than 3 dimensions 0 is assumed for the missing coordinates)
 
29
-- and that the point must be very near the surface of the sphere
 
30
-- centered about the origin with the radius of the earth.
 
31
 
 
32
CREATE DOMAIN earth AS cube
 
33
  CONSTRAINT not_point check(cube_is_point(value))
 
34
  CONSTRAINT not_3d check(cube_dim(value) <= 3)
 
35
  CONSTRAINT on_surface check(abs(cube_distance(value, '(0)'::cube) /
 
36
  earth() - 1) < '10e-7'::float8);
 
37
 
 
38
CREATE OR REPLACE FUNCTION sec_to_gc(float8) 
 
39
RETURNS float8
 
40
LANGUAGE SQL
 
41
IMMUTABLE STRICT
 
42
AS 'SELECT CASE WHEN $1 < 0 THEN 0::float8 WHEN $1/(2*earth()) > 1 THEN pi()*earth() ELSE 2*earth()*asin($1/(2*earth())) END';
 
43
 
 
44
CREATE OR REPLACE FUNCTION gc_to_sec(float8)
 
45
RETURNS float8
 
46
LANGUAGE SQL
 
47
IMMUTABLE STRICT
 
48
AS 'SELECT CASE WHEN $1 < 0 THEN 0::float8 WHEN $1/earth() > pi() THEN 2*earth() ELSE 2*earth()*sin($1/(2*earth())) END';
 
49
 
 
50
CREATE OR REPLACE FUNCTION ll_to_earth(float8, float8)
 
51
RETURNS earth
 
52
LANGUAGE SQL
 
53
IMMUTABLE STRICT
 
54
AS 'SELECT cube(cube(cube(earth()*cos(radians($1))*cos(radians($2))),earth()*cos(radians($1))*sin(radians($2))),earth()*sin(radians($1)))::earth';
 
55
 
 
56
CREATE OR REPLACE FUNCTION latitude(earth)
 
57
RETURNS float8
 
58
LANGUAGE SQL
 
59
IMMUTABLE STRICT
 
60
AS 'SELECT CASE WHEN cube_ll_coord($1, 3)/earth() < -1 THEN -90::float8 WHEN cube_ll_coord($1, 3)/earth() > 1 THEN 90::float8 ELSE degrees(asin(cube_ll_coord($1, 3)/earth())) END';
 
61
 
 
62
CREATE OR REPLACE FUNCTION longitude(earth)
 
63
RETURNS float8
 
64
LANGUAGE SQL
 
65
IMMUTABLE STRICT
 
66
AS 'SELECT degrees(atan2(cube_ll_coord($1, 2), cube_ll_coord($1, 1)))';
 
67
 
 
68
CREATE OR REPLACE FUNCTION earth_distance(earth, earth)
 
69
RETURNS float8
 
70
LANGUAGE SQL
 
71
IMMUTABLE STRICT
 
72
AS 'SELECT sec_to_gc(cube_distance($1, $2))';
 
73
 
 
74
CREATE OR REPLACE FUNCTION earth_box(earth, float8)
 
75
RETURNS cube
 
76
LANGUAGE SQL
 
77
IMMUTABLE STRICT
 
78
AS 'SELECT cube_enlarge($1, gc_to_sec($2), 3)';
 
79
  
 
80
--------------- geo_distance
 
81
 
 
82
CREATE OR REPLACE FUNCTION geo_distance (point, point)
 
83
RETURNS float8
 
84
LANGUAGE C IMMUTABLE STRICT AS 'MODULE_PATHNAME';
 
85
 
 
86
--------------- geo_distance as operator <@>
 
87
 
 
88
CREATE OPERATOR <@> (
 
89
  LEFTARG = point,
 
90
  RIGHTARG = point,
 
91
  PROCEDURE = geo_distance,
 
92
  COMMUTATOR = <@>
 
93
);