PostGIS를 사용하여 가장 가까운 이웃 계산 최적화


13

PostGIS를 사용하여 가장 가까운 다각형 이웃을 계산하고 있습니다. 내가 계산하고 싶은 것은 각 다각형에서 가장 가까운 다각형까지의 최소 거리입니다.

지금까지 나는 Mike Toews의 대답 (작은 변화로 인용) 에서 큰 도움을 얻었습니다 .

SELECT 
  a.hgt AS a_hgt,
  b.hgt AS b_hgt,
  ST_Distance(a.the_geom, b.the_geom) AS distance_between_a_and_b
FROM 
  public."TestArea" AS a, public."TestArea" AS b
WHERE
  a.hgt !=  b.hgt AND ST_Distance(a.the_geom, b.the_geom) < 400

그런 다음 최소값을 계산했습니다.

SELECT a_hgt, MIN(distance_between_a_and_b)
FROM public."lon_TestArea"
GROUP BY a_hgt

그러나 내 도전은 많은 수의 다각형 (1,000,000)에 대해 이것을 계산하는 것입니다. 위의 계산에서 각 다각형을 다른 다각형과 비교할 때 10 ^ 12 계산을 수행 할 필요가 없도록 계산을 개선 할 수있는 방법이 궁금했습니다.

한 가지 생각은 각 다각형을 버퍼링 한 다음 해당 다각형에 대한 버퍼 내의 모든 값의 가장 가까운 이웃을 계산하고 최소값을 기록하는 것이라고 생각했습니다. 이것이 최선의 방법인지 또는 PostGIS에 사용해야하는 기능이 있는지 확실하지 않습니다.


편집 : Nicklas의 제안 중 하나를 사용하여 실험하고 있습니다 ST_Dwithin().

CREATE TABLE mytable_withinRange AS SELECT 
  a.hgt AS a_hgt,
  b.hgt AS b_hgt,
  ST_DWithin(a.the_geom, b.the_geom, 400)
FROM 
  public."lon_TestArea" AS a, public."lon_TestArea" AS b

여기에 이미지 설명을 입력하십시오

각 다각형의 ID와 특정 거리 내에 있는지 여부에 대한 표를 반환합니다. IF/ELSESQL을 사용하여 형식 문 을 구성 할 수 있습니까? ( CASE조건 사용에 대해 읽었습니다. ) 또는 생성 한 테이블을 원래 테이블에 조인 한 다음 ST_Distance를 사용하여 쿼리를 다시 실행해야합니까?


내 대답에서 보스턴 gis 링크의 두 번째 예를 살펴보십시오. 쿼리의 where 부분에 st_dwithin을 사용해야합니다.
Nicklas Avén

답변:


7

BostonGIS 페이지에"가장 가까운 이웃"섹션이 있습니다.


편집하다:

어때요?

CREATE TABLE mytable_withinRange AS SELECT 
 a.hgt AS a_hgt,
 b.hgt AS b_hgt
FROM 
 public."lon_TestArea" AS a, public."lon_TestArea" AS b
WHERE 
 ST_DWithin(a.the_geom, b.the_geom, 400)

CASE 진술에 관하여 :

SELECT a,
   CASE WHEN a=1 THEN 'one'
        WHEN a=2 THEN 'two'
        ELSE 'other'
   END
FROM test;

WHERE ST_DWithin(a.the_geom, b.the_geom, 400)이 거리 400를 계산하거나 기록하는 것 보다 더 큰 거리를 막을 수 있는지 알고 있습니까? 또한 사례 계산을 수치 계산에 사용할 수 있습니까? 예를 들어 :CASE WHEN ST_DWithin(a.the_geom, b.the_geom, 400) == TRUE THEN ST_DWithin(a.the_geom, b.the_geom)
djq

1
@celenius 거리가 400m를 초과하면 선택 부분에서 아무것도 계산되지 않습니다. 왜 당신이 믹스에 케이스를 넣고 싶어하는지 모르겠습니다.
Nicklas Avén

@ Niklas ok-이해합니다. 400 개 미만의 거리 만 저장되었다는 의미 일 수 있습니다. 이것은 내가보다 훨씬 쉽게 만듭니다. 감사!
djq

3

어이

더 빨리 움직이기 위해 고려해야 할 사항과 향후 가능할 수있는 사항이 있습니다.

먼저 , 모든 조합을 계산하지 않기 위해 버퍼를 사용하여 최소 범위의 다각형을 찾는 것을 고려하고 있다고 언급했습니다.

Boston gis 의 다른 링크에서 논의했듯이 PostGIS에서 올바른 방법은 ST_Dwithin을 사용하는 입니다. ST_Dwithin은 색인을 사용하여 특정 범위의 이웃을 찾습니다.

모든 다각형에 st_DWithin에 고정 값을 사용하기에 충분하거나 어두운 부분이나 거친 지능과 같은 것을 수행 해야하는 경우 물론 데이터 세트에 따라 다릅니다.

두 번째 는 PostGIS 1.5 이상을 사용하는 입니다. 경계 상자가 교차하지 않으면 다각형 대 다각형 계산이 1.5보다 훨씬 빠르기 때문입니다. 자세한 내용은 여기참조하십시오. .

세 번째 로 언급 할 것은 미래입니다.

PostgreSQL 9.1에는 knn-gist라는 것이 있습니다. 인덱스는 예 또는 아니요로 응답 할 수있을뿐만 아니라 인덱스에서 직접 정렬 된 결과를 반환합니다. 여기에서 그것에 대해 읽을 수 있습니다 .

그러나 knn 요지가 이와 같은 일을 돕기 전에 PostGIS 측에서 할 일이 여전히 많이 있습니다. 여기에 대한 티켓이 있습니다.

문안 인사

니클라스


제안 Nicklas에 감사드립니다; pgAdmin / PostGIS를 시작하고 실행하는 것이 까다로운 것으로 나타 났으므로 현재 1.5를 사용하지 않는 것이 좋습니다. ST_Dwithin ()이 이것을 해결하는 방법 인 것 같습니다.
djq

2
1.5를 설치해도 postgresql과 pgadmin의 관계에는 영향을 미치지 않습니다. 데이터베이스 서버에 둘 이상의 버전의 postgi가있을 수 있으며 그 중 하나를 데이터베이스에로드 할 수 있습니다. 1.4 및 1.5 데이터베이스 하나를 동일한 데이터베이스 서버로 만들 수 있습니다.
Nicklas Avén

1

Nathan Kerr의 마스터 작업과 관련된 다음 페이지는이 직접적인 문제에 대한 통찰력을 제공합니다. 내 동료는 Bostongis 방법을 시도 여기여기에 있지만, 작업 오른쪽으로 점점 몇 가지 문제가 있었다.

버퍼와 유사하다고 생각하는 또 다른 접근법은 확장 / 축소 사각형을 수행하는 것입니다. 기본적으로 1을 통과하면 경계 상자 (원래 다각형의 bbox와 직선 + x 단위)가 교차하여 적어도 하나의 교차를 잡을 것이라고 생각합니다. 교차가있는 데이터의 경우 가장 일치하는 항목을 테스트하는 하위 쿼리를 수행하십시오. 데이터가 일치하지 않으면 경계 상자를 확장하고 반복하십시오.

분명히 재귀 프로그래밍 문제이며 Postgis에서 Shapely를 100 % 이상 사용하여 Python에서 더 잘 수행 할 수 있습니다.

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