대규모 GeoJson 파일을 PostGIS에로드하기위한 ogr2ogr의 대안


24

PostGIS 데이터베이스에로드하려는 7GB GeoJson 파일이 있습니다. ogr2ogr을 사용해 보았지만 파일이 너무 커서 ogr2ogr이 메모리에로드 한 다음 처리 할 수 ​​없기 때문에 실패합니다.

이 geojson 파일을 PostGIS에로드하기위한 다른 대안이 있습니까?

내가 얻는 ogr2ogr 오류는 다음과 같습니다.

오류 2 : CPLMalloc () : -611145182 바이트를 할당하는 메모리가 부족합니다. 이 응용 프로그램은 런타임을 비정상적인 방식으로 종료하도록 요청했습니다. 자세한 내용은 응용 프로그램 지원 팀에 문의하십시오.


1
"-gt"옵션을 사용해 보셨습니까? 기본적으로 트랜잭션 당 200 개의 기능을 그룹화합니다.
Pablo

나는 -gt 옵션을 알지 못했고 전에 시도하지 않았다. 방금 -gt 옵션을 사용하여 다시 실행을 시도했지만 불행히도 같은 오류가 발생했습니다. 또한 검색 가능한 옵션의 수를 제한하기 위해 -WHERE 옵션을 사용하려고 시도했지만 도움이되지 않는 것 같습니다.
RyanDalton

GDAL / OGR은 2.3.0에서 대용량 GeoJSON 파일의 읽기를 향상시켜 메모리 오버 헤드를 크게 줄였습니다.
AndrewHarvey

답변:


10

보낸 샘플은 notepad ++와 같은 편집기를 사용하여 파일을 수동으로 분할 할 수 있음을 보여줍니다.

1) 각 청크마다 헤더를 만듭니다.

{"type":"FeatureCollection","features":[

2) 헤더 장소 후 많은 기능 :

{"geometry": {"type": "Point", "coordinates": [-103.422819, 20.686477]}, "type": "Feature", "id": "SG_3TspYXmaZcMIB8GxzXcayF_20.686477_-103.422819@1308163237", "properties": {"website": "http://www.buongiorno.com", "city": "M\u00e9xico D.F. ", "name": "Buongiorno", "tags": ["mobile", "vas", "community", "social-networking", "connected-devices", "android", "tablets", "smartphones"], "country": "MX", "classifiers": [{"category": "Professional", "type": "Services", "subcategory": "Computer Services"}], "href": "http://api.simplegeo.com/1.0/features/SG_3TspYXmaZcMIB8GxzXcayF_20.686477_-103.422819@1308163237.json", "address": "Le\u00f3n Tolstoi #18 PH Col. Anzures", "owner": "simplegeo", "postcode": "11590"}},

3) 청크로 마무리합니다 :

]}

편집-다음은 정의 된 크기의 조각 (기능 수)으로 파일을 분할하는 파이썬 코드입니다.

import sys

class JsonFile(object):
    def __init__(self,file):
        self.file = open(file, 'r') 
    def split(self,csize):
        header=self.file.readline()
        number=0
        while True:
            output=open("chunk %s.geojson" %(number),'w')
            output.write(header)
            number+=1
            feature=self.file.readline()
            if feature==']}':
                break
            else:
                for i in range(csize):
                    output.write(feature)
                    feature=self.file.readline()
                    if feature==']}':
                        output.write("]}")
                        output.close()
                        sys.exit("Done!")
                output.write("]}")
                output.close()

if __name__=="__main__":
    myfile = JsonFile('places_mx.geojson')
    myfile.split(2000) #size of the chunks.

19

불행히도 JSON은 XML과 마찬가지로 스트림 처리에 적합하지 않으므로 거의 모든 구현에서는 전체 데이터 세트를 메모리에로드해야합니다. 귀하의 경우 작은 세트에 대해서는 괜찮지 만 데이터 세트를 더 작고 관리 가능한 덩어리로 나누는 것 외에 다른 옵션은 없습니다.

Pablo의 솔루션을 개선하기 위해 실제로 파일을 편집기로 열고로드하지 않아도되고 직접 분할 할 필요는 없지만 가능한 한 전체 프로세스를 자동화하려고 시도하는 솔루션이 있습니다.

json 파일을 Unix 호스트 (linux, osx)에 복사하거나 Windows에 cygwin 도구를 설치하십시오. 그런 다음 쉘을 열고 vim 을 사용 하여 파일에서 첫 번째와 마지막 행을 제거하십시오.

$ vim places.json

dd 를 입력 하여 첫 번째 행을 제거한 다음 SHIFT-G 를 눌러 파일 끝을 이동하고 dd를 다시 입력 하여 마지막 행을 제거하십시오. 이제 : wq 를 입력 하여 변경 사항을 저장하십시오. 최대 2 분 정도 소요됩니다.

이제 우리는 유닉스의 강력한 기능을 활용하여 파일을보다 관리하기 쉬운 덩어리로 나눕니다. 쉘 유형에서 :

$ split -l 10000 places.json places-chunks-

맥주 마시 러 가자 이렇게하면 파일이 여러 개의 작은 파일로 분할되며 각 줄에는 10000 줄이 포함됩니다. ogr2gr 이 관리 할 수 있도록 줄을 작게 유지하는 한 수 를 늘릴 수 있습니다.

이제 각 파일에 머리와 꼬리를 붙이겠습니다.

$ echo '{"type":"FeatureCollection","features":[' > head
$ echo ']}' > tail
$ for f in places-chunks-* ; do cat head $f tail > $f.json && rm -f $f ; done

갈래를 잡아라. 처음 두 명령은 단순히 정확한 내용을 가진 머리글과 바닥 글 파일을 작성하는 반면 (실제로는 편의상) 마지막 명령은 위에서 분할 한 각 청크에 머리글과 바닥 글을 추가하고 머리글 / 바닥 글없는 청크를 제거하여 공간을 절약합니다. ).

이 시점 에서 ogr2ogr을 사용 하여 많은 places- chunks- *. json 파일을 처리 할 수 ​​있습니다.

$ for f in places-chunks-*.json ; do ogr2ogr -your-options-here $f ; done

1
이 방법을 사용하면 피쳐 블록의 끝에서 "청크"파일이 분할되었는지 확인하지 않아도됩니까? 헤더 및 바닥 글 정보를 추가하기 위해 Python에서 이미 데이터를 사전 처리했기 때문에 데이터 청크에 카운터를 추가 할 수 있어야합니다. 나는 그 다음에 갈 것이다. 제안 해 주셔서 감사합니다.
RyanDalton

제공 한 예제 데이터에는 한 줄에 하나의 기능이 있었으므로 split -l을 사용했습니다 . 실제 데이터의 경우가 아니면 작동하지 않을 것입니다.
unicoletti

예, 물론 각 기능이 별도의 줄에있는 것이 맞습니다. 나는 그것을 완전히 생각하지 않았습니다.
RyanDalton

파일을 열지 않고 줄을 제거합니다. 첫번째 줄을 sed -i "1d" places.json 제거하십시오 : 첫번째 4 줄을 sed -i "1,4d" places.json 제거하십시오 : 마지막 4 줄을 제거하십시오 : head -n -4 places.json > places2.json
egofer

2

FME Desktop으로 데이터를로드 할 수 있습니다. 그건 매우 쉬워요.


이처럼 매우 큰 파일을 처리합니까?
RyanDalton

예를 들어 변환하기 전에 파일을 여러 파일로 분할하십시오. hjsplit.org 그리고 PostGIS로 가져 오기 위해 FME Desktop에서 뉴스 파일을 가져옵니다.

1
아마, 그것을 당신이 :) 지원에 소리 수 dosent 경우
simplexio

2

geojson 파일을 훨씬 작은 shapefile 형식으로 변환하거나 메모리에서 모든 작업을 수행하지 않고 직접 SQL로 변환하는 Python에서 게으른 판독기 및 작성기를 작성하는 것이 간단해야합니다. 기본 PostGIS 도구는 일단 변환되면 큰 데이터 세트를 가져올 수 있습니다. OGR의 geojson 지원은 비교적 새롭고 큰 파일을 처리하기위한 플래그는 없습니다.

어떻게 든 관리 가능한 파일 덩어리를 공유 할 수 있다면 도와 줄 수 있습니다.


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