From 47c574b599e49649f64c0f590219abcefeb6938d Mon Sep 17 00:00:00 2001 From: Laupie2 Date: Thu, 5 Feb 2026 15:46:04 +0100 Subject: [PATCH] displacement road MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A l'aide de ce code on retrouve un phénomène de déplacement (dans ce cas ci des routes en fonction d'autres MultiLine tel que les rivières). Nous observons que les routes vont être déplacées de 12m si l'obstacle se situe à moins de 15m sinon elles ne seront pas modifié. A soulginer que pour que cela fonctionne le code permet de découper les routes en points et de selectionner le point le plus proche de l'obstacle permettant ce déplacement, on peut bien évidemment jouer avec la valeur à laquelle on considère qu'un obstacle est proche et aussi sur la valeur de déplacement de notre objet, ici le choix de ces valeurs a été fait à l'aide de l'interprétation visuelle de la zone d'étude (elle aussi peut être supprimée pour le faire sur une plus grande zone). A grande échelle (1:2000) les valeurs choisies sont sans doute trop importante (voir photo), à souligner qu'à une échelle plus petite c'est moins flagrant. De plus il faut aussi souligner que toute les routes qu'elles soient qualifiées de chemins ou d'autoroute sont prises en compte dans ce code. --- ...placement only linestring +commentaire.sql | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 ticket 5_displacement/displacement only linestring +commentaire.sql diff --git a/ticket 5_displacement/displacement only linestring +commentaire.sql b/ticket 5_displacement/displacement only linestring +commentaire.sql new file mode 100644 index 0000000..2de20a4 --- /dev/null +++ b/ticket 5_displacement/displacement only linestring +commentaire.sql @@ -0,0 +1,59 @@ +WITH +-- 1. On définit la zone en 3857 (le SRID de tes données planet_osm_line) +zone AS ( + SELECT ST_Transform(ST_MakeEnvelope(5.72, 50.57, 5.80, 50.60, 4326), 3857) AS geom +), +-- 2. Obstacles (Rivières et Rails) --> ici on recupere les obstacles pour les routes ATTENTION on ne prend en compte que les éléments "ligne" +obstacles AS ( + SELECT way as geom + FROM planet_osm_line + WHERE (waterway IS NOT NULL OR railway = 'rail') -- garde uniquement rail et rivières de la table et dans la zone définie auparavant + AND ST_Intersects(way, (SELECT geom FROM zone)) +), +-- 3. Points des routes éclatés -- objectif transformer les lignes en une serie de points + chaque point sera pris individuellement pour voir s'il est ou non proche d'un obstacle + +points_eclates AS ( + SELECT + r.osm_id, + (ST_DumpPoints(r.way)).path as pt_path, -- pt_path va donner la position du point dans la ligne et st_dump va decouper la ligne en points + (ST_DumpPoints(r.way)).geom as pt_geom -- geom du point individuel (les coordonées du pts) + FROM planet_osm_line r + WHERE r.highway IS NOT NULL + AND (r.bridge IS NULL OR r.bridge = 'no') -- exclusion des ponts (vu qu'ils passent au dessus il n'y a donc pas de conflit) + AND ST_Intersects(r.way, (SELECT geom FROM zone)) +), +-- 4. Recherche de l'obstacle et déplacement (en mètres car le 3857 utilise le mètre) +calcul_deplacement AS ( + SELECT + p.osm_id, + p.pt_path, -- position du point dans la ligne + CASE + WHEN ST_DWithin(p.pt_geom, obs.geom, 15) THEN -- ici on vérifie si le point se situe 15m d'un obstacle, si oui alors il y a conflit + ST_Translate( --si il y a conflit alors : déplacement du point + p.pt_geom, -- ici on prend le point à déplacer + sin(ST_Azimuth(ST_ClosestPoint(obs.geom, p.pt_geom), p.pt_geom)) * 12, -- On pousse de 12m le point le plus proche de l'obstacle en X + cos(ST_Azimuth(ST_ClosestPoint(obs.geom, p.pt_geom), p.pt_geom)) * 12 -- on pousse de 12m le point le plus proche de l'obstacle en Y + ) + ELSE p.pt_geom -- sinon on conserve le point originel + END as geom_p + FROM points_eclates p + LEFT JOIN LATERAL ( -- Lateral join permet pour chaque point de chercher et trouver l'obstacle le plus proche (recherche personalisée pour chaque point, alors que le join normal va en general relier les points avec tout les obstacles possibles + SELECT geom FROM obstacles + ORDER BY p.pt_geom <-> geom -- <-> = operateur de distance postgis, il va calculer la distance entre les deux geoms + LIMIT 1 -- garde que l'obstacle le plus proche + ) obs ON true -- jointure toujours vraie +), +-- 5. Reconstruction des lignes +lignes_reconstruites AS ( + SELECT + osm_id, + ST_MakeLine(geom_p ORDER BY pt_path)::geometry(LineString, 3857) as geom -- reconnecte les points en une ligne dans l'ordre original de la route en forcant un type de geom = ligne + FROM calcul_deplacement + GROUP BY osm_id -- groupement pour refaire la route +) +-- 6. Résultat final pour QGIS +SELECT + CAST(ROW_NUMBER() OVER() AS INT) as qgis_id, + osm_id, + geom +FROM lignes_reconstruites;