Suite

Obtenez les 2 points immédiatement avant et après un point donné dans PostGIS


Dans l'image ci-dessous : Le point donné est C, je voudrais sélectionner A et B, mais pas Z (qui est plus proche de C que B mais ce n'est pas immédiatement après dans la LineString).

Notez que C est toujours sur la ligne mais pas un sommet de la ligne.


Vous pouvez trouver ces points en utilisantST_Points de vidage(docs) combiné avec ledécalageetmenerfonctions de la fenêtre.

Tout d'abord, nous pouvons configurer quelques données de test :

test CREATE TEMPORARY TABLE (géométrie geom); INSERT INTO test VALUES ('LINESTRING (1 1, 2 2, 3 3, 4 4, 5 5)');

Ensuite, nous pouvons utiliserST_DumpPointspour obtenir les coordonnées dans l'ordre :

SELECT ST_DumpPoints(geom) AS dump FROM test ; décharger ------------------------------------------------- - ({1},01010000000000000000000F03F000000000000F03F) ({2},0101000000000000000000004000000000000000040) ({3},01010000000000000000000840000000000000840) ({4},0101000000000000000000010400000000000001040) ({5},01010000000000000000000000144000000000000001440) (5 lignes)

Cela renvoie ungeometrie_dumpobjet, dontcheminchamp contient l'indice du point, et dontgéomchamp contient le point lui-même. Ensuite, nous pouvons sélectionner parmi les éléments ci-dessus, en utilisant lemeneretdécalagefonctions (j'ai supprimé leST_AsTextappelle à la clarté):

SELECT ((dump).geom, lag ((dump).geom, 1) OVER (ORDER BY (dump).path ASC) AS prev, lead((dump).geom, 1) OVER (ORDER BY (dump). path ASC) AS next FROM (SELECT ST_DumpPoints(geom) AS dump FROM test) sq; curr | prev | next ------------+------------+ ------------ POINT(1 1) | | POINT(2 2) POINT(2 2) | POINT(1 1) | POINT(3 3) POINT(3 3) | POINT(2 2) | POINT(4 4) POINT(4 4) | POINT(3 3) | POINT(5 5) POINT(5 5) | POINT(4 4) | (5 lignes)

Maintenant, nous avons un jeu d'enregistrements contre lequel nous pouvons faire correspondre un point de test et trouver les points suivant et précédent dans la séquence :

SELECT précédent, suivant DE  WHERE ST_Equals(geom, 'POINT (4 4)'); précédent | suivant ------------+------------ POINT(3 3) | POINT(5 5) (1 rangée)

J'ai finalement résolu simplement avec ces étapes:

1) créer une table avec les segments individuels ("vidés" à partir des chaînes de lignes… en fait, je n'ai pas utilisé st_dump ou similaire, mais j'ai créé les segments à partir de la table contenant tous les points)

2) trouver les segments (AB) qui coupent les points C

3) calculer la limite de AB et vider le résultat pour obtenir les points A et B

Cependant merci à tous pour l'aide précieuse qui m'a fait comprendre beaucoup de choses.