[Gfoss] Da Linee 3D a Poligoni 3D in QGIS-Spatialite

a.furieri a lqt.it a.furieri a lqt.it
Mer 29 Nov 2017 20:36:06 CET


On Wed, 29 Nov 2017 08:08:44 -0700 (MST), titino2 wrote:
> Ciao a tutti.
> Sto riscontrando numerosi problemi per quanto riguarda la costruzione 
> di uno
> strato poligonale partendo da uno strato lineare.
> Le linee che utilizzo sono di tipo Linestring ZM 
> (st_geometrytype(geometry))
> e dove si intersecano, o sono spezzate o sono perfettamente 
> "snappate" ad un
> vertice (eseguiti tutti i controlli di GRASS v.clean); partendo da 
> queste
> linee vorrei produrre uno strato poligonale 3D.
>

ciao Titino2,

(visto che non ti firmi ti chiamero' con il nome della tua mailbox),
c'e' un punto che non mi e' del tutto chiaro.
quando tu dici "dove si intersecano o sono spezzate o sono 
perfettamente
snappate ad un vertice" intendi dire che ti stai aspettando che vengano
applicati automaticamente tutta una serie di "tagli" la dove ci sono
intersezioni tra i tuoi Linestrings ?
sarebbe importante chiarire meglio, perche' come vedremo tra poco non
si tratta affatto di un dettaglio irrilevante.


> Le linee sono caricate all'interno di un db SpatiaLite.
>

questo dettaglio e' praticamente irrilevante; quello che e' invece
assolutamente critico e' identificare con chiarezza quale sw stai
usando per le tue elaborazioni:
- quando parli di strumenti e tool box di QGIS ovviamente stai usando
   QGIS; il fatto che poi alla fine i dati vadano a finire dentro ad
   un DB spatialite oppure dentro ad uno shapefile o che altro non puo'
   avere nessuna influenza.
- quando invece parli di funzioni SQL e di query allora stai realmente
   usando SpatiaLite, ed in questo caso usare o meno QGIS e' del tutto
   irrilevante. io ti rispondero' solo ed esclusivamente per quanto
   riguarda SpatiaLite.


> ho provato con delle funzioni geometriche tipo st_buildarea, 
> st_poligonize o
> st_makepolygon ma anche in questo caso i risultati sono stati molto 
> poco
> soddisfacenti (sospetto per mia incapacità nello scrivere la query
> correttamente).
>

ok, queste sono effettivamente funzione SQL di SpatiaLite.
occhio pero' che sono molto diverse l'una dall'altra, non le puoi
certo usare a capocchia come se fossero la stessa cosa.
ti confermo comunque che tutte loro rispettano fedelmente le
dimensioni che ricevono in input, ragion per cui se i tuoi
Linestrings sono XYZM anche i Polygons in output saranno
altrettanto XYZM.
dettagli fortemente critici (specie nel tuo caso):

- la ST MakePolygon() si limita semplicemente a trasformare
   i Linestrings "chiusi" (con il primo vertice esattamente
   sovrapposto all'ultimo) in Rings e quindi in Polygons.
   ma se i tuoi Linestrings non sono gia' di per se "chiusi"
   la ST_MakePolygon() ti tornera' semplicemente dei NULL.
   quindi in base alle scarne notizie che ci hai dato,
   direi proprio che la ST_MakePolygon() non puo' essere
   la soluzione giusta per il tuo problema.

- la ST_BuildArea() e' un po' piu' sofisticata; se gli  passi
   tanti "pezzettini stagliuzzati" prova a riassemblarli in
   modo tale da formare dei Rings, e quindi dei Polygons.
   Attenzione pero': i "pezzettini" devono essere gia' tagliati
   a monte, perche' la ST_BuildArea() di per se non taglia mai
   nulla (per definizione), si limita semplicemente a riassemblare
   i Linestrings esattamente per come li ha ricevuti.
   Se non ci riesce (per esempio perche' ancora ci sono delle
   intersezioni non tagliate, oppure perche' "avanzano pezzi
   inutilizzati") ovviamente fallisce.

- infine c'e' la ST_Polygonize() che e' molto simile alla
   ST_BuildArea() eccetto che e' una funzione _AGGREGATA_,
   cioe' non lavora riga per riga ma elabora tutte le righe
   del dataset di input in un sol colpo.
   detto in soldoni: alla fine ti ritornera' un _SINGOLO_
   MultiPolygon, che tu dovrai pazientemente risolvere in
   tanti Poligoni elementari (ma lo puoi fare abbastanza
   facilmente chiamando la ElementaryGeometries).
   se ho capito correttamente il tuo problema e' questa
   la funzione che fa al caaso tuo (previo "stagliuzzamento"
   preventivo)

insomma, queste funzioni fanno esattamente quello che ti
aspetti da un classico approccio coerente di tipo SQL:
- evitano accuratamente di fare "magie nere" full-auto
   in cui non si capisce mai come siamo arrivati al
   risultato finale in un unico passaggio.
- fanno invece tanti piccoli passettini elementari, molto
   piu' facili da tenere sotto rigoroso controllo uno alla
   volta.
   ovviamente e' un approccio piu' flessibile, ma richiede
   uno sforzo piu' grande da parte dell'utente per produrre
   i risultati sperati.


> Comunque da tutte queste prove la funzione che più si
> avvicina al risultato da me sperato è il tool poligonize peccato che 
> mi
> restituisce poligoni 2D. Ho provato con ArcGis che ha generato dei 
> perfetti
> poligoni 3D coerenti con le linee di partenza.
> Avete qualche consiglio da darmi?
>

consiglio #1
============
prova a tagliare preventivamente tutti i tuoi Linestrings
la dove ci sono delle intersezioni; prova a dare un'occhiata
alla ST_LinesCutAtNodes(), potrebbe semplificarti il lavoro.
dopo di che darai tutto in pasto alla ST_Polygonize() che
provedera' a ricostruire tutti i Polygons (che naturalmente
saranno XYZM se i Linestrings di partenza erano XYZM).


consiglio #2
============
l'approccio di cui sopra non e' per nulla rigoroso, e ti
sconsiglio di usarlo a meno che il tuo dataset non sia
particolarmente semplice, liscio, pulito e ben strutturato.
il modo giusto e rigoroso per affrontare il tuo problema
e' quello di alimentare una Topologia; in questo modo
sarai assolutamente sicuro di potere risolvere anche le
casistiche piu' complesse ed intricate.
naturalmente usare una Topologia fa salire (e di molto)
l'asticella della complessita'.
se te la senti puoi dare un'occhiata alla nuovissima
Topologia di SpatiaLite:
https://www.gaia-gis.it/fossil/libspatialite/wiki?name=ISO+Topology

controindicazioni: la Topologia ISO supporta solo il
2D (XY) ed il 3D (XYZ), ma non il 4D (XYZM, come nel
tuo caso).

ciao Sandro


Maggiori informazioni sulla lista Gfoss