受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

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

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

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

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

Caution

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

F.12.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.12.2. 基于点的地球距离 #

该模块的第二部分依赖于将地球上的位置表示为 point 类型的值,其中第一个分量被视为以度为单位的经度,第二个分量被视为以度为单位的纬度。之所以采用 (longitude, latitude) 而不是相反的顺序,是因为经度更接近 x 轴的直观概念,而纬度更接近 y 轴。

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

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

操作符

描述

point <@> pointfloat8

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


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

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

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。