Name

<-> — 返回A和B之间的2D距离。

Synopsis

double precision <->( geometry A , geometry B );

double precision <->( geography A , geography B );

描述

这个 <-> 运算符返回两个几何图形之间的2D距离。在“ORDER BY”子句中使用提供索引辅助的最近邻结果集。对于低于9.5的PostgreSQL,仅提供边界框的质心距离,对于PostgreSQL 9.5+,执行True KNN距离搜索,提供几何图形之间的真实距离,以及地理的距离球体。

[Note]

此操作数将使用几何图形上可能可用的2D Gist索引。它与其他使用空间索引的运算符的不同之处在于,仅当运算符位于ORDER BY子句中时才使用空间索引。

[Note]

仅当其中一个几何图形是常量(不在子查询/CTE中)时,索引才起作用。例如:‘SRID=3005;POINT(1011102 450541)’::几何图形而不是a.geom

请参阅 PostGIS专题讨论会:最近邻搜索 查看详细的示例。

增强:2.2.0--PostgreSQL 9.5+的几何和地理的True KNN(“K近邻”)行为。请注意,KNN是基于球面而不是椭球体的。对于PostgreSQL 9.4和更低版本,地理支持是新的,但只支持质心框。

更改:2.2.0--对于PostgreSQL9.5用户,旧的混合语法可能会更慢,所以如果您只在PostGIS2.2+9.5+上运行代码,那么您将希望摆脱这种攻击。请参见下面的示例。

可用性:2.0.0--弱KNN基于几何形心距离而不是真实距离提供最近邻居。点的结果是准确的,所有其他类型的结果都不准确。适用于PostgreSQL 9.1+

示例

SELECT ST_Distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY d limit 10;

        d         | edabbr | vaabbr
------------------+--------+--------
                0 | ALQ    | 128
 5541.57712511724 | ALQ    | 129A
 5579.67450712005 | ALQ    | 001
  6083.4207708641 | ALQ    | 131
  7691.2205404848 | ALQ    | 003
 7900.75451037313 | ALQ    | 122
 8694.20710669982 | ALQ    | 129B
 9564.24289057111 | ALQ    | 130
  12089.665931705 | ALQ    | 127
 18472.5531479404 | ALQ    | 002
(10 rows)

然后是KNN的原始答案:

SELECT st_distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
FROM va2005
ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry limit 10;

        d         | edabbr | vaabbr
------------------+--------+--------
                0 | ALQ    | 128
 5541.57712511724 | ALQ    | 129A
 5579.67450712005 | ALQ    | 001
  6083.4207708641 | ALQ    | 131
  7691.2205404848 | ALQ    | 003
 7900.75451037313 | ALQ    | 122
 8694.20710669982 | ALQ    | 129B
 9564.24289057111 | ALQ    | 130
  12089.665931705 | ALQ    | 127
 18472.5531479404 | ALQ    | 002
(10 rows)

如果您对这两个查询运行“EXPLAIN ANALYSE”,您将看到第二个查询的性能有所提高。

适用于运行PostgreSQL的用户 < 9.5中,使用混合查询来查找真正的最近邻居。首先是使用索引辅助KNN的CTE查询,然后是获得正确排序的精确查询:

WITH index_query AS (
  SELECT ST_Distance(geom, 'SRID=3005;POINT(1011102 450541)'::geometry) as d,edabbr, vaabbr
        FROM va2005
  ORDER BY geom <-> 'SRID=3005;POINT(1011102 450541)'::geometry LIMIT 100)
  SELECT *
        FROM index_query
  ORDER BY d limit 10;

        d         | edabbr | vaabbr
------------------+--------+--------
                0 | ALQ    | 128
 5541.57712511724 | ALQ    | 129A
 5579.67450712005 | ALQ    | 001
  6083.4207708641 | ALQ    | 131
  7691.2205404848 | ALQ    | 003
 7900.75451037313 | ALQ    | 122
 8694.20710669982 | ALQ    | 129B
 9564.24289057111 | ALQ    | 130
  12089.665931705 | ALQ    | 127
 18472.5531479404 | ALQ    | 002
(10 rows)

                        

另请参阅

ST_DWithin, ST_Distance, <#>