mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
4c1383efd1
points on the surface of the earth and locating points within a specified distance using an index based on the contrib/cube package. The new functions are all of language type sql. A couple of bugs in the old earthdistance function based on the point datatype are fixed. A regression test has been added for both sets of functions. The README file has been updated to include documentation on the new stuff. There are comments about how this package is also useful for Astronomers. Bruno Wolff III
136 lines
5.6 KiB
Plaintext
136 lines
5.6 KiB
Plaintext
This contrib package contains two different approaches to calculating
|
|
great circle distances on the surface of the Earth. The one described
|
|
first depends on the contrib/cube package (which MUST be installed before
|
|
earthdistance is installed). The second one is based on the point
|
|
datatype using latitude and longitude for the coordinates. The install
|
|
script makes the defined functions executable by anyone.
|
|
|
|
Make sure contrib/cube has been installed.
|
|
make
|
|
make install
|
|
make installcheck
|
|
|
|
To use these functions in a particular database as a postgres superuser do:
|
|
psql databasename < earthdistance.sql
|
|
|
|
-------------------------------------------
|
|
contrib/cube based Earth distance functions
|
|
Bruno Wolff III
|
|
September 2002
|
|
|
|
A spherical model of the Earth is used.
|
|
|
|
Data is stored in cubes that are points (both corners are the same) using 3
|
|
coordinates representing the distance from the center of the Earth.
|
|
|
|
The radius of the Earth is obtained from the earth() function. It is
|
|
given in meters. But by changing this one function you can change it
|
|
to use some other units or to use a different value of the radius
|
|
that you feel is more appropiate.
|
|
|
|
This package also has applications to astronomical databases as well.
|
|
Astronomers will probably want to change earth() to return a radius of
|
|
180/pi() so that distances are in degrees.
|
|
|
|
Functions are provided to allow for input in latitude and longitude (in
|
|
degrees), to allow for output of latitude and longitude, to calculate
|
|
the great circle distance between two points and to easily specify a
|
|
bounding box usable for index searches.
|
|
|
|
The functions are all 'sql' functions. If you want to make these functions
|
|
executable by other people you will also have to make the referenced
|
|
cube functions executable. cube(text), cube_distance(cube,cube),
|
|
cube_ll_coord(cube,int) and cube_enlarge(cube,float8,int) are used indirectly
|
|
by the earth distance functions. is_point(cube) and cube_dim(cube) are used
|
|
in suggested constraints for data in domain earth. cube_ur_coord(cube,int)
|
|
is used in the regression tests and might be useful for looking at bounding
|
|
box coordinates in user applications.
|
|
|
|
A domain of type cube named earth is defined. Since check constraints
|
|
are not supported for domains yet, this isn't as useful as it might be.
|
|
However the checks that should be supplied to all data of type earth are:
|
|
|
|
constraint not_point check(is_point(earth))
|
|
constraint not_3d check(cube_dim(earth) <= 3)
|
|
constraint on_surface check(abs(cube_distance(earth, '(0)'::cube) /
|
|
earth() - 1) < '10e-12'::float8);
|
|
|
|
The following functions are provided:
|
|
|
|
earth() - Returns the radius of the earth in meters.
|
|
|
|
sec_to_gc(float8) - Converts the normal straight line (secant) distance between
|
|
between two points on the surface of the Earth to the great circle distance
|
|
between them.
|
|
|
|
gc_to_sec(float8) - Converts the great circle distance between two points
|
|
on the surface of the Earth to the normal straight line (secant) distance
|
|
between them.
|
|
|
|
ll_to_cube(float8, float8) - Returns the location of a point on the surface of
|
|
the Earth given its latitude (argument 1) and longitude (argument 2) in degrees.
|
|
|
|
latitude(earth) - Returns the latitude in degrees of a point on the surface
|
|
of the Earth.
|
|
|
|
longitude(earth) - Returns the longitude in degrees of a point on the surface
|
|
of the Earth.
|
|
|
|
earth_distance(earth, earth) - Returns the great circle distance between
|
|
two points on the surface of the Earth.
|
|
|
|
earth_box(earth, float8) - Returns a box suitable for an indexed search using
|
|
the cube @ operator for points within a given great circle distance of a
|
|
location. Some points in this box are further than the specified great circle
|
|
distance from the location so a second check using earth_distance should be
|
|
made at the same time.
|
|
|
|
One advantage of using cube representation over a point using latitude and
|
|
longitude for coordinates, is that you don't have to worry about special
|
|
conditions at +/- 180 degrees of longitude or near the poles.
|
|
|
|
Below is the documentation for the Earth distance operator that works
|
|
with the point data type.
|
|
|
|
---------------------------------------------------------------------
|
|
|
|
I corrected a bug in the geo_distance code where two double constants
|
|
were declared as int. I also changed the distance function to use
|
|
the haversine formula which is more accurate for small distances.
|
|
Bruno Wolff
|
|
September 2002
|
|
|
|
---------------------------------------------------------------------
|
|
|
|
Date: Wed, 1 Apr 1998 15:19:32 -0600 (CST)
|
|
From: Hal Snyder <hal@vailsys.com>
|
|
To: vmehr@ctp.com
|
|
Subject: [QUESTIONS] Re: Spatial data, R-Trees
|
|
|
|
> From: Vivek Mehra <vmehr@ctp.com>
|
|
> Date: Wed, 1 Apr 1998 10:06:50 -0500
|
|
|
|
> Am just starting out with PostgreSQL and would like to learn more about
|
|
> the spatial data handling ablilities of postgreSQL - in terms of using
|
|
> R-tree indexes, user defined types, operators and functions.
|
|
>
|
|
> Would you be able to suggest where I could find some code and SQL to
|
|
> look at to create these?
|
|
|
|
Here's the setup for adding an operator '<@>' to give distance in
|
|
statute miles between two points on the earth's surface. Coordinates
|
|
are in degrees. Points are taken as (longitude, latitude) and not vice
|
|
versa as longitude is closer to the intuitive idea of x-axis and
|
|
latitude to y-axis.
|
|
|
|
There's C source, Makefile for FreeBSD, and SQL for installing and
|
|
testing the function.
|
|
|
|
Let me know if anything looks fishy!
|
|
|
|
A note on testing C extensions - it seems not enough to drop a function
|
|
and re-create it - if I change a function, I have to stop and restart
|
|
the backend for the new version to be seen. I guess it would be too
|
|
messy to track which functions are added from a .so and do a dlclose
|
|
when the last one is dropped.
|