교차로에서 OSM 도로를 개별 세그먼트로 나누는 방법은 무엇입니까?


10

OpenStreetMap 데이터를 사용하여 pgRouting과 함께 사용할 도로 네트워크를 만들고 싶습니다. GeoFabrik의 shapefile을 Postgres 테이블로로드했습니다 (PostGIS가 활성화 된 상태). 그러나 내가 가진 문제 중 하나는 도로가 항상 교차로에서 끝나는 것은 아니기 때문에 모든 교차로 나 교차로에서 도로를 모두 분할하기로 결정했습니다.

도로가 교차하거나 교차 한 모든 교차점을 식별하기 위해 다음을 사용했습니다 SQL( 이전 질문 과 유사 ).

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

이제이 지점을 사용하여 도로를 분할하고 싶습니다. 나는 다음과 같은 접근법을 사용했다.

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

이 분할 방식의 문제점은 모든 분할 부분에 추가로 전체 도로 길이가 남아 있다는 것입니다. 포함 된이 분리되지 않은 도로 형상을 제거하기 위해이 ST_Equals()기능을 사용하여 이를 식별하고 삭제했습니다.

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

그러나이 방법은 분리되지 않은 원래 형상을 모두 제거하지는 않습니다 (일부는 분리하지만). 테이블에 분할 된 형상 만 갖도록 삭제 (또는 전체)에 대한 더 나은 접근 방법이 있습니까?


설명서에 따르면 ST_Split은 분리되지 않은 원래 형상을 반환하지 않습니다. SELECT 문 첫 줄의 마지막 닫는 괄호에서 추가 '.geom'이 무엇입니까? 그것을 제거하는 것만 큼 간단 할 수 있습니다.
Scro

@Scro .geom당신이 말하는 것은 무엇입니까? 그것을 찾을 수 없습니다!
djq

기술적으로 SELECT 문의 두 번째 줄이 될 것 같습니다. 또한 "split_roads"테이블 생성을 참조하고 있습니다. '))). geom)으로 끝나는 줄입니다.
Scro

흠, 내가 할 때 오류가 발생합니다. 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

ST_GeomFromEWKB ((ST_Dump (ST_Split (g.geom, blade.geom))))
Geom으로

답변:


6

귀하의 문제에 대한 진정한 해결책은 아니지만 osm2po를 사용해보십시오 ... pgrouting에서 라우팅을위한 완벽한 SQL 코드를 만듭니다 : http://osm2po.de/


제안 해 주셔서 감사합니다. 시도 osm2pgrouting했지만 서버보다 많은 메모리가 필요하며 완료하지 않고 종료됩니다.
djq

2
@djq osm2po는 osm2pgrouting보다 훨씬 큰 파일을 처리 할 수 ​​있습니다. 심지어 planet.osm로드 할 수 있습니다
언더 다크

아, 나는 원래 osm2po오타 라고 생각했다 . 우분투에 설치하는 것이 간단합니까?
djq

준비된 컴파일 된 JAR 파일 (java)입니다. 웹 사이트에 설명 된대로 실행하십시오.
GIS 학생

11

간단한 대답 :하지 마십시오. 그렇게하지 말아야합니다.

OSM 도로 쉐이프 파일에서 교차로와 고가도로를 구분하는 것은 불가능합니다. 겉보기에 교차하는 모든 도로를 쪼개면 실제로 존재하지 않는 교차로를 만들 수 있습니다.

osm2pgrouting (네트워크가 충분히 작은 경우) 또는 osm2po와 같은 기존 도구를 사용하지 않으려면 원본 OSM 파일을 사용하여 손을 더럽게해야합니다.


1
그렇습니다 . 이것은 일부 사람들이 navteq 및 teleatlas 데이터를 처리 할 때하는 또 다른 실수입니다. 지하도 / 고가도로는 고통이지만 현실입니다.
Ragi Yaser Burhum

1
동의하다. 데이터가 어느 정도 나쁜지 GIS에 오신 것을 환영합니다
simplexio

3

일반적인 문제에 대해 pgRouting 사용 : @Uffer, @GisStudent 및 "OSC 등"을 사용하는 방법을 보여주는 다른 사람들이 맞다고 생각합니다. "모범 사례"및 "표준"의 힌트를 따르십시오 ...

질문 : "교차로에서 개별 구간으로 도로를 분할"또는 "원래의 분리되지 않은 형상을 모두 제거하는 방법". 여기에 결과를 단계별로 표시하면 도움이 될 수 있습니다 ...

첫 번째 단계 : 토폴로지 분석

 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

또 다른 "문제에 대한 실질적인 해결책은 아니지만" OSM 변환기 는 교차점에서 분할되어 OSM에서 SHP로 변환됩니다. 기하학적 계산을 수행하는 대신 노드의 ID를 비교할 수 있기 때문에 더 효율적입니다.


1

알고리즘 적으로 해결하는 한 가지 방법은 각 도로의 시작점과 끝점을 "교차점"세트에 추가하여 모든 세그먼트가 두 교차점 사이에 있는지 확인할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.