Unire un sacco di piccoli poligoni per formare un poligono più grande con PostGIS?


47

Ho il seguente livello usando SRID 27700 in postgis:

inserisci qui la descrizione dell'immagine

È ogni regione amministrativa nel Regno Unito e (come puoi vedere dal raggruppamento dei colori), ognuno di essi ha un campo di testo che specifica la contea in cui si trovano.

Quello che mi piacerebbe fare è creare poligoni di contea più grandi da quelli più piccoli in una data contea, quindi EG nella foto soprattutto i poligoni color verde acqua formerebbero un grande poligono dal singolo anello esterno che contiene tutti i poligoni in quello il colore, come tutti i viola, i marroni, i rosa, i grigi, ecc. dovrebbe formare un poligono.

Ho già provato quanto segue:

insert into parishesmerged (geometry)
select astext(multi(ST_Union(the_geom))) as the_geom from parishes
group by county_name

Ma continua a generare geometrie rotte che poi ho grossi problemi a elaborare ulteriormente.

Sto cercando di creare una mappa a livello di contea più semplice con le principali aree di output in.

Nessuna soluzione deve trovarsi nemmeno in Postgis, ho installato lo stack OS4Geo completo, l'ultima versione di QGis e più utility di quante non riesca a scuotere.

Le uniche cose che non ho sono i ragazzi grandi come ArcGis (anche se potrei avere un vecchio Mapinfo in giro da qualche parte)


Per la cronaca, il set di dati che sto cercando di creare è di accompagnare un libro GIS che sto scrivendo rivolto ai programmatori .NET che desiderano scrivere applicazioni GIS usando .NET


Dopo aver provato i suggerimenti di seguito, quello che ha funzionato meglio è stata la soluzione "Paul Ramseys".

Ora ho un bel file di contee e distretti semplificato che è abbastanza semplice per il mio libro, ma abbastanza complesso da permettermi di dimostrare un interessante SQL geo-spaziale.

Anche se la soluzione di Paul alla fine è stata quella che ha funzionato per me, ho anche attinto alle altre risposte per cose come semplificare la mappa poligonale e ridurre ulteriormente la complessità.

Ciò che ho osservato osservando ciò, tuttavia, mentre ST_Collect è effettivamente più veloce di ST_Union, correre per correre è stato anche il principale responsabile delle geometrie rotte. La mia ipotesi è che l'aumento di velocità si ottiene a scapito di una minore precisione nella funzione principale.


Questo processo è noto come "dissolvenza". Non ho esperienza con PostGIS, ma credo che sia possibile utilizzare il comando ST_Union per eseguire la dissoluzione.
Dmahr,

Ciao Dmahr, grazie per il chiarimento, non ero sicuro di come si chiamava, tuttavia se leggi la mia domanda vedrai che l'ho già provato :-)
shawty

Oops, scusa ... non l'ho visto. Hai provato l'istruzione select senza la astext(multi())parte? Sto solo uscendo da quello che vedo negli altri esempi di dissolvenza di PostGIS.
Dmahr

Non ancora, ci proverò ora. Tks. Hai un link per dissolvere esempi?
shawty

Modifica per express se vuoi "il singolo anello esterno" o no. (vedi la mia risposta)
Peter Krauss,

Risposte:


43

ST_Union funzionerebbe, ma il lavoro di linea è quasi sicuramente non pulito. Quindi i confini delle tue piccole cose non si adattano perfettamente. Puoi agganciarli delicatamente a una griglia per provare ad aumentare le probabilità che i vertici siano allineati, ma scommetto che avrai ancora alcuni casi che non funzionano. O saranno oltre la tolleranza o, più probabilmente, ci saranno punti in cui i vertici non sono accoppiati, quindi c'è una linea da un lato e un vertice dall'altro.

 CREATE TABLE merged AS
 SELECT ST_Union(ST_SnapToGrid(the_geom,0.0001)) 
 FROM parishes
 GROUP BY county_name;

Se si dispone di PostGIS 2.0, la creazione di una struttura di topologia con tolleranza potrebbe portarti alla risposta che stai cercando, se hai fortuna.


Un buon indizio per la correzione delle geometrie, ma riguardo a "... un grande poligono dal singolo anello esterno che contiene tutti i polis ..."?
Peter Krauss,

Non sapevo di 'SnapTo' Ci proverò :-) Tks. Sfortunatamente, no, non usando PG 2 ancora, l'aggiornamento è in preparazione però.
Shawty

Non sono sicuro che la sintassi sia corretta. Per postgis.net/docs/ST_Union.html , non esiste una firma che accetta un numero nel secondo parametro.
Aren Cambre,

Hai ragione, la parentesi era nel posto sbagliato. Modificato.
Paul Ramsey,

c'è un mysql equivalente a questo? continuo a ricevere Incorrect parameter count in the call to native function 'ST_Union'e non so se si tratta di una limitazione mysql.
Jayen,

7

Dici che devi "... formare un grande poligono dal singolo anello esterno che contiene tutti i polis ...". L'ST_ExteriorRing fa questo,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_Union(GEOM)))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

È possibile utilizzare ST_Union (), come suggerito, oppure testare con ST_Collection ().


NOTE: per evitare piccoli lops o "geometrie rotte" puoi usare st_convexhull e / o ST_Simplify per ogni geom,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_union(ST_Simplify(GEOM,0.5))))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

e controlla le tue geometrie,

SELECT * FROM (
   SELECT gid, ST_IsValid(geom) as valid, ST_IsSimple(geom) as simple 
   FROM GEOMTABLE) AS t  
WHERE NOT(valid AND simple); 

Scusate la confusione: ciò che intendevo con la mia descrizione era un poligono più grande creato da quelli più piccoli, mi rendo conto che a seconda del contesto "Anello esterno" può significare cose diverse per persone diverse, la mia intenzione era di descrivere un singolo poligono creato dal limite presente attorno a ciascun gruppo poligonale.
Shawty

7

La funzione ST_Collect è una funzione "aggregata" nella terminologia di PostgreSQL

" SELECT ST_Collect(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN" restituirà una GEOMETRYCOLLECTION separata per ciascun valore distinto di ATTRCOLUM

http://postgis.net/docs/ST_Collect.html

Nota: ST_Collect è molto più veloce di ST_Union


3
L'ho provato e ho ottenuto risultati leggermente diversi, ma una collezione di geometrie è ciò di cui ho bisogno? Sto essenzialmente cercando di creare un grande poligono, opzionalmente con dei buchi (in particolare nel Derbyshire e nel nottinghamshire dove sia il derby che il Nottingham formano distretti separati proprio al centro. Tuttavia ho osservato la differenza di velocità, quindi è kewl.
Shawty

2

Presumo dalla tua domanda che stai utilizzando il prodotto Boundary-Line di Ordnance Survey. In tal caso, include già un set di dati a livello di contea, quindi non è necessario tentare di generarlo da aree parrocchiali di livello inferiore.

Se non stai usando Boundary-Line, ti consiglio di farlo in quanto è gratuito sotto la licenza OpenData del sistema operativo e ha un livello di contea come file di forma che puoi caricare direttamente in PostGIS.


2
Che ne dici di fornire un link per coloro che non lo conoscono? Grazie.
Jonatr

1
Ciao CHEnderson, in effetti, hai ragione, sì, sto usando il set di dati del layer di confine di OS Opendata, sfortunatamente i confini della contea non sono completi, il file di forma della contea attuale include solo quelli che sono denominati contee, i distretti di Londra contengono le aree intorno Londra e altri file hanno tutti delle parti, alcuni livelli più bassi e più piccoli degli altri. L'unico file che ha l'intero profilo del Regno Unito e, successivamente, ogni possibilità di estrarre tutte le contee di livello superiore e i confini municipali in un livello è il livello delle parrocchie, quindi perché sto tentando di farlo.
shawty

Per coloro che sono interessati è possibile scaricare i confini della contea e altro, proprio qui: ordnancesurvey.co.uk/oswebsite/products/os-opendata.html
shawty
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.