Estou tendo dificuldades com uma consulta. Eu tenho uma rede de cadeias de linhas, cada uma com um valor na coluna n_type. Essa pode ser uma das poucas opções. Eu gostaria de gerar uma nova tabela que agrupe todas as cadeias de linha que são do mesmo tipo e que formam uma linha contínua.
Antes:
Depois de:
Aqui está o que eu tenho até agora. Ele retorna resultados, mas eles não fazem sentido - os tipos não correspondem e retornam muitos recursos.
Observe também que eu defini "contínua" como qualquer linha a um metro e meio de distância do seu vizinho e que se encontre com um ângulo inferior a 30 graus.
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
Eu assumi que uma consulta recursiva é o caminho a percorrer, mas estou feliz por ter provado que está errado nisso. As recursivas são um pouco difíceis de entender.
Editar: devo acrescentar que já tentei agregar usando ST_Union e ST_Linemerge e depois despejar o resultado. Isso meio que funciona, mas não representa interseções de mais de 30 graus e também não pode respeitar a tolerância de cinco pés para conectividade.
a.pk_uid != b.pk_uid
Respostas:
Sua solução está, pelo menos, faltando uma pré-encomenda dos componentes da linha, como disse John Barça.
Consultas recursivas são muito, muito difíceis de entender, eu diria.
Você deve tentar replicar o comportamento ST_Linemerge em uma nova função de banco de dados. Eu tentaria primeiro examinar a origem de uma implementação ST_Linemerge e replicar, alterando-a para produzir a contração de um ângulo de 30 graus.
Para descartar da agregação os segmentos que não estão em um ângulo de <30 graus., Você deve compará-los DENTRO de um loop de agregação.
fonte