Comment obtenir le point le plus proche d'une chaîne de lignes à un point donné?


28

J'utilise PostGIS depuis longtemps mais je n'ai jamais eu à utiliser la LINESTRINGgéométrie ...! :)

Voici ce que je voudrais faire: j'ai un tableau des lignes de ligne (représentant les rues d'une ville donnée, SRID 3395) et je voudrais trouver les lignes de ligne les plus proches d'un point donné (position GPS, SRID 4326).

La solution que j'ai trouvée est de sélectionner toutes les chaînes de lignes de mon point en utilisant la expand()méthode et de déterminer la distance entre chaque chaîne de lignes et mon point en utilisant la ST_Distance()méthode.

Voici le SQL:

SELECT myLineId, myLineName, ST_Distance(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395),myLineGeom) AS myLineDistance
FROM myLines
WHERE myLineGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)
ORDER BY myLineDistance;

Les résultats que j'obtiens semblent corrects mais j'ai l'impression que quelque chose ne va pas dans ma mise en œuvre.

1) Pensez-vous que les gars expand()peuvent obtenir toutes les chaînes de caractères concernées?

2) Pensez-vous que ST_Distance()c'est la bonne méthode à utiliser? Je suppose que je me trompe, car la distance que je voudrais obtenir est la plus petite distance entre le point et ma ligne et non la distance entre le point et l'un des points de la chaîne.

Illustration:

texte alternatif

Réponses:


11

ad 1) En regardant la documentation de vos fonctions utilisées, je dirais: "Oui, toutes les chaînes de caractères concernées seront trouvées."

développer (géométrie, flotter)

Cette fonction renvoie un cadre de délimitation développé dans toutes les directions à partir du cadre de délimitation de la géométrie en entrée, d'une quantité spécifiée dans le deuxième argument. Très utile pour les requêtes distance (), pour ajouter un filtre d'index à la requête.

UN B

L'opérateur "&&" est l'opérateur "chevauchements". Si la boîte englobante de A chevauche la boîte englobante de B, l'opérateur renvoie true.

ad 2) Vous devriez pouvoir réaliser ce que vous voulez via:

line_interpolate_point(linestring, line_locate_point(LineString, Point))

line_interpolate_point (linestring, location)

Interpole un point le long d'une ligne. Le premier argument doit être un LINESTRING. Le deuxième argument est un flottant8 compris entre 0 et 1 représentant la fraction de la longueur totale 2D où le point doit être localisé.

line_locate_point (LineString, Point)

Renvoie un flottant entre 0 et 1 représentant l'emplacement du point le plus proche sur LineString du point donné, sous la forme d'une fraction de la longueur totale de la ligne 2D. Vous pouvez utiliser l'emplacement renvoyé pour extraire un point (line_interpolate_point)

Source: http://main.merlin.com.ua/doc/postgis/docs/ch06.html


Pour le point 2), je me demandais simplement si ST_Distance entre une géométrie POINT et une géométrie LINESTRING donne la plus petite distance possible entre les thèses (alias la longueur de la ligne perpendiculaire entre le POINT et le LINGESTRING); je veux la distance de chaque géométrie LINESTRING :)
Vivi

Et je suppose que ce n'est pas la distance que je recherche car "la fonction line_locate_point vous donne une valeur entre 0 et 1 représentant l'emplacement du point le plus proche sur LineString au point donné": /
Vivi

J'ai bien peur que tu me perdes dans ton dernier commentaire. Maintenant je ne sais plus ce que tu veux;)
underdark

1
Désolé :) Je voudrais ceci: en donnant une géométrie LINESTRING (représentant un chemin) et une géométrie POINT, je veux avoir la géométrie POINT la plus proche qui se trouve sur le chemin (qui peut ne pas être un point de la définition de la géométrie LINESTRING). Est-ce clair? Je devrais peut-être mettre à jour mon article avec un dessin: D
Vivi

Je ne peux pas mettre à jour mon article, voici donc un lien vers un dessin de ce que j'aimerais obtenir: i.imgur.com/UwPxo.jpg
Vivi

7

Bonjour

Tout d'abord, la question de savoir ce que ST_Distance renvoie. ST_Distance renvoie la distance la plus courte entre la ligne et le point (ou quels types de géométrie sont entrés) Cela signifie que ST_Distance entre le point (1 3) et la chaîne de caractères (0 0,0 10) renverra 1. La distance ne sera pas mesurée entre le point et (0 0) ou le point et (0 10) mais du point (1 3) à (0 3).

Donc d'après ce que je comprends, ST_Distance vous donne la réponse que vous voulez.

Si vous voulez trouver le point (0 3) dans l'exemple ci-dessus, vous pouvez utiliser ST_Closestpoint si vous avez PostGIS 1.5 Pour mon exemple, vous l'utilisez comme ceci: ST_Closestpoint ('LINESTRING (0 0,0 10)' :: geometry, ' POINT (1 3) ':: geometry) alors vous devriez obtenir le point (0 3) en retour, le point sur la ligne qui est le plus proche de votre point.

HTH Nicklas


5

Je l'ai trouvé :) (Bon je suppose: P)

En utilisant le ST_Line_Locate_Point()et ST_Line_Interpolate_point()j'ai réussi à obtenir un point qui NE fait PAS partie de la définition de LINESTRING mais EST sur ladite ligne :) Tout ce que j'ai à faire est d'obtenir la distance de mon point à ce point et j'ai terminé.

SELECT AsText(ST_Line_Interpolate_Point(myLineGeom,ST_Line_Locate_Point(myLineGeom,ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395))))
FROM myLines
WHERE myGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)

La ST_Line_Locate_Point()méthode recherche l'emplacement du point le plus proche sur la ligne jusqu'au point donné, la ST_Line_Interpolate_Pointméthode transforme cet emplacement en un point.


1
St_distance entre le point et la ligne vous donnera la même réponse. Pourquoi pensez-vous que vous devez le faire de cette façon?
Nicklas Avén

1
Je pense que ST_Distance peut être utilisé avec n'importe quel type de géométrie. postgis.refractions.net/docs/ST_Distance.html :ST_Distance(geometry g1, geometry g2)
Magno C

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.