Name

<-> — Renvoie la distance en 2D entre A et B.

Synopsis

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

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

Description

L'opérateur <-> renvoie la distance 2D entre deux géométries. Utilisé dans la clause "ORDER BY" fournit des ensembles de résultats de plus proches voisins assistés par index. Pour PostgreSQL inférieur à 9.5, donne uniquement la distance centroïde des boîtes englobantes et pour PostgreSQL 9.5+, fait une vraie recherche de distance KNN donnant la vraie distance entre les géométries, et la sphère de distance pour les géographies.

[Note]

Cet opérande utilise les index 2D GiST qui peuvent être disponibles sur les géométries. Il est différent des autres opérateurs qui utilisent des index spatiaux en ce sens que l'index spatial n'est utilisé que lorsque l'opérateur est dans la clause ORDER BY.

[Note]

L'index n'intervient que si l'une des géométries est une constante (pas dans une sous-requête/cte). Par exemple, 'SRID=3005;POINT(1011102 450541)'::geometry au lieu de a.geom

Reportez-vous à l'atelier PostGIS : La recherche du plus proche voisin pour un exemple détaillé.

Amélioré : 2.2.0 -- Comportement KNN ("K nearest neighbor") réel pour la géométrie et la géographie pour PostgreSQL 9.5+. Note : pour la géographie, KNN est basé sur la sphère plutôt que sur le sphéroïde. Pour PostgreSQL 9.4 et moins, le support de la géographie est nouveau mais ne supporte que le centroïde de la boîte de délimitation.

Modifié : 2.2.0 -- Pour les utilisateurs de PostgreSQL 9.5, l'ancienne syntaxe Hybrid peut être plus lente, donc vous voudrez vous débarrasser de ce hack si vous exécutez votre code uniquement sur PostGIS 2.2+ 9.5+. Voir les exemples ci-dessous.

Disponibilité : 2.0.0 -- Le KNN fournit des voisins les plus proches basés sur les distances entre les centroïdes géométriques au lieu des distances réelles. Résultats exacts pour les points, inexacts pour tous les autres types. Disponible pour PostgreSQL 9.1+

Exemples

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)

Puis la réponse brute 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)

Si vous exécutez "EXPLAIN ANALYZE" sur les deux requêtes, vous constaterez une amélioration des performances pour la seconde.

Pour les utilisateurs utilisant PostgreSQL < 9.5, utilisez une requête hybride pour trouver les vrais plus proches voisins. D'abord une requête CTE utilisant le KNN assisté par index, puis une requête exacte pour obtenir l'ordre correct :

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)

                        

Voir aussi

ST_DWithin, ST_Distance, <#>