QGIS에서 가장 가까운 이웃 그룹 선택


14

qgis로 가져온 위도 / 경도 형식의 100,000 포인트가 넘는 목록이 있습니다.

자, 여기서하려고하는 것은이 모든 포인트를 박스 그룹으로 그룹화하는 것이며, 기본적으로 맵을 경계 박스로 분할하고 싶다는 의미입니다.

내 요구 사항은 다음과 같습니다.

  • 박스형 그룹에는 100 점 미만, 200 점 이상은 없어야합니다.
  • 둘 이상의 그룹에 지점이 없어야합니다
  • 모든 포인트는 가장 가까운 이웃을 기준으로해야합니다

qgis를 통해 어떻게 이것을 달성 할 수 있습니까?

사용자 정의 쿼리 코드를 전달하고 shapefile로 작성된 결과 또는 상자를 저장할 수 있다고 가정합니다. 누군가 어떻게 이것이 가능하고 코드가 어떻게 생겼는지 설명해 주시겠습니까?

언급 한 바와 같이, 나의 목표는 각 박스 내에 100 개 이상의 속성과 200 이하의 정사각형 파일 박스를 shapefile 레이어로 표시하는 것입니다.


6
이 질문에 "즐겨 찾기"라고 표시 한 모든 사람에게 : 왜 그렇게 찬성하지 않습니까? 가장 좋아하는 질문은 좋은 질문이라고 생각할 것입니다.
underdark

1
왜 권투가 필요합니까? 개수를 기준으로 상자를 만들면 어쨌든 크기가 다르므로 바둑판 식 배열은 문제가되지 않습니다. 다각형으로 그룹화하는 것이 더 쉽습니다 (예 : 볼록 껍질).
diciu

@diciu 응답 주셔서 감사합니다. 네, 나중에 볼록 껍질이 상자로 바뀔 수 있기 때문에 볼록 껍질이 좋을 것 같습니다. 볼록 껍질 방식을 사용하려면 어떤 코드를 사용해야합니까?
NetConstructor.com

2
볼록 껍질을 사용하는 경우 경계 상자 (선체 포함)가 겹쳐지고 단일 BBOX에있는 점에 대한 요구 사항이 더 이상 충족되지 않습니다. 볼록 껍질은 BBOX를 향한 중간 단계가 아니라 대체품으로 사용됩니다. 그럼에도 불구하고 일반적인 솔루션을 만드는 것이 다소 복잡 할 것입니다.
diciu

답변:


13

(a) 포인트 세트의 가장 동쪽 절반과 (b) 포인트 세트의 최 북쪽 절반을 요청하는 방법을 알아 냈다고 가정하면 거기에 갈 수 있습니다. 이것들로부터, 물론, (c) 가장 서쪽의 절반 또는 (d) 가장 남쪽의 절반을 쉽게 얻을 수 있습니다. (QGIS는 모르지만 일반적으로 (a)를 수행하는 한 가지 방법은 중간 x 좌표를 요청한 다음 x 좌표가이를 초과하는 모든 포인트를 가져 오는 것입니다. (b)-(d)에 대한 솔루션은 유사합니다 .)

이 기능을 사용하면 쉬운 재귀로 솔루션을 얻을 수 있습니다. 이를 설명하기 위해, Half앞의 연산을 구현 하는 프로 시저가 있다고 가정 해 봅시다 . 앞의 연산은 두 개의 인수를 취합니다. 첫 번째는 포인트 세트이고 두 번째는 true동서 파티셔닝이 필요한 경우와 같고 false그렇지 않으면 같은 코드 입니다. 요청에 따라 파티션을 분할하는 입력의 두 서브 세트를 리턴합니다.

Procedure Box(P: set of points, i: boolean, n: integer)
Begin
    If (Count(P) > 2*n) then
        {R,S} = Half(P,i)
        Q = Box(R,!i,n) + Box(S,!i,n)
    Else
        Q = {P}
    Endif
    Return Q
End

이 의사 코드에서, R 및 S 파티션 P; Box (R,! i, n)은 직교 방향으로 R의 구획이고 , Box (S,! i, n)은 직교 방향으로의 S의 구획이며, "+"는 집합 이론적 결합을 형성하고, {}는 세트를 지정합니다. (분할 방향을 바꾸면 스트립 대신 상자가 만들어집니다.) 매개 변수 n 은 파티션에서 그룹의 최소 크기를 지정합니다. 최대 크기는 2 n 입니다.

예

여기서, 예시로서, Box(P,true,100)100에서 200 사이의 그룹으로 분할 된 12,891 개의 랜덤 포인트의 세트 P가있다 . 이 알고리즘은 128 개의 상자 중 37 개의 상자에 100 개의 점이 있고 91 개의 상자에 101 개의 점이있는 128 개의 상자를 만듭니다.


2
알고리즘이 효율적입니다. 단일 코어에서 실행되어 18 초 동안 10 배 많은 포인트 (128,910)를 처리했습니다. n 포인트에 대해 O (n log (n) log (n))로 스케일됩니다. (log (n)의 이러한 요소 중 하나를 제거하는 것이 개선 될 수 있지만 그 노력은 가치가 없을 것 같습니다.)
whuber

1
@W 점 좌표의 분할을 용이하게하기 위해 사전 식 정렬을 사용 했습니까?

2
@ whuber 이것은 대단합니다
dassouki

1
@Dan 어휘 정렬은 도움이되지만 필요하지는 않습니다. n 값의 중앙값은 O (n) 시간 (O (n log (n)) 시간이 아님)에서 찾을 수 있으므로 점을 동서 절반 또는 남북 절반으로 분할하는 것은 무증상 O (n ) 계산.
whuber
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.