Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17 / 18

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

F.14.1. 基于立方体的地球距离
F.14.2. 基于点的地球距离

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

在这个模块中,地球被假定为完全球形的。(如果这种假设对你而言精度不足,可以参见 PostGIS 项目。)

必须先安装 cube 模块,才能安装 earthdistance(不过,你也可以使用 CREATE EXTENSIONCASCADE 选项,用一条命令同时安装这两个扩展)。

Caution

强烈建议将 earthdistancecube 安装到同一个模式中,并且该模式过去没有、将来也不会向任何不受信任的用户授予 CREATE 权限。 否则,如果 earthdistance 所在的模式包含由恶意用户定义的对象,就会在安装时产生安全隐患。 此外,在安装后使用 earthdistance 的函数时,整个搜索路径都应当只包含受信任的模式。

F.14.1. 基于立方体的地球距离 #

数据以立方体形式存储,而这些立方体实际上是点(两个角相同),使用 3 个坐标分别表示距地心的 x、y、z 距离。这里还提供了一个基于类型 cube earth,其中包含约束检查,用以确认该值满足这些限制,并且与地球实际表面足够接近。

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

这个模块在天文数据库中也有用途。天文学家大概会希望修改 earth(),使其返回半径 180/pi(),这样距离单位就是度。

这里提供了一些函数,用于按经纬度(以度为单位)输入、输出经纬度、计算两点之间的大圆距离,以及方便地指定一个可用于索引搜索的边界框。

所提供的函数见 Table F.4

Table F.4. 基于立方体的地球距离函数

函数

描述

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 类型的值,其中第一个分量被视为以度为单位的经度,第二个分量被视为以度为单位的纬度。之所以采用 (longitude, latitude) 而不是相反的顺序,是因为经度更接近 x 轴的直观概念,而纬度更接近 y 轴。

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

Table F.5. 基于点的地球距离操作符

操作符

描述

point <@> pointfloat8

计算地球表面上两个点之间的距离,单位为法定英里。


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

经度/纬度表示的一个缺点是,你需要小心靠近两极以及接近经度 +/- 180 度时的边界情况。基于 cube 的表示可以避免这些不连续性。