Come dividere le strade OSM in singoli segmenti agli incroci?


10

Voglio creare una rete stradale da utilizzare con pgRouting utilizzando i dati OpenStreetMap. Ho caricato uno shapefile da GeoFabrik in una tabella Postgres (con PostGIS abilitato). Tuttavia, un problema che ho avuto è stato che le strade non finiscono sempre agli incroci, quindi ho deciso di dividerli tutti ad ogni incrocio o incrocio.

Per identificare tutte le intersezioni in cui le strade si incrociavano o si intersecavano, ho usato quanto segue SQL(simile a una domanda precedente ):

CREATE TABLE split_points as
SELECT DISTINCT    
   ST_GeometryN(ST_Intersection(a.geom, b.geom),1) as geom      
FROM
   roads as a,
   roads as b
WHERE
    ST_Touches(a.geom, b.geom)
OR
    ST_Crosses(a.geom, b.geom)    
    AND a.gid != b.gid
GROUP BY
   ST_Intersection(a.geom, b.geom);

Ora voglio dividere le strade usando questi punti. Ho usato il seguente approccio:

CREATE TABLE split_roads as
SELECT     
    ST_GeomFromEWKB((ST_Dump(ST_Split(g.geom, blade.geom))).geom) As geom,
    generate_series(1,ST_NumGeometries((ST_Split(g.geom, blade.geom)))) as gid
FROM    
    split_points as blade,
    roads as g
WHERE
    ST_Intersects(g.geom, blade.geom);

Il problema con questo approccio diviso è che l'intera lunghezza della strada rimane in aggiunta a tutti i pezzi divisi. Per rimuovere queste geometrie stradali non suddivise che sono state incluse, ho usato la ST_Equals()funzione per identificarle ed eliminarle:

DELETE FROM split_roads USING roads
WHERE ST_Equals(split_roads.geom, roads.geom)

Tuttavia, questo approccio non rimuove tutte le geometrie non divise originali (sebbene ne rimuova alcune). Esiste un approccio migliore per la cancellazione (o nel complesso) in modo da avere solo le geometrie divise in una tabella?


Secondo la documentazione, ST_Split non restituisce la geometria originale, non divisa. Che cos'è quel '.geom' extra che si blocca all'ultima parentesi di chiusura nella prima riga dell'istruzione SELECT? Potrebbe essere semplice come rimuoverlo.
Scro,

@Scro a cui .geomti riferisci? Non riesco a individuarlo!
djq,

Immagino tecnicamente che sarebbe la seconda riga dell'istruzione SELECT. Mi riferisco anche alla creazione della tabella "split_roads". È la linea che termina con '))). Geom) come geom'.
Scro,

hmm, ricevo un errore quando lo faccio. ERROR: function st_geomfromewkb(geometry_dump) does not exist LINE 4: ST_GeomFromEWKB((ST_Dump(ST_Split(g.geom, blade.geom))))... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
djq,

L'intera riga era simile alla seguente: ST_GeomFromEWKB ((ST_Dump (ST_Split (g.geom, blade.geom)))) Come geom,
Scro,

Risposte:


6

Non è una vera soluzione al tuo problema, ma prova osm2po ... crea il codice SQL perfetto per il routing in pgrouting: http://osm2po.de/


Grazie per il suggerimento Ho provato osm2pgroutingma richiede più memoria di quella del mio server e termina senza finire.
djq

2
@djq osm2po può gestire file molto più grandi di osm2pgrouting. Si può anche caricare planet.osm
Sottosuolo

ah, inizialmente pensavo osm2pofosse un errore di battitura. Esiste un modo semplice per installarlo su Ubuntu?
djq,

È un file JAR compilato pronto (java). Basta eseguirlo come spiegato sul sito Web.
Studente GIS,

11

Risposta semplice: No. Non dovresti farlo in questo modo.

Dai Shapefile della strada OSM, è impossibile distinguere tra incroci e sopra / sottopassi. Creerai incroci che non esistono nella realtà se dividi tutte le strade che sembrano attraversare.

Dovrai sporcarti le mani con il file OSM originale, se non vuoi usare strumenti esistenti come osm2pgrouting (dove la rete è abbastanza piccola) o osm2po.


1
Esattamente . Questo è anche un altro errore che alcune persone fanno quando elaborano i dati navteq e teleatlas. Sottopassaggi / Cavalcavia sono una sofferenza ma una realtà.
Ragi Yaser Burhum,

1
Essere d'accordo. Benvenuti nel GIS, dove i dati sono sempre più o meno dannosi
simplexio,

3

Riguardo al tuo problema generale, usando pgRouting: penso che @Uffer, @GisStudent e altri che stanno mostrando come usare "OSC & ecc", hanno ragione. Segui gli indizi di "migliori pratiche" e "standard" ...

Informazioni sulla tua domanda: "dividi le strade in singoli segmenti agli incroci" o "come rimuovere tutte le geometrie non divise originali". Posso aiutarti se mostri qui i tuoi risultati qui, passo dopo passo ...

Primo passo: analisi della topologia

 CREATE TABLE split_points_topo as
  SELECT     
    a.gid as gid_a, b.gid  as gid_b, ST_Relation(a.geom, b.geom) as DE9IM_code
  FROM
    roads as a,
    roads as b
  WHERE a.gid != b.gid AND a.geom && b.geom;

 SELECT DISTINCT st_geometryType(geom) FROM roads;
 SELECT DISTINCT DE9IM_code FROM split_points_topo;
 -- list here the results o these two queries!  ... after we can continue.

2

Un'altra "soluzione non reale al tuo problema", ma il nostro convertitore OSM si divide agli incroci mentre converte da OSM a SHP. È più efficiente in questo modo, poiché può confrontare l'ID dei nodi, anziché eseguire calcoli geometrici.


1

Un modo per risolverlo algoritmicamente sarebbe aggiungere il punto iniziale e finale di ogni intera strada all'insieme di "intersezioni", in modo da poter essere certi che ogni segmento si trova tra due intersezioni.

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.