Aggancio dei nodi iniziale e finale delle linee ad altre linee in PostGIS


9

Ci sono molti esempi che mostrano come agganciare le linee ai punti, ma non sono stato in grado di trovare alcun modo (veloce!) Per agganciare i nodi iniziale e finale delle stringhe di linea ai nodi di altre linee.

In sostanza voglio "pulire" il mio livello in postgis (2.0), spostando insieme punti quasi simili e cucendo piccole aperture tra le stringhe di linea.

Non importerebbe così tanto se aggiungo un altro nodo, sposto il primo / ultimo nodo di una delle due linee o muovo entrambi i punti al centro.

Ho trovato due opzioni, ma non sono sicuro di come iniziare con una di esse:

La seconda opzione sembra fattibile, ma qualsiasi aiuto su come seguire questo metodo sarebbe molto apprezzato.

Risposte:


6

Sono riuscito a risolverlo, senza usare i menzionati strumenti GRASS o le funzioni topologiche.

Fondamentalmente prendo tutti i nodi iniziale e finale, li inserisco in una nuova tabella temporanea, inserisco un buffer attorno ad essi, unisco gli oggetti buffer e sposto tutti i nodi trovati in ciascun buffer sul centroide del buffer.

Al termine, sposto i punti di inizio e fine originali nella nuova posizione.

Più facile del previsto e ancora più veloce, ma mi aspettavo che PostGIS avesse una funzione integrata per questo - sarebbe ancora più veloce.

Modifica: nell'interesse di restituire alla comunità, questo è il mio codice (abbastanza scadente) per ora.

drop table if exists nodes;
drop table if exists nodes2;
drop table if exists buffers;

-- Get Start and End nodes
select ST_StartPoint(wkb_geometry) startnode,  ST_EndPoint(wkb_geometry) endnode,    ogc_fid into nodes  from sourceTable;
-- Combine all nodes into one table for easier queries
select startnode node, ogc_fid into nodes2 from nodes;
insert into nodes2 select endnode node, ogc_fid from nodes;

-- Some indexes to speed everything up
CREATE INDEX nodesstart_idx ON nodes USING gist  (startnode);
CREATE INDEX nodesend_idx ON nodes USING gist  (endnode);
CREATE INDEX nodes2_idx ON nodes2 USING gist  (node);
CREATE INDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);

-- Create buffers, combine them, split combined objects again
select (ST_Dump(ST_Union(ST_Buffer(node, 1)))).geom geom into buffers from nodes2;
CREATE INDEX buffers_idx ON buffers USING gist  (geom);

-- Update start/end nodes table
UPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));
UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));
-- Update original points
update sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry, 0, (select startnode from nodes where ogc_fid=sourceTable.ogc_fid)), 
ST_NumPoints(wkb_geometry) - 1, (select endnode from nodes where ogc_fid=sourceTable.ogc_fid));

DROP TABLE nodes;
DROP TABLE nodes2;
DROP TABLE buffers;

Questa risposta assomiglia un po 'al suggerimento "non topologico" della mia risposta. Sarebbe gentile se hai dato un voto o hai selezionato la risposta. Quelli sono ciò che alimenta la comunità qui :)
katahdin

Hai ragione. Ho valutato la tua risposta e modificherò la mia risposta per includere il mio codice.
Jelmer Baas

4

Ecco tre opzioni. Speriamo che uno possa aiutare.

v.clean

Utilizzando gli strumenti GRASS in QGIS è possibile ripulire la topologia di un oggetto spaziale. L'utente @RK fornisce una buona serie di istruzioni su come eseguire questa operazione in risposta a una domanda diversa . Il vantaggio offerto da GRASS è che inferirà la topologia del file di forma. Lo svantaggio per la tua situazione è che i tuoi dati non sono in uno shapefile. Ovviamente potresti esportare i dati da Postgres in un file di forma usando lo strumento "Aggiungi livello PostGIS", ma questo è un passo in più.

Funzioni PostGIS non topologiche

In PostGIS è possibile utilizzare le funzioni ST_EndPoint e ST_StartPoint per ottenere la fine e il punto iniziale per una stringa lineare . Quindi, utilizzando una combinazione di ST_DWithi n e ST_Distance , è possibile trovare il punto iniziale o finale più vicino su una geometria vicina. Se hai molti punti, ST_DWithin accelera molto la query, supponendo che tu abbia un indice in atto. Da lì dovrai stabilire una regola che definisce quali punti devono essere modificati e quali sono fissi.

Il vantaggio qui è che non è necessario inviare i dati a GRASS per la pulizia, ma ci sono alcune insidie ​​a cui prestare attenzione.

Funzioni topologiche PostGIS

La domanda faceva riferimento alle funzioni topologiche di PostGIS. Funzionano alla grande, ma, come descrive il wiki , devi definire esplicitamente bordi, nodi e facce. Chiaramente questo sarà un problema per il tuo set di dati poiché hai riscontrato problemi con la topologia.


1

PostGIS ha funzioni di snap ... forse aiuteranno?

ST_Snap: Aggancia segmenti e vertici della geometria di input ai vertici di una geometria di riferimento.

ST_SnapToGrid: Aggancia tutti i punti della geometria di input su una griglia normale.


1
Grazie, sono a conoscenza di queste funzioni. ST_Snap scatta TUTTI i nodi, voglio solo il nodo iniziale e finale. ST_SnapToGrid non è davvero adatto perché modifica tutta la geometria esistente e ha la possibilità di spostare nodi più vicini, perché a malapena rientrano in un altro segmento.
Jelmer Baas
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.