Crea diagramma voronoi da segmenti di linea


14

Sto cercando un modo per creare un diagramma voronoi basato su segmenti di linea anziché su punti. Vedi l'esempio seguente (tratto da questa presentazione ).

Idealmente, vorrei qualcosa che potessi scrivere da Python, ma sarebbe accettabile anche una soluzione che utilizza ArcGIS o simili.

diagramma di voronoi da segmenti di linea

L'unica libreria per fare ciò che ho trovato finora è openvoronoi , che sembra promettente. Ce ne sono altri?


1
Questo probabilmente aiuterà: gis.stackexchange.com/questions/53414/…
Dan C

Grazie. Non sono sicuro del perché questa domanda non sia emersa nelle mie ricerche.
Snorfalorpagus,

Risposte:


5

Noi (un team universitario) abbiamo progettato un'implementazione per questo usando un componente aggiuntivo ArcGIS 10.0 e ArcObjects. L'applicazione è completamente gratuita. L'implementazione utilizza una metodologia raster che prende come punti di input, linee o poligoni per creare diagrammi Voronoi ordinari o moltiplicati (o una combinazione di quanto sopra, ovvero è possibile utilizzare uno di ogni tipo di forma, creando un singolo diagramma impostato da tre classi di caratteristiche distinte). È ancora in fase di sviluppo, ma dovrebbe essere abbastanza stabile, soprattutto se si desidera fare solo linee. Per funzionare, il componente aggiuntivo richiede la licenza Analista spaziale. Il codice stesso è open source, quindi sentiti libero di farlo come preferisci.

https://github.com/UNTGeography/VoronoiDiagramsGIS

Utilizza un metodo simile a quello "Allocazione euclidea" descritto nella risposta di @ radouxju e utilizza la direzione del flusso / raster del bacino per creare poligoni vettoriali dal raster risultante.



3

Voronoï è inizialmente progettato per i punti. Ecco i due metodi che posso immaginare per il tuo problema (citando gli strumenti ArcGIS, ma probabilmente possibili con Shapely):

1)

a) creare punti lungo le linee (ad es. densificare quindi mettere i vertici sulla linea)

b) creare poligoni di Thiessen

c) dissolvere i poligoni di Thiessen in base alle linee che intersecano

2)

a) con analista spaziale, calcolare l'allocazione euclidea alle linee

b) convertire ogni zona in un poligono


3

Per alcuni clienti un paio di compagni di lavoro e io abbiamo lavorato alla creazione di 2 strumenti di geoprocessing che lo fanno. Mentre gli strumenti di geoprocessing non sono disponibili pubblicamente, il python e il C # che abbiamo usato sono:

Sia il C # che il wrapper python in realtà si basano sull'API C ++ Boost Voronoi: http://www.boost.org/doc/libs/1_54_0/libs/polygon/doc/voronoi_main.htm

Si noti che l'API consuma molta memoria. Questo non è un problema se si utilizza Geoprocessing per 64 bit, ArcGIS Pro o QGIS. Questa è una limitazione se sei su ArcGIS Desktop in quanto a 32 bit. (Una rete stradale dettagliata di almeno 40.000 file dovrebbe essere sufficiente per raggiungere il limite di memoria)


1
In realtà ho creato uno strumento di geoprocessing per ArcMap e ArcGIS Pro che si basa sulla libreria pyvoronoi: github.com/fabanc/Boost-Voronoi-For-ArcGIS
Fabien Ancelin

2

ET Geowizards (un plugin per Arc) ha uno strumento per questo che accetta Polilinee (vedi screenshot sotto). Sfortunatamente avrai bisogno del prodotto concesso in licenza per eseguire lo strumento, ma penso che dovrebbe fare il trucco.

inserisci qui la descrizione dell'immagine


0

Inoltre un altro modo per risolvere il tuo compito con PostgreSQL / PostGIS.

Se le linee sono brevi e semplici, esegui lo script:

WITH
tbla AS (SELECT (ST_Dump(geom)).geom geom FROM <line_name_table>),
tblb AS (SELECT (ST_DumpPoints(geom)).geom geom FROM tbla
        UNION
        SELECT ST_Centroid(geom) geom FROM tbla),
tblc AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tblb)
SELECT ST_Union(a.geom) geom FROM tblc a JOIN tbla b ON ST_Intersects(a.geom, b.geom) GROUP BY b.geom;

Vedi il risultato

Se le linee sono lunghe, quindi eseguire lo script:

WITH
tbla AS (SELECT (ST_Dump(geom)).geom geom FROM <line_name_table>),
tblb AS (WITH btbl AS (SELECT (ST_Dump(geom)).geom geom FROM tbla),
intervals AS (SELECT generate_series (0, 9) as steps)
SELECT steps AS stp, ST_LineInterpolatePoint(geom, steps/(SELECT count(steps)::float-1 FROM intervals)) geom FROM btbl, intervals GROUP BY intervals.steps, geom),
tblc AS (SELECT ((ST_Dump(ST_VoronoiPolygons(ST_Collect(geom)))).geom) geom FROM tblb)
SELECT ST_Union(a.geom) geom FROM tblc a JOIN tbla b ON ST_Intersects(a.geom, b.geom) GROUP BY b.geom;

Vedi il risultato

Se necessario, compatta il numero di punti sulle linee, nel mio esempio questo è il punto 10.

Soluzioni originali.

Questo script si chiama: ST_VoronoiDiagramsFromLines.


Non l'ho ancora eseguito, ma sembra che crei i poligoni voroni usando i vertici delle geometrie e poi li unisca (con un'unione) se toccano le geometrie originali. È corretto? In tal caso è un'approssimazione OK purché le geometrie originali abbiano molti vertici e nessun segmento lungo senza nessuno.
Snorfalorpagus il

Testato da: PostgreSQL 11.1, PostGIS 2.5 USE_GEOS = 1 USE_PROJ = 1 USE_STATS = 1 ...
Cyril Mikhalchenko
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.