다각형 Shapefile로 점 CSV를 공간적으로 결합하는 가장 빠른 방법


19

10 억 포인트 CSV 파일과 약 5,000 개의 다각형이있는 shapefile이 있습니다. 점과 다각형을 공간적으로 결합하는 가장 빠른 방법은 무엇입니까? 각 포인트마다 포함하는 다각형 ID를 가져와야합니다. (다각형은 겹치지 않습니다.)

일반적으로 두 데이터 세트를 PostGIS에로드합니다. 작업을 더 빠르게 수행 할 수있는 방법이 있습니까?

오픈 소스 솔루션을 찾고 있습니다.

답변:


16

"빠른"의 양이 포함되어있는 경우 귀하 소요되는 시간을,이 솔루션은 당신이 편안 어떤 소프트웨어에 따라 달라집니다 및 신속하게 사용할 수 있습니다. 결과적으로 다음 설명은 가능한 가장 빠른 컴퓨팅 시간 을 달성하기위한 아이디어에 중점을 둡니다 .

미리 준비된 프로그램을 사용하는 경우 폴리곤을 사전 처리하여 KD 트리 또는 쿼드 트리와 같은 폴리 인 포인트 데이터 구조를 설정하여 성능이 일반적으로 O (log (V ( ) * (N + V)) 여기서 V는 다각형의 총 꼭짓점 수이고 N은 점 수입니다. 데이터 구조는 최소한 O (log (V) * V)의 노력이 필요하므로 포인트 당 비용 O (log (V))로 각 포인트에 대해 프로브해야합니다.

겹침이 없다는 가정을 이용하여 다각형을 먼저 격자로 표시하여 실질적으로 더 나은 작업을 수행 할 수 있습니다. 각 격자 셀은 다각형 내부 ( "범용 다각형"의 내부 포함)에 완전히 들어 있습니다.이 경우 다각형의 id로 셀에 레이블을 지정하거나 하나 이상의 다각형 모서리를 포함합니다. 모든 모서리를 래스터 화하는 동안 참조 된 그리드 셀의 수와 동일한이 래스터 화 비용은 O (V / c)이며 여기서 c는 셀의 크기이지만 big-O 표기법의 암시 적 상수는 작습니다.

(이 방법의 한 가지 장점은 표준 그래픽 루틴을 활용할 수 있다는 것입니다. 예를 들어 (a) (b) 각 다각형에 대해 고유 한 색상을 사용하여 가상 화면에 다각형을 그리고 (c) 해결하려는 모든 픽셀의 색상을 읽을 수 있습니다.)

이 그리드를 사용하여 각 포인트를 포함하는 셀을 계산하여 포인트를 사전 검열합니다 (몇 개의 클럭 만 필요한 O (1) 연산). 점이 다각형 경계 주위에 모여 있지 않으면 일반적으로 약 O (c) 점만 남게되므로 모호한 결과가 나타납니다. 따라서 그리드를 구축하고 사전 심사하는 데 드는 총 비용은 O (V / c + 1 / c ^ 2) + O (N)입니다. O (log (V) * N * c)의 비용으로 나머지 점 (다각형 경계에 가까운 점)을 처리하려면 다른 방법 (예 : 지금까지 권장 된 방법)을 사용해야합니다. .

c가 작아짐에 따라 에지가있는 동일한 그리드 셀에 점점 더 적은 점이 생길 수 있으므로 후속 O (log (V)) 처리가 더 적게 필요합니다. 이에 대항하여 행동하려면 O (1 / c ^ 2) 그리드 셀을 저장하고 다각형을 래스터 화하는 데 O (V / c + 1 / c ^ 2) 시간을 소비해야합니다. 그러므로 최적의 격자 크기가있을 것입니다. c. 이를 사용하여 총 계산 비용은 O (log (V) * N)이지만 암시 적 상수는 일반적 으로 사전 심사의 O (N) 속도로 인해 미리 준비된 절차를 사용하는 보다 훨씬 작습니다.

20 년 전에 나는이 접근법을 테스트했으며 (영국과 근해 전체에 균일 한 간격을두고, 비디오 버퍼가 제공하는 약 400K 셀의 상대적으로 조잡한 그리드를 활용), 내가 할 수있는 최고의 공개 알고리즘에 비해 2 배 빠른 속도를 얻었습니다. 찾기. 다각형이 작고 단순 할 때 (삼각형과 같은)에도 사실상 속도가 크게 향상됩니다.

내 경험상 계산이 너무 빨라서 전체 작업이 CPU가 아닌 데이터 I / O 속도에 의해 제한되었습니다. I / O가 병목 현상을 일으킬 것으로 예상하면 데이터 읽기 시간을 최소화하기 위해 포인트를 가능한 한 압축 형식으로 저장하여 가장 빠른 결과를 얻을 수 있습니다. 또한 디스크 쓰기를 제한 할 수 있도록 결과를 저장하는 방법을 고려해야합니다.


6
솔루션과 컴퓨팅 시간을 실현하는 데 소요되는 시간이 아주 좋습니다. 최적의 솔루션에 도달하는 데 오랜 시간이 걸리는 것은 최적화를 통해 비용을 절감 할 수있는 경우에만 유용합니다 (예 : 고용주의 관점에서).
Sasa Ivetic

5

필자의 경우 CSV 데이터를 shp 파일에 로드 한 다음 shapefile을 사용하여 python 스크립트를 작성 하고 shapely 를 포함하여 다각형 ID를 가져와 필드 값을 업데이트합니다.

geotools와 JTS가 shapefile / shapely보다 빠른지 모르겠습니다 ... 테스트 할 시간이 없습니다!

편집 : 그런데 shapefile 형식으로 csv 변환은 ​​필요하지 않을 것입니다. 폴리곤 shapefile에서 공간 객체로 값을 테스트하기 위해 값을 쉽게 형식화 할 수 있기 때문입니다.


4
CSV 리더를 사용하여 데이터를 직접로드하고 Rtree 공간 인덱스를 웁니다 . Rtree와 Shapely의 조합은 인상적인 성능을 제공합니다 (PostGIS보다 훨씬 낫습니다. Java를 모르기 때문에 JTS와 비교할 수 없습니다).
Mike T

2
1b 포인트를 모두 메모리에 한 번에 저장할 필요가없는 것이 좋습니다. 포인트 당 최소 16 바이트 (X / Y)에서 16GB의 데이터를보고 있습니다. Rtree가 로컬 스토리지에서 인덱스를 빌드하면 성능이 확실히 향상됩니다. 1b 포인트를 단일 쉐이프 파일로 가져 오기도 작동하지 않습니다. OGR 사양 상태 shapefile은 8GB (4GB 권장)로 제한됩니다. 단일 점 모양은 20 바이트를 사용합니다.
Sasa Ivetic

4

결국 다각형을 래스터로 변환하고 점 위치에서 샘플링했습니다. 내 다각형이 겹치지 않고 높은 정확도가 필요하지 않았기 때문에 (다각형은 토지 사용 클래스를 나타내고 그 경계는 다소 불확실한 것으로 간주되었습니다) 이것이 내가 얻을 수있는 가장 시간 효율적인 솔루션이었습니다.



3

Spatialite를 사용하십시오 .

GUI를 다운로드하십시오. Shapefile과 CSV를 모두 가상 테이블로 열 수 있습니다. 즉, 실제로 데이터베이스로 가져 오지 않지만 테이블로 표시되므로 원하는 방식으로 빠르게 조인하고 쿼리 할 수 ​​있습니다.


3

C / C ++ / Python에서 OGR을 사용하여 상당히 빠르게 수행 할 수 있습니다 (Python은 3 중 가장 느립니다). 모든 다각형을 반복하고 점에 필터를 설정하고 필터링 된 점을 반복하면 반복하는 각 점이 현재 다각형에 속한다는 것을 알 수 있습니다. 다음은 다각형을 반복하고 그에 따라 점을 필터링하는 OGR을 사용하는 Python의 샘플 코드입니다. C / C ++ 코드는 이것과 매우 비슷하게 보일 것입니다. 파이썬에 비해 속도가 크게 향상 될 것입니다. CSV를 업데이트하려면 몇 줄의 코드를 추가해야합니다.

from osgeo import ogr
from osgeo.gdalconst import *

inPolyDS = ogr.Open("winnipeg.shp", GA_ReadOnly)
inPolyLayer = inPolyDS.GetLayer(0)
inPointDS = ogr.Open("busstops.vrt", GA_ReadOnly)   
inPointLayer = inPointDS.GetLayerByName("busstops")

inPolyFeat = inPolyLayer.GetNextFeature()
while inPolyFeat is not None:
  inPtFeat = inPointLayer.GetNextFeature()
  while inPtFeat is not None:
    ptGeom = inPtFeat.GetGeometryRef()
    # Do work here...

    inPtFeat = inPointLayer.GetNextFeature()

  inPolyFeat = inPolyLayer.GetNextFeature()

VRT 파일 (busstops.vrt) :

<OGRVRTDataSource>
  <OGRVRTLayer name="busstops">
    <SrcDataSource>busstops.csv</SrcDataSource>
    <GeometryType>wkbPoint</GeometryType>
    <LayerSRS>WGS84</LayerSRS>
    <GeometryField encoding="PointFromColumns" x="X" y="Y" reportSrcColumn="FALSE" />
  </OGRVRTLayer>
</OGRVRTDataSource>

CSV 파일 (busstops.csv) :

FID,X,Y,stop_name
1,-97.1394781371062,49.8712241633646,Southbound Osborne at Mulvey

CSVT 파일 (busstops.csvt, OGR은 열 유형을 식별해야하며, 그렇지 않으면 공간 필터를 수행하지 않습니다) :

Integer,Real,Real,String

2
10 억 포인트를 5000 번 반복하지 않습니까 (각 다각형마다 한 번씩)?
underdark

공간 인덱스는 절대 필수 입니다. 내가 언급 RTREE 전을, 내가 다시 말할거야!
Mike T

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