Name

<-> — Retorna a distância 2D entre A e B.

Synopsis

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

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

Descrição

O operador <-> retorna a distância 2D entre duas geometrias. Usado nas orações "ORDEM" que fornecem configurações de resultado index-assisted nearest-neighbor. Para o PostgreSQL menor que 9.5 somente fornece a distância centroide das caixas limitadoras e para PostgreSQL 9.5+, a verdadeira distância KNN procura dando verdadeiras distâncias entre geometrias, e distância esférica para geografias.

[Note]

Esse operador fará uso dos indexes 2D GiST que podem estar disponíveis nas geometrias. É diferente de outros operadores que usam indexes espaciais em que eles só são usados quando o operador está na oração ORDEM.

[Note]

O index só rejeita se uma das geometrias é uma constante (não em uma subquery/cte). ex. 'SRID=3005;POINT(1011102 450541)'::geometria ao invés de uma .geom

Vá para OpenGeo workshop: Nearest-Neighbour Searching para um exemplo real.

melhorias: 2.2.0 -- Verdadeiro comportamento KNN ("vizinho mais perto de K") para geometria e geografia para PostgreSQL 9.5+. Note que para geografia o KNN é baseado em esfera ao invés de esferoide. Para o PostgreSQL 9.4 ou menor, o suporte para geografia é novo, mas só suporta caixa centroide.

Alterações: 2.2.0 -- Para usuários do PostgreSQL 9.5, a sintaxe Hybrid antiga pode ser ais lenta, então, você vai querer se livrar daquele hack se você está executando seu código só no PostGIS 2.2+ 9.5+. Veja os exemplos abaixo.

Disponibilidade: 2.0.0 -- O KNN mais fraco fornece vizinho mais próximos baseados em distâncias centroides de geometrias, ao invés de distâncias reais. Resultados corretos para pontos, incorretos para todos os outros tipos. Disponível para PostgreSQL 9.1+

Exemplos

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)

Então, a resposta KNN crua:

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)

Se você executar "ANÁLISE EXPLICATIVA" nas duas pesquisas, você verá uma apresentação melhorada para a segunda.

Para usuários com PostgreSQL < 9.5, use uma pesquisa hybrid para encontrar os vizinhos verdadeiros mais próximos. Primeiro, uma pesquisa CTE usando o index-assisted KNN, e depois, uma pesquisa exata para pegar a ordem certa:

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)


Veja também

ST_DWithin, ST_Distance, <#>