도달 가능한 영역 위에 다각형 만들기


10

나는 현재 isochrones 및 기본 알고리즘 분야에서 일하고 있습니다. 이제 문제를 일으키는 것은 isochrone 자체의 계산이 아니라 결과의 시각화입니다.
내 isochrone 알고리즘의 결과는 점과 가장자리입니다. 실제로 작동하는 솔루션이 있지만 3873 엣지와 1529 노드의 경우 영원히 걸리는 것처럼 보입니다 (2015 Core i7 CPU와 매우 빠른 SSD를 포함하는 Lenovo T440s 랩톱에서 약 2.0 초). 몇 초 대신 msec :-)와 같은 것을 원합니다.

어쩌면 누군가 도달 할 수있는 영역을 시각화하는 다각형을 만드는 데 필요한 계산 시간을 줄이는 데 도움이 될 수 있습니다.

잠깐만 ... 먼저 먼저!
다음은 내가 isochrone의 계산 결과 인 모서리를 시각화 한 것입니다. 이소 크로네 계산 결과 (선 스트링에 존재하는 골격) 이 모서리는 PostGIS 데이터베이스 테이블에 저장되며 간단한 선 스트링입니다.

사용자에게 보여주고 싶은 것은 다음과 같습니다 : 여기에 이미지 설명을 입력하십시오 그림의 가장 남쪽과 동쪽의 연결이 끊어진 부분에 주목하십시오. 이들은 별도의 영역으로 그려야합니다 (따라서 병합은 허용되지 않습니다 :-)).

현재이 쿼리를 사용하고 있습니다 :

SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
    SELECT ST_MakePolygon(ST_ExteriorRing(ST_GeometryN(segments, generate_series(1, ST_NumGeometries(segments))))) AS polygons FROM (
        SELECT ST_Union(ST_Buffer("GEOMETRY", 20, 'quad_segs=2')) AS segments FROM my_edges AS a
    ) AS b
) AS c

나는 이미 몇 가지 실험을했고 많은 문서를 읽었지만 더 나은 해결책을 찾을 수는 없습니다.
내 눈에 가장 큰 문제는 ST_Union의 사용법입니다 (문서에 명시된 바와 같이이 기능이 느릴 수 있습니다). 가장 흥미로운 점은 ST_Collect로 대체하면 ST_Buffer 계산 속도가 느려져 모든 쿼리에서 가장자리 사이의 영역을 채우지 않지만 다음 쿼리는 훨씬 오래 걸립니다. ) :

SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
    SELECT ST_Buffer(ST_Collect(ST_LineMerge("GEOMETRY")), 20, 'quad_segs=2') AS polygons FROM my_edges AS a
) AS b

내 시스템에서 약 3.8 초가 걸리므로 시간이 거의 두 배가 걸립니다. 이 작은 벤치 마크에서 첫 번째 결론은 ST_Buffer가 MultiLineStrings와 관련하여 예기치 않게 느려진다는 것입니다 (각 라인마다 버퍼를 만들고 버퍼를 병합 할 때보 다 느립니다)-내 눈에는 이상합니다)

나는 또한 pgRouting에서 구현을 사용하여 알파 셰이프를 사용하려고 시도했지만 설정할 알파 값이 없기 때문에 (그리고 실제로는 실제로 어떤 값으로 설정하지 않을 것인지) 하나의 큰 다각형을 얻습니다 ( 그래서 나는 남쪽과 동쪽의 지역을 내가 원하는 것이 아닌 별도의 지역으로 잃을 것입니다).
또한 ST_Polygonize (내 생각에 가장 먼저 나온 것)는 사용 가능한 결과를 얻지 못했지만 여기서 뭔가를 놓쳤을 수도 있습니다 ...

PostGIS에 표시된 영역을 만드는 더 좋은 방법이 있습니까? 아마도 자바 코드 (jts) 또는 클라이언트 측 자바 스크립트 코드 (jsts)를 사용하여? 사실 결과에 표시된 영역이 분리되어 있고 계산 속도가 훨씬 빠르면 세부 사항을 잃어 버릴 수 있습니다.


ST_Exteriorring (ST_Dump (ST_Union (ST_Buffer (geom, ....))). geom을 사용하면 버퍼링 된 것이 폴리곤이되고 ST_Union은 모든 교차 지오메트리를 연결하므로 MakePolygon 또는 GeometryN이 필요하지 않습니다. 버퍼 이후 ST_Union에서 발생하는 라인 스트링을 테스트해야 할 수도 있지만 ST_GeometryType (geom)을 사용하면 쉽습니다 .Java 또는 jsts를 사용하는 경우에는 가능하지만 더 빠를 것 같지는 않습니다. Postgis (GEOS) 기능의 대부분은 JTS의 C / C ++ 포트입니다
— John Powell

맞습니다.이 작동하지만 실제로 더 빠르지는 않습니다 (GeometryN을 사용하는 동안 ~ 3.1 초 소요, 2 초 소요). 다음은 내가 사용한 것입니다. SELECT ST_AsGeoJson (ST_Transform (ST_Exteriorring ((ST_Dump (ST_Union (ST_Buffer ( "GEOMETRY", 20))). geom), 4326)) FROM my_edges;
— Nikolaus Krismer

@ john-barça : 오 .. 접근법을 시도 할 때 ST_Buffer에서 quad_segs = 2 부분을 연무합니다. 그러나 이것은 여전히 ​​매우 느립니다 (내 눈에서), 그것을 시도하는 다른 방법이 있습니까?
— Nikolaus Krismer

흥미로운 문제 .... 테스트 데이터를 공유하고 싶습니까?
— dbaston

도움이된다면 일부 데이터를 공유하게되어 기쁩니다. 내가 여기서하는 모든 일은 오픈 소스이므로 큰 문제는 아닙니다. 주의 사항 : 테스트를위한 웹 애플리케이션은 dbis-isochrone.uibk.ac.at:8080/testing에 있습니다. 내가 작업하는 것에 대한 자세한 정보는 dbis-isochrone.uibk.ac.at 에서 찾을 수 있습니다 . 웹 사이트의 "링크"섹션에는 몇 가지 추가 참조 (테스트 데이터 포함)가 있습니다
— Nikolaus Krismer

답변:


5

GeoJSON 직렬화를 제외하고 랩톱에서 다음을 수행하는 데 약 6.3 초가 걸립니다.

SELECT
  ST_MakePolygon(
    ST_ExteriorRing(
      (ST_Dump(
        ST_Union(
          ST_Buffer(geom, 20, 2)))).geom))
FROM bz_edges

OpenJUMP의 데이터를 살펴보면 거리 세그먼트에서 출력의 원하는 세부 수준과 관련하여 상당히 세부적인 부분을 발견했습니다. PostGIS에서 이러한 라인의 즉각적인 단순화조차도 큰 속도 향상을 가져올 수 있습니다.

SELECT
  ST_MakePolygon(
    ST_ExteriorRing(
      (ST_Dump(
        ST_Union(
          ST_Buffer(ST_Simplify(geom, 10), 20, 2)))).geom))
FROM bz_edges

2.3 초로 줄어 듭니다. 일반화 된 형상을 즉석에서 계산하는 대신 별도의 열에 저장하여 더 나은 작업을 수행 할 수 있다고 생각했지만 실제로는 추가 이점이 없습니다.

작성하려는 코드의 양에 따라 여러 코어를 활용할 수 있기 때문에 Java에서 더 잘 할 수 있습니다. JTS는 2.8 초 안에 위 작업을 수행합니다. 한 가지 접근 방식은 CascadedPolygonUnion일부 노조 작업이 동시에 수행되도록 확장 하는 것입니다. (업데이트-여기는 ParallelCascadedPolygonUnion입니다 )

샘플 데이터에서 가장자리가 시작 및 끝 노드에 대한 참조와 함께 저장되어 있음을 알았습니다. 즉, 사전 빌드 그래프가 있습니다. 일반적인 지오메트리 작업을 사용하는 대신 그래프에서 작업하면 이러한 다각형을 훨씬 빠르게 생성 할 수 있습니다 . 예를 들어 다음과 같이 할 수 있다고 생각합니다.

  1. 그래프의 연결된 구성 요소를 식별
  2. 연결된 각 구성 요소에 대해 최소 X 좌표를 가진 노드를 찾으십시오 (구성 요소 외부에 있음).
  3. 구성품의 가장자리를 걷습니다. 가능하면 항상 왼쪽 (또는 오른쪽)으로 돌리십시오. 이렇게하면 각 구성 요소의 외부 링이 제공됩니다.
  4. 외부 링을 다각형 화하고 적절히 버퍼링하십시오.

고마워 ... 단순화는 대단하고 "간단한"개선입니다. 랩톱에서 필요한 시간이 1.5 초로 줄었습니다. 내가 원하는 곳이 아니라 조금 나아졌습니다.
— Nikolaus Krismer

제안 된 해결책에 관하여 (1-4 점). 매우 간단하게 들리며 시도해 볼 가치가 있습니다. 비슷한 것을 생각했지만 point1 (매우 초기 :-)에 붙어 있습니다. 연결된 구성 요소를 식별하는 방법 (내 생각 만 할 수있는 것은 재귀 쿼리 만 매우 느릴 수 있음).
— Nikolaus Krismer

@NikolausKrismer 나는 이와 같은 작업에 JGraphT 와 베틀 을 모두 사용합니다 . 대신 자체 그래프 방법을 작성하면 (최상의 성능에 대한 나쁜 생각은 아님) 깊이 우선 검색을 통해 구성 요소를 찾을 수 있습니다. (당신은 다가오는 PostGIS 2.2에서 그것들을 찾을 수 ST_ClusterIntersecting있지만 어쨌든 데이터베이스 외부에서 어떤 종류의 그래프 처리가 일어나기를 원할 것이므로 아마도 유용하지 않을 것입니다).
— dbaston

이것들은 좋은 힌트입니다. JGraphT를 살펴본 결과 확실히 내 문제를 해결하는 데 도움이 될 수 있습니다. 그러나 Postgis 2.2와 ST_ClusterIntersecting 함수-> 위의 경우 다른 클러스터를 식별하는 데 약 200-250msec가 소요됩니다. 그것은 나에게 괜찮습니다 (JGraphT는 확실히 더 잘 할 수 있습니다). 지금은 exteriorRing 작성을 처리해야합니다 (ST_MakePolygon에서 내 링크는 쉘이 없기 때문에 ST_ExteriorRing이 실패 함)
— Nikolaus Krismer

두 가지 합병증이 있습니다. (a) 외부 링뿐만 아니라 해당 링에서 바깥쪽으로 연장되는 세그먼트도 필요합니다. (b) 선이 실제로 일부 교차점에서 교차하지 않는 것처럼 보입니다. 그래프 보행 결과에서 지오메트리를 구성하려는 경우 (b)를 수정해야합니다.
— dbaston
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.