J'ai du mal avec une requête. J'ai un réseau de chaînes de lignes, chacune avec une valeur dans la colonne n_type. Cela peut être l'une d'une poignée d'options. Je voudrais générer un nouveau tableau qui regroupe toutes les chaînes de lignes qui sont du même type et qui forment une ligne continue.
Avant:
Après:
Voici ce que j'ai jusqu'à présent. Il renvoie des résultats mais ils n'ont aucun sens - les types ne correspondent pas et retournent trop de fonctionnalités.
Veuillez également noter que j'ai défini «continu» comme toute ligne à moins de 5 pieds de son voisin et se rencontrant à moins d'un angle de 30 degrés.
WITH RECURSIVE all_links (i, pk_uid, n_type, geom) AS (
SELECT 1 AS i,
pk_uid,
n_type,
geom
FROM network
WHERE n_type != 'none'
UNION ALL
SELECT a.i + 1,
b.pk_uid,
b.n_type,
b.geom
FROM network b, all_links a
WHERE b.n_type = a.n_type
AND b.geom <#> a.geom <= 5 --lines are continuous if within 5 feet of neighbor
AND ABS( DEGREES( 3*pi() - st_azimuth(st_startpoint(a.geom),st_endpoint(a.geom)) + st_azimuth(st_startpoint(b.geom),st_endpoint(b.geom)))::int % 360 - 180) <= 30 ) --only take links within 30 degrees of the same angle
SELECT i, n_type, ST_Union(the_geom) FROM all_links GROUP BY i, n_type
J'ai supposé qu'une requête récursive était la voie à suivre, mais je suis heureux d'avoir tort. Les récursifs sont un peu difficiles à comprendre.
Edit: je dois également ajouter que j'ai déjà essayé d'agréger à l'aide de ST_Union et ST_Linemerge, puis de vider le résultat. Cela fonctionne un peu, mais ne tient pas compte des intersections de> 30 degrés et ne peut pas non plus respecter la tolérance de cinq pieds pour la connectivité.
a.pk_uid != b.pk_uid
Réponses:
Votre solution manque, au moins, une précommande de composants de ligne comme l'a dit John Barça.
Je dirais que les requêtes récursives sont très, très difficiles à gérer.
Vous devez essayer de répliquer le comportement ST_Linemerge dans une nouvelle fonction de base de données. J'essaierais d'abord de regarder la source d'une implémentation de ST_Linemerge et de la répliquer, en la modifiant pour produire la contraction d'angle de 30 degrés.
Pour éliminer de l'agrégation les segments qui ne sont pas à un angle <30 degrés, vous devez les comparer À L'INTÉRIEUR d'une boucle d'agrégation.
la source