Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Mon 09 May 2016 16:32

Cmoreau
Participant occasionnel
Date d'inscription: 31 Mar 2016
Messages: 14

[POSTGRESQL] Compléter des segments de linestring discontinus

Bonjour,

Je possède actuellement une couche de polylignes obtenues à partir de l'extraction de pixels bleus sur de vieux document géoréférencés,  correspondant à des tracés de cours d'eau. J'ai ensuite squelettiser le tout via SAGA pour obtenir la couche sur laquelle je travaille actuellement. Cette classification me donne cependant une couche dotée de nombreuses discontinuités, causées à la fois par l'acquisition de pixels, les modules de SAGA mais aussi la présence de routes et ponts chevauchant ledit cours d'eau.

Je possède déjà un prototype très peu fonctionnel permettant de créer des segments pour compléter à certains endroits. Cependant la requête prend beaucoup trop de temps, même sur une zone réduite, en plus de placer de nouveaux segments à des endroits où elle ne devrait pas. Il est à préciser que la fonction "AND xx_99_utils.f_trigo_angle_diff" me permet de calculer des différence d'angle entre deux géométries en entrée.

Code:

CREATE TABLE chain.line_etat_maj AS

 WITH chain AS (

    SELECT
        row_number () OVER () AS id,
        ST_ShortestLine(line_a.geom, line_b.geom) AS geom

    FROM
        chain.etat_maj_tot_reel AS line_a,
        chain.etat_maj_tot_reel AS line_b
        
    WHERE

        NOT St_intersects(line_a.geom, line_b.geom)
        AND St_DWithin(line_a.geom, line_b.geom, 100)
        AND xx_99_utils.f_trigo_angle_diff(line_a.geom, line_b.geom) < 10
        AND xx_99_utils.f_trigo_angle_diff(line_a.geom, ST_shortestline(line_a.geom, line_b.geom)) < 30
        
        OR  (St_DWithin(st_startpoint(line_a.geom), st_startpoint(line_b.geom), 50) AND NOT St_intersects(line_a.geom, line_b.geom))
        OR  (ST_DWithin(ST_endpoint(line_a.geom), st_startpoint(line_b.geom), 50) AND NOT St_intersects(line_a.geom, line_b.geom))
        OR  (ST_DWithin(ST_endpoint(line_a.geom), st_endpoint(line_b.geom), 50) AND NOT St_intersects(line_a.geom, line_b.geom))
        OR  (St_DWithin(st_startpoint(line_a.geom), st_endpoint(line_b.geom), 50) AND NOT St_intersects(line_a.geom, line_b.geom));

)

SELECT 

id,
geom

FROM

chain

EXCEPT

SELECT

ch.id,
ch.geom

FROM

chain AS ch,
chain AS ch_2

WHERE

ST_intersect (ch.geom, ch_2.geom) AND St_length(ch.geom) > St_length(ch_2.geom)

J'aimerais améliorer ce code pour répondre à mes besoins, ou repartir sur une requète plus judicieuse si ma méthodologie actuelle m'envoie droit dans le mur.

Hors ligne

 

#2 Mon 09 May 2016 17:38

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: [POSTGRESQL] Compléter des segments de linestring discontinus

Bonjour,

Problème pas évident en effet si on n'a pas de critères sur les lignes à joindre autre que des critères spatiaux ("prolonger vers celle qui semble la mieux alignée").

Vous auriez un jeu de données de test pas trop gros, représentatif d'une zone avec les différents cas possibles ?

Pour le test sur les endpoints/startpoints des lignes, un truc qui marche est de prendre la boundary des lignes: ce sont les startpoint et endpoint comme le défini OGC, sous forme de multipoint.
Ca permet de tester chaque ligne une seule fois.

A ce propos, vous pouvez aussi préparer des index spatiaux sur les fonctions/objets que vous utilisez dans les étapes intermédiaires:
par ex index spatial sur st_boundary(lignes), histoire que l'index soit déclenché dans le test.

Nicolas

Hors ligne

 

#3 Tue 10 May 2016 08:59

Cmoreau
Participant occasionnel
Date d'inscription: 31 Mar 2016
Messages: 14

Re: [POSTGRESQL] Compléter des segments de linestring discontinus

Merci pour le conseil, pour un exemple de jeu de données je vais voir ce que je peux faire car celle que j'ai crée est de taille assez conséquente (même sur de petits espaces on se retrouve avec beaucoup de segments)

Hors ligne

 

#4 Wed 25 May 2016 11:21

Cmoreau
Participant occasionnel
Date d'inscription: 31 Mar 2016
Messages: 14

Re: [POSTGRESQL] Compléter des segments de linestring discontinus

Pour ceux qui seraient intéressés j'ai complètement revu ma copie sur le sujet et j'ai décidé de partir d'aborder le problème sous un angle complètement différent. Pour cela j'ai commencé par créer une fonction qui me crée des cones selon des paramètres que j'ai moi même sélectionné, ils permettent de définir un "champ de vision" (à savoir un angle pour la direction, une distance et l'angle du champ de vision de part et d'autre de la direction principale) au niveau de chaque point que l'on rentrera en entrée:

Code:

CREATE OR REPLACE FUNCTION xx_99_utils.f_cone_azimut_view_v2(iN _pt geometry, _azimut numeric, IN _dist integer, IN _diff_angle integer )
  RETURNS TABLE(buff geometry, cone geometry) AS
$BODY$

/*
EXEMPLE D'APPEL:
select  (xx_99_utils.f_trigo_angle_diff(st_endpoint(geom), f_azimut(geom), 100, 10)).*
from --  table qui a des points 
LIMIT 1;

*/
 with w_primitives as (

Select

ST_setSRID(ST_makepoint((St_x(_pt) + (sin(radians(_azimut)) * _dist)), (ST_y(_pt) + (cos(radians(_azimut)) * _dist))), 2154) AS pt_translate


)


 SELECT ST_setSRID(st_buffer(_pt,_dist), ST_SRID(_pt)) AS buffer, ST_setSRID(ST_convexhull(ST_collect(ST_intersection(ST_buffer(_pt, _dist), ST_buffer(pt_translate, _dist*asin(radians(_diff_angle)))), _pt)), ST_SRID(_pt) ) AS cone 
 from w_primitives
  
$BODY$
  LANGUAGE sql STABLE STRICT
  COST 100
  ROWS 1;

Cette fonction est à appliquer aux startpoints et endpoints de la couche de lignes dont on utilisera l'azimut comme paramètre en entrée. Il suffira ensuite de créer une QUERY créant de nouveaux segments entre les startpoints et endpoints qui rentrent dans leurs champs de vision respectifs. Le gain en temps de calcul de cette méthode est de plus non négligeable.

Hors ligne

 

#5 Thu 26 May 2016 08:28

JD
Moderateur
Date d'inscription: 8 Aug 2013
Messages: 726

Re: [POSTGRESQL] Compléter des segments de linestring discontinus

Bonjour,
Si vous avez la possibilité, il serait intéressant que vous nous expliquiez comment vous avez réussi à vectoriser les cours d'eau, le résultat final, les limites de la méthodes etc... C'est hyper intéressant et il n'y a pas beaucoup de Retour sur le sujet.
Cordialement,

Hors ligne

 

#6 Thu 26 May 2016 10:07

Cmoreau
Participant occasionnel
Date d'inscription: 31 Mar 2016
Messages: 14

Re: [POSTGRESQL] Compléter des segments de linestring discontinus

Bonjour,

J'ai utilisé de très nombreuses méthodes et couches d'origines variées. Pour commencer j'ai refait des tracés théoriques  partir de mnts de 3 origines et résolutions différentes. Les plus fins donnaient des résultats précis et intéressants, cependant les MNTs en question étant peu corrigés et très hétérogènes on observait de nombreuses discontinuités ou incohérences par endroit (en particulier à cause des tracés de routes qui influençaient ladite donnée). Un outils de floutage régla le problème sur certaines discontinuités en repassant mon modèle par dessus une seconde fois. La BD alti, précise à 25 m, donna des résultats continus et exploitables sans traitement mais posa problème de par sa résolution insuffisante.

Le modèle en question utilise les outils de SAGA, Grass utilisant moins de ressources mais se révélant moins précis. La marche à suivre est la suivante sink detection (terrain analysis :: preprocessing) > fill sinks > channel network and drainage basins (terrain analysis :: channels). Les couches nécessaires à la création des tracés théoriques sont obtenues lors du sink route et fill sinks, channel network quand à lui possède un paramètre "Threshold" qui permet de changer à partir de quand Saga considère qu'il y a un cours d'eau (Cela se fait par décalage des ordres de Strahler affectés aux tracés crées par le module, il est possible d'obtenir une couche vectorisée comportant ces derniers)

L'autre méthode de vectorisation qui m'a prit beaucoup de temps est un peu plus expérimentale, compte tenu que j'ai extrait ces derniers de cartes anciennes. Pour celà j'ai installé sur qgis un module nommé SCP Roi, ou semi automatic classification, qui permet d'utiliser des outils proches de ENVI sous qgis. En classant l'image, par création de ROI sur des zones d’intérêt ou comportant des pixels spécifiques de ce que l'on recherche, j'ai extrait des séries de pixels que j'ai de nouveau injecté dans SAGA pour obtenir un squelette de mes tracés de cours d'eau (grâce à l'outils imagerie :: segmentation). Bien que discontinus et dénué de toute information quand aux ordres de Strahler ou la surface du BV en amont, les tracés obtenus suivent très bien ce que l'on a sur la carte d'origine et évitent d'avoir à tout numériser à la main.

Pour ce qui est de mon fill des discontinuités par l'utilisation de la fonction ci-dessus, il faudra si possible limiter son exécution sur toutes les fins de segments pour un gain de temps de calcul supplémentaire et éviter trop de correction manuelles. De plus, dans le cas ou deux segments crées s'intersectent autre part qu'au niveau de leur points de départ ou de fin, il est utile et intéressant de garder que le plus petit des deux.

Hors ligne

 

Pied de page des forums

Powered by FluxBB