<-> — Renvoie la distance en 2D entre A et B.
double precision <->(
geometry A , geometry B )
;
double precision <->(
geography A , geography B )
;
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.
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. |
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+
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)