Análise de arestas de polígono PostGIS (orientação, comprimento da aresta)

9

Sou um pouco novo no mundo dos SIG e, principalmente, do PostGIS, então, desculpe-me se a resposta parecer evidente ...

Eu gostaria de fazer uma análise em vários edifícios. Uma coisa que me interessa são as superfícies das fachadas, juntamente com a respectiva orientação. Como ilustrado na figura abaixo, eu gostaria de ter o comprimento e a orientação (normal) de todas as arestas em uma série de polígonos. No exemplo, destaquei apenas uma superfície.

insira a descrição da imagem aqui

Uma tabela de resultados pode ficar assim:

building_id | edge_id | orientation | edge_length
-------------------------------------------------
      1     |    1    |     315     |    10.0
      1     |    2    |      45     |     7.0
      1     |   ...   |     ...     |     ...

No entanto, não tenho certeza se é uma maneira inteligente de armazenar o resultado para processamento adicional (por exemplo, calcular a distância da borda até o próximo edifício, etc.). Então, minha pergunta é dupla:

  1. Existe uma função PostGIS eficiente que pode analisar as arestas de um polígono? Caso não exista uma função PostGIS nativa, eu estaria interessado em uma abordagem baseada em Python.
  2. Qual seria uma maneira inteligente de armazenar o resultado em uma tabela PostGIS, já que os polígonos podem ter diferentes números de arestas?
n1000
fonte
2
Primeiro, crie os segmentos do polígono: stackoverflow.com/questions/7595635/… Em seguida, as coordenadas do ponto inicial e do ponto final devem ir para colunas como x1, y1 e x2, y2 e ST_Azimuth (ST_Startpoint (geometries), ST_Endpoint (geometries)) . ( postgis.org/docs/ST_Azimuth.html )
Tamas Kosa
11
@ TamasKosa: Você tem a essência de uma boa resposta. Por que não expandi-lo em um? Além disso, para normais, os azimutes precisam de +/- pi / 2.
Martin F
11
@TamasKosa Essa é uma abordagem em que eu também estava pensando. Use ST_ExteriorRing e obtenha os azimutes como você diz. Como idealmente eu armazenaria os resultados, já que os edifícios podem ter um número diferente de arestas? Em uma tabela como eu descrevi acima? Eu concordo com o MartinF, isso é quase uma resposta;) #
n1000
Apenas curioso, por que você quer normais ... exposição ao sol?
Martin F
11
A primeira parte da sua pergunta foi respondida - você pode usar ST_Dumppoints e ST_Azimuth. Para a segunda parte, como não há elementos espaciais para a saída, eu acho que um link para polygonID e edge_id como você seria encontrado.
John Powell

Respostas:

10

Ontem não tive tempo de criá-lo em detalhes ... Veja minha solução em 4 etapas:

CREATE OR REPLACE VIEW bd_segment AS
SELECT
      ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) AS sp,
      ST_PointN(geom, generate_series(2, ST_NPoints(geom)  )) AS ep
    FROM
       -- extract the individual linestrings
       (SELECT (ST_Dump(ST_Boundary(the_geom))).geom
       FROM bd) AS linestrings;

CREATE OR REPLACE VIEW bd_segment_geom AS
SELECT sp, ep, st_makeline(sp, ep) 
FROM bd_segment;

CREATE OR REPLACE view bd_segment_id AS 
SELECT bd.gid, row_number() 
    OVER (order by bd.gid), degrees(st_azimuth(ff.sp, ff.ep)-1.57079633) AS az_deg,
    ST_LENGTH(ff.st_makeline) , ff.st_makeline FROM bd_segment_geom ff
JOIN bd ON st_touches(ff.st_makeline, bd.the_geom)
GROUP BY bd.gid, ff.sp, ff.ep, ff.st_makeline;

UPDATE bd_segment_id
SET az_deg = az_deg + 360
WHERE az_deg < 0;

A última consulta fornece os IDs de construção com uma junção espacial usando st_touches. Espero que ajude. Atualização - No qgis, a solução fica assim: insira a descrição da imagem aqui

Tamas Kosa
fonte
11
Impressionante! Eu tenho que trabalhar. Muito obrigado! Torna-se um pouco lento com um grande número de edifícios. Os azimutes não são normais no momento. Você também teria uma idéia de como lidar com isso? Não sei como encontrar o lado "exterior" do polígono.
N1000
11
adicione 90 graus ao azimute em radiano assim: graus (st_azimuth (ff.sp, ff.ep) +1.57079633). Às vezes, gera valores maiores que 360. mas com uma consulta de atualização, você pode substituí-los. Se você deseja usar como uma exibição estática, crie "CRIAR VISTA MATERIALIZADA" e ela não será lenta apenas na primeira vez.
Tamas Kosa
2
Não é bem assim. Supondo que o norte seja 0 °, isso dará o normal para o interior do polígono / prédio (como também é visto na sua captura de tela). Mas você está certo - um simples UPDATEdeve fazer o truque. Obrigado novamente por esta ótima solução. Vou esperar mais alguns dias se outras respostas aparecerem antes de aceitar.
N1000
11
Que tal ST_ForceRHR? Essa resposta realmente parece boa.
Jakub Kania
@JakubKania Tentei encontrar uma ST_ForceRHRsolução, mas não foi bem-sucedida. Seria grato por dicas ... Eu tenteiST_Dump(ST_Boundary(ST_ForceRHR(the_geom)))
n1000