#1 Tue 26 November 2019 22:43
- preliator
- Participant assidu
- Date d'inscription: 17 Nov 2018
- Messages: 433
Distance entre géométrie
Bonjour à tous,
Sur PostGis, je dispose d'une couche de parcelles (polygones) et de cours d'eau (tracés). Je souhaiterais trouver un moyen de calculer la distance minimum qui sépare chaque parcelle à un cours d'eau. Etant 2 géométrie différentes, je me retrouve un peu bloqué.
En cherchant sur les forums, j'ai trouvé une formule interessante :
Code:
st_length(st_shortestline(parcelles.geom, riviere.geom))
Malheureusement, cela me fait le produit cartésien des 2 éléments, soit 281 000 parcelles * 891 cours d'eau ....
Merci à vous.
Hors ligne
#2 Wed 27 November 2019 12:13
Re: Distance entre géométrie
Bonjour,
la fonction st_distance() fait le travail. Il reste à extraire la valeur minimale pour chaque parcelle.
Ci-dessous j'utilise la condition de jointure st_dwithin avec une distance de 5000 mètres pour ne pas faire le produit cartésien des deux tables, en considérant que chaque parcelle est à moins de 5000 m d'une rivière (à adapter à votre cas).
Code:
SELECT parcelle.id, min(st_distance(parcelle.geom, riviere.geom)) FROM parcelle JOIN rivieres ON st_dwithin(parcelle.geom, riviere.geom,5000) GROUP BY parcelle.id
La piste de la recherche du plus proche voisin est intéressante aussi.
Mathieu BOSSAERT
Association GeoRezo
Hors ligne
#3 Wed 27 November 2019 21:35
- preliator
- Participant assidu
- Date d'inscription: 17 Nov 2018
- Messages: 433
Re: Distance entre géométrie
Un grand merci à vous cela marche niquel
Hors ligne
#4 Fri 29 November 2019 11:37
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Distance entre géométrie
Bonjour,
Comme le dit Mathieu, PostGIS a un opérateur distance dédié à ce genre de requetes: <->:
Cela permet de chercher les n voisins plus proches (KNN) des géométries.
L'avantage par rapport a min(distance) est double:
• énorme performance qq ms contre plusieurs secondes ou minutes pour min(distance)
• pas besoin de préfiltrer par une distance qui dépend des données: l'opérateur marche tjs qq soit la distance min entre géométries.
Pour utiliser cet opérateur, il faut faire une jointure latérale entre les tables qui permet de référencer les colonnes d'une table depuis une sous requête:
Code:
select p.id, t.riv_id, t.dist from parcelle p cross join lateral ( select r.id as riv_id, p.geom <-> r.geom as dist from riviere r order by p.geom <-> r.geom limit 1 ) as t;
La différence de perf sur une table parcelle de 300 000 et rivieres de 400 geoms:
knn: 128 ms
min(distance): 7200 ms
Nicolas
Hors ligne