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


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.