Jak podzielić drogi OSM na poszczególne segmenty na skrzyżowaniach?

10

Chcę utworzyć sieć drogową do użytku z pgRouting przy użyciu danych OpenStreetMap. Załadowałem plik kształtu z GeoFabrik do tabeli Postgres (z włączonym PostGIS). Jednak jednym z moich problemów było to, że drogi nie zawsze kończą się na skrzyżowaniach, dlatego postanowiłem je wszystkie podzielić na każdym skrzyżowaniu lub skrzyżowaniu.

Aby zidentyfikować wszystkie skrzyżowania, w których drogi przecinały się lub przecinały, użyłem następującego SQL(podobnego do poprzedniego pytania):

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);

Chcę teraz podzielić drogi za pomocą tych punktów. Zastosowałem następujące podejście:

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);

Problem z tym podejściem dzielonym polega na tym, że oprócz wszystkich podzielonych elementów pozostaje pełna długość drogi. Aby usunąć te nierozdzielone geometrie drogi, które zostały uwzględnione, użyłem ST_Equals()funkcji do ich zidentyfikowania i usunięcia:

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

Jednak to podejście nie usuwa wszystkich oryginalnych nieoświetlonych geometrii (chociaż usuwa niektóre z nich). Czy istnieje lepsze podejście do usuwania (lub ogólnie), aby mieć tylko podzielone geometrie w tabeli?

djq
źródło
Zgodnie z dokumentacją ST_Split nie zwraca oryginalnej, nieoświetlonej geometrii. Co to za dodatkowy „.geom” wychodzący przy ostatnim zamykającym nawiasie w pierwszym wierszu instrukcji SELECT? Może to być tak proste, jak usunięcie tego.
Scro,
@ Scro, o którym .geommówisz? Nie mogę tego zauważyć!
djq
Chyba technicznie byłby to drugi wiersz instrukcji SELECT. Mam również na myśli tworzenie tabeli „split_roads”. To linia, która kończy się na „))). Geom) as geom”.
Scro,
hmm, kiedy to robię, pojawia się błąd. 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
Czy cała linia wyglądała tak: ST_GeomFromEWKB ((ST_Dump (ST_Split (g.geom, blade.geom)))) As geom,
Scro

Odpowiedzi:

6

Nie jest to prawdziwe rozwiązanie twojego problemu, ale spróbuj osm2po ... tworzy idealny kod SQL do routingu w pgrouting: http://osm2po.de/

GIS Student
źródło
Dzieki za sugestie. Próbowałem, osm2pgroutingale wymaga więcej pamięci niż mój serwer i kończy się bez ukończenia.
djq
2
@djq osm2po może obsługiwać znacznie większe pliki niż osm2pgrouting. Może nawet ładować planetę. Kosmos
podmrok
ah, początkowo myślałem, że osm2poto literówka. Czy instalacja Ubuntu jest prosta?
djq
Jest to gotowy skompilowany plik JAR (java). Po prostu uruchom go, jak wyjaśniono na stronie internetowej.
GIS Student
11

Prosta odpowiedź: nie. Nie powinieneś tego robić w ten sposób.

Z plików kształtów dróg OSM nie można rozróżnić skrzyżowań i przejazdów / przejazdów podziemnych. Utworzysz skrzyżowania, które w rzeczywistości nie istnieją, jeśli podzielisz wszystkie pozornie przecinające się drogi.

Musisz zabrudzić sobie ręce oryginalnym plikiem OSM, jeśli nie chcesz używać istniejących narzędzi, takich jak osm2pgrouting (gdzie sieć jest wystarczająco mała) lub osm2po.

podmrok
źródło
1
Dokładnie . Jest to także kolejny błąd, który popełniają niektórzy ludzie, przetwarzając dane navteq i teleatlas. Przejścia podziemne / wiadukty to ból, ale rzeczywistość.
Ragi Yaser Burhum
1
Zgodzić się. Witamy w GIS, gdzie dane są zawsze mniej lub bardziej złe
simplexio,
3

O twoim ogólnym problemie z użyciem pgRouting: Myślę, że @Uffer, @GisStudent i inni, którzy pokazują, jak używać „OSC i tym podobnych”, mają rację. Postępuj zgodnie ze wskazówkami „najlepszych praktyk” i „standardów” ...

O twoim pytaniu: „podziel drogi na poszczególne segmenty na skrzyżowaniach” lub „jak usunąć wszystkie oryginalne nieoświetlone geometrie”. Mogę pomóc, jeśli pokażesz tutaj swoje wyniki, krok po kroku ...

Pierwszy krok: analiza topologii

 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.
Peter Krauss
źródło
2

Kolejne „nierealne rozwiązanie twojego problemu”, ale nasz konwerter OSM dzieli się na skrzyżowaniach podczas konwersji OSM na SHP. Jest w ten sposób bardziej wydajny, ponieważ może porównywać identyfikatory węzłów, zamiast wykonywać obliczenia geometryczne.

Uffe Kousgaard
źródło
1

Jednym ze sposobów rozwiązania tego algorytmu byłoby dodanie punktu początkowego i końcowego każdej całej drogi do zestawu „skrzyżowań”, aby mieć pewność, że każdy odcinek znajduje się między dwoma skrzyżowaniami.

relet
źródło