Analisi del bordo poligonale PostGIS (orientamento, lunghezza del bordo)


9

Sono piuttosto nuovo nel mondo dei GIS e in particolare PostGIS, quindi mi scusi se la risposta sembra evidente ...

Vorrei fare analisi su un certo numero di edifici. Una cosa che mi interessa sono le superfici delle loro facciate e il rispettivo orientamento. Come illustrato nella figura seguente, vorrei avere la lunghezza e l'orientamento (normale) di tutti i bordi in una serie di poligoni. Nell'esempio ho evidenziato solo una superficie.

inserisci qui la descrizione dell'immagine

Una tabella dei risultati potrebbe apparire così:

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

Tuttavia, non sono sicuro che sia un modo intelligente per memorizzare il risultato per ulteriori elaborazioni (ad es. Calcolare la distanza dal bordo al prossimo edificio, ecc.). Quindi la mia domanda è duplice:

  1. Esiste un'efficace funzione PostGIS in grado di analizzare i bordi di un poligono? Nel caso in cui non esistesse una funzione PostGIS nativa, sarei in alternativa interessato ad un approccio basato su Python.
  2. Quale sarebbe un modo intelligente per archiviare il risultato in una tabella PostGIS, dal momento che i poligoni possono avere un numero diverso di bordi?

2
Prima creare i segmenti del poligono: stackoverflow.com/questions/7595635/... Quindi il punto di inizio e le coordinate endpoint dovrebbe andare a colonne come x1, y1 e x2, y2 e che ST_Azimuth (ST_StartPoint (geometrie), ST_Endpoint (geometrie)) . ( postgis.org/docs/ST_Azimuth.html )
Tamas Kosa,

1
@TamasKosa: hai l'essenza di una buona risposta. Perché non espanderlo in uno? Inoltre, per le normali, gli azimut hanno bisogno di +/- pi / 2.
Martin F,

1
@TamasKosa Questo è un approccio a cui stavo anche pensando. Utilizzare ST_ExteriorRing e quindi ottenere gli azimut come dici tu. Come potrei archiviare idealmente i risultati, poiché gli edifici possono avere un numero diverso di bordi? In una tabella come ho descritto sopra? Concordo con MartinF, questa è quasi una risposta;)
1000

Solo curioso, perché vuoi normali ... esposizione al sole?
Martin F,

1
La prima parte della tua domanda ha avuto risposta: puoi usare ST_Dumppoints e ST_Azimuth. Per la seconda parte, dato che non ci sono elementi spaziali nell'output, penserei che sarebbe stato trovato un collegamento a polygonID e edge_id come hai trovato.
John Powell,

Risposte:


10

Ieri non ho avuto il tempo di crearlo in dettaglio ... Vedi la mia soluzione in 4 passaggi:

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;

L'ultima query ti fornisce gli ID di costruzione con un join spaziale usando st_touches. Spero che sia d'aiuto. Aggiornamento - In qgis la soluzione è simile alla seguente: inserisci qui la descrizione dell'immagine


1
Degno di nota! L'ho fatto funzionare. Grazie mille! Diventa un po 'lento con un gran numero di edifici. Gli azimut non sono normali al momento. Avresti anche idea di come affrontarlo? Non sono sicuro di come trovare il lato "esterno" del poligono.
1000,

1
aggiungi 90 deggrees all'azimut in radiante in questo modo: gradi (st_azimuth (ff.sp, ff.ep) +1.57079633). A volte genererà valori superiori a 360. Ma con una query di aggiornamento è possibile sostituirli. Se desideri utilizzare come vista statica, crea "CREA VISTA MATERIALIZZATA" e non sarà lento solo alla prima volta.
Tamas Kosa,

2
Non proprio. Supponendo che il Nord sia 0 °, questo darà la normale verso l' interno del poligono / edificio (come si vede anche nello screenshot). Ma hai ragione: un semplice UPDATEdovrebbe fare il trucco. Grazie ancora per questa ottima soluzione. Aspetterò ancora qualche giorno se compaiono altre risposte, prima di accettare.
n.

1
Che dire ST_ForceRHR? Questa risposta in realtà sembra a posto.
Jakub Kania,

@JakubKania Ho provato a trovare una ST_ForceRHRsoluzione, ma non ci sono riuscito. Sarei grato per i suggerimenti ... Ho provatoST_Dump(ST_Boundary(ST_ForceRHR(the_geom)))
n1000
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.