Come a degradare in modo intelligente o dati liscia GIS (semplificando poligoni)?
Domanda
Ho dettagliato mappe contea americane, dalle TIGER pubblicitario insiemi di dati. Come potrei provare, liscio, o degradare i dati in modo che ricevo più dritto, più squadrate, meno forme "rumorosi" per rappresentare le caratteristiche geografiche - in questo caso solo i confini provinciali e confini di stato, ma forse anche nel caso generale?
Il campionamento potrebbe accadere in tempo di rendering se questo può essere fatto in modo efficiente, o di un insieme di dati in parallelo potrebbe essere generato e conservato. Sto usando PostGIS , e le linee sono multi-polilinee generate da shp2pgsql
- ma qualsiasi soluzione in cui si prende una linea ondulata e ridurlo ad una linea fluida di circa lo stesso significato ad un interprete umano sarebbe molto utile.
Soluzione
Il problema semplicemente buttando via punti è che si può alterare rapidamente la forma del poligono originale. Un approccio migliore è a considerarlo dalla direzione opposta; iniziare con un'approssimazione di base del poligono e poi perfezionare l'alto verso la vostra forma complessa.
Un eccellente esempio di questo approccio è il Douglas-Puecker algoritmo . Si inizia con due vertici tratte dal pieno poligono. Aggiungere un terzo vertice selezionando quella che si trova più lontano da un bordo tracciata tra i primi due vertici. Continuare ad aggiungere punti fino ad avere qualcosa che assomiglia sufficientemente poligono originale.
Altri suggerimenti
Douglas-Peucker è sicuramente il giusto approccio. Ci sono alcuni semplici modi per accedere alle implementazioni di esso in PostGIS e QGIS che ho pensato di aggiungere qui per coloro che vengono in questo post con una domanda simile. L'obiettivo è quello di iniziare con qualcosa di simile:
e finire con qualcosa di simile:
In PostGIS Douglas-Peucker è implementata come simplify
, la sintassi, dettagliato qui a bostongis.org , è qualche variante:
SELECT transform(simplify(transform(the_geom, 2249), 500),4326) from the_geo_table
Questo ha funzionato molto bene anche sul set di dati nazionale piena, con alcuni pochi errori che sembrano a causa di dati sottostanti cattivi. Si scopre anche che in QGIS il Tools > Geometry Tools > Simplify Geometries
voce di menu esportare uno shapefile semplificata di qualsiasi geometria e aggiungerlo come strato per il progetto corrente.
Questa è una bella fondamentale strumento-set e ho fatto la domanda a un livello troppo basso, anche se è stato bello imparare la matematica di base, c'è una buona spiegazione di che qui:! http://www.mappinghacks.com/code/PolyLineReduction/ , insieme al codice di esempio che si rivela non essere troppo necessaria
Invece di QGIS, io suggerisco di usare ogr2ogr perché non elimina i poligoni !
ogr2ogr output.shp input.shp -simplify 0.0001
Ecco un semplice algoritmo di smoothing iterativo:
per ogni tre punti sequenziali qualsiasi percorso, se il punto centrale ha intersezioni e si trova qualche piccolo angolo di soglia del percorso diretto tra i due punti esterni, rimuoverlo.
Ripetere fino a soddisfarlo.
Si potrebbe anche provare l'algoritmo di Visvalingam, che rimuove in modo iterativo la parte meno percepibile di una linea. Ecco una grande spiegazione di tale algoritmo:
Si potrebbe anche usare Simplify.js che utilizza una combinazione di Douglas-Peucker e algoritmi Radial distanza. Ci sono anche link a molte porte verso altre lingue elencate sul github progetto
Risposta da @unmounted è corretto, ma vorrei aggiungere un altro suggerimento.
Usare sempre la funzione ST_SimplifyPreserveTopology invece di ST_Simplify in PostGIS. Entrambi utilizzano lo stesso algoritmo sottostante (Douglas-Peucker), ma il primo evita eventuali semplificazioni che porterebbe a geometrie non valide. Ad esempio, può provocare ST_Simplify geometria che si interseca.