PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

F.14. earthdistance — 计算大圆距离 #

F.14.1. 基于 Cube 的地球距离
F.14.2. 基于 Point 的地球距离

earthdistance 模块提供两种不同的方法来计算地球表面的大圆距离。第一种方法依赖 cube 模块。第二种方法基于内置的 point 数据类型,使用经度与纬度作为坐标。

在该模块中,地球被假定为一个完美的球体。(如果这个精度对你来说不够,你可以考虑 PostGIS 项目。)

在安装 earthdistance 之前必须先安装 cube 模块(不过你可以使用 CREATE EXTENSION 的 CASCADE 选项在一条命令中同时安装两者)。

Caution

强烈建议将 earthdistance 与 cube 安装在同一个模式中,并且该模式从未、将来也不会被授予任何不受信任的用户 CREATE 权限。否则,如果 earthdistance 所在的模式中包含敌意用户定义的对象,就会产生安装期安全隐患。此外,安装后在 earthdistance 的函数中使用时,整个搜索路径应只包含受信任的模式。

F.14.1. 基于 Cube 的地球距离 #

数据存储在表示点的立方体中(两个角相同),使用 3 个坐标表示距地心的 x、y、z 距离。模块提供建立在 cube 类型之上的 域 earth,它带有约束检查,确保值满足这些限制,并且与地球实际表面足够接近。

地球半径由 earth() 函数获得,单位为米。只要修改这一个函数,你就可以让模块改用其他单位,或者使用你认为更合适的半径值。

该扩展包同样适用于天文数据库。天文学家可能希望修改 earth() 使其返回 180/pi() 的半径,这样距离就以度为单位。

模块提供的函数支持以经纬度(单位为度)输入与输出、计算两点之间的大圆距离,以及方便地指定可用于索引搜索的边界框。

提供的函数见 Table F.4。

Table F.4. 基于 Cube 的 earthdistance 函数

函数

描述

earth () → float8

返回假定的地球半径。

sec_to_gc ( float8 ) → float8

将地球表面上两点之间的法线直线(割线)距离转换为它们之间的大圆距离。

gc_to_sec ( float8 ) → float8

将地球表面上两点之间的大圆距离转换为它们之间的法线直线(割线)距离。

ll_to_earth ( float8, float8 ) → earth

根据以度表示的纬度(参数 1)与经度(参数 2),返回地球表面上某点的位置。

latitude ( earth ) → float8

返回地球表面上某点的纬度(单位为度)。

longitude ( earth ) → float8

返回地球表面上某点的经度(单位为度)。

earth_distance ( earth, earth ) → float8

返回地球表面上两点之间的大圆距离。

earth_box ( earth, float8 ) → cube

返回一个适合用 cube 的 @> 操作符进行索引搜索的边界框,用于查找与某位置距离不超过给定大圆距离的点。该边界框中的某些点与该位置的大圆距离可能超过指定值,因此查询中还应包含一次使用 earth_distance 的二次检查。


F.14.2. 基于 Point 的地球距离 #

模块的第二部分依赖将地球位置表示为 point 类型的值,其中第一个分量表示经度(单位为度),第二个分量表示纬度(单位为度)。点被理解为(经度,纬度)的顺序,原因是经度更接近 x 轴的直观概念,纬度更接近 y 轴。

该部分只提供一个操作符,见 Table F.5。

Table F.5. 基于 Point 的 earthdistance 操作符

操作符

描述

point <@> point → float8

计算地球表面两点之间的法定英里距离。


请注意,与模块中基于 cube 的部分不同,这里的单位是固定的:修改 earth() 函数不会影响该操作符的结果。

经度/纬度表示法的一个缺点是,你必须小心处理极点附近以及经度接近 +/- 180 度附近的边界情况。基于 cube 的表示方式避免了这些不连续问题。