earthdistance
The earthdistance module provides two different methods for calculating great circle distances on the surface of the Earth. The first method, described below, depends on the cube module. The second method is based on the built-in point data type, using longitude and latitude for coordinates.
In this module, the Earth is assumed to be a perfect sphere.
The cube module must be installed before earthdistance. (However, you can use the CASCADE option of CREATE EXTENSION to install both in a single command.)
| Caution: It is strongly recommended that earthdistance and cube be installed in the same schema, and that the CREATE privilege for that schema has not been and will not be granted to any untrusted users. Otherwise, there is a security risk during installation if the earthdistance schema contains objects defined by hostile users. Additionally, when using earthdistance functions after installation, the entire search path should contain only trusted schemas. |
|---|
1. Cube-Based Earth Distances
Data is stored in cubes, where cube points (all corners identical) use 3 coordinates to represent the x, y, and z distances from the Earth's center. A domain earth over cube is provided, which includes constraints that check that values conform to these limits and are reasonably close to the Earth's true surface.
The radius of the Earth is obtained from the earth() function. The unit is meters. However, by changing this function you can adapt the module to use some other unit, or use a different radius value that you consider more appropriate. This package also has applications in astronomical databases. Astronomers may want to change earth() to return a radius of 180/pi(), so that distances are in degrees.
Functions are also provided to support latitude/longitude input (in degrees), latitude/longitude output, computing the great circle distance between two points, and easily specifying a bounding box suitable for indexed searches. The provided functions are described in Table C.5.
Table C.5. Cube-Based Earth Distance Functions
| Function/Description |
|---|
| earth () → float8 Returns the assumed radius of the Earth. |
| sec_to_gc ( float8 ) → float8 Converts the normal straight-line (secant) distance between two points on the Earth's surface to the great circle distance between them. |
| gc_to_sec ( float8 ) → float8 Converts the great circle distance between two points on the Earth's surface to the normal straight-line (secant) distance between them. |
| ll_to_earth ( float8, float8 ) → earth Returns the position on the Earth's surface for a point given its latitude (argument 1) and longitude (argument 2) in degrees. |
| latitude ( earth ) → float8 Returns the latitude (in degrees) of a point on the Earth's surface. |
| longitude ( earth ) → float8 Returns the longitude (in degrees) of a point on the Earth's surface. |
| earth_distance ( earth, earth ) → float8 Returns the great circle distance between two points on the Earth's surface. |
| earth_box ( earth, float8 ) → cube Returns a box suitable for indexed searches using the cube @> operator, for points within a given great circle distance of a location. Some points in this box may be further from the location than the specified great circle distance, so a second check using earth_distance should be included in the query. |
2. Point-Based Earth Distances
The second part of this module depends on representing Earth positions as values of type point, where the first component is used for longitude in degrees and the second component for latitude in degrees. Points are taken as (longitude, latitude) and not the other way around, because longitude is closer to the intuitive x-axis, while latitude is closer to the y-axis. As shown in Table C.6, this part provides only a single operator.
Table C.6. Point-Based Earth Distance Operator
| Operator/Description |
|---|
| point point → float8 Computes the distance between two points on the Earth's surface in statute miles. |
Note that unlike the cube-based part of this module, the units here are hard-coded: changing the earth() function will not affect the results of this operator.
One disadvantage of the longitude/latitude representation is that you need to be careful about edge cases near the poles and near the +/- 180 degree longitude line. The cube-based representation avoids these discontinuities.