ทางเลือกแทน ogr2ogr สำหรับการโหลดไฟล์ GeoJson ขนาดใหญ่ไปยัง PostGIS


24

ฉันมีไฟล์ GeoJson ขนาด 7GB ที่ฉันต้องการโหลดลงในฐานข้อมูล PostGIS ฉันได้ลองใช้ ogr2ogr แล้ว แต่มันล้มเหลวเพราะไฟล์ใหญ่เกินไปสำหรับ ogr2ogr ที่จะโหลดลงในหน่วยความจำแล้วประมวลผล

มีทางเลือกอื่นสำหรับการโหลดไฟล์ geojson นี้ลงใน PostGIS หรือไม่

ข้อผิดพลาด ogr2ogr ที่ฉันได้รับคือ:

ข้อผิดพลาด 2: CPLMalloc (): หน่วยความจำไม่เพียงพอจัดสรร -611145182 ไบต์ แอปพลิเคชั่นนี้ร้องขอให้ Runtime ทำการยกเลิกในลักษณะที่ผิดปกติ โปรดติดต่อทีมสนับสนุนของแอปพลิเคชันสำหรับข้อมูลเพิ่มเติม


1
คุณลองตัวเลือก "-gt" แล้วหรือยัง โดยค่าเริ่มต้นกลุ่ม 200 คุณสมบัติต่อการทำธุรกรรม
Pablo

ฉันไม่รู้ตัวเลือก -gt และไม่เคยลองมาก่อน ฉันเพิ่งลองเรียกใช้อีกครั้งโดยใช้ตัวเลือก -gt แต่น่าเสียดายที่พบข้อผิดพลาดเดียวกัน ฉันพยายามใช้ตัวเลือก -WHERE เพื่อ จำกัด จำนวนตัวเลือกที่ค้นหาได้ แต่ดูเหมือนจะไม่ช่วยอะไรเช่นกัน
RyanDalton

GDAL / OGR ปรับปรุงการอ่านไฟล์ GeoJSON ขนาดใหญ่ใน 2.3.0 ซึ่งช่วยลดโอเวอร์เฮดของหน่วยความจำ
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) หรือติดตั้งเครื่องมือ cygwin บน Windows จากนั้นเปิดเชลล์และใช้vimเพื่อลบแถวแรกและแถวสุดท้ายออกจากไฟล์:

$ vim places.json

พิมพ์ddเพื่อลบบรรทัดแรกจากนั้นกดSHIFT-Gเพื่อย้ายจุดสิ้นสุดของไฟล์พิมพ์ddอีกครั้งเพื่อลบบรรทัดสุดท้าย ตอนนี้พิมพ์: wqเพื่อบันทึกการเปลี่ยนแปลง ขั้นตอนนี้ควรใช้เวลาไม่กี่นาที

ตอนนี้เราจะควบคุมพลังที่แท้จริงของยูนิกซ์เพื่อแยกไฟล์เป็นกลุ่มที่จัดการได้มากขึ้น ในประเภทเปลือก:

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

ไปคว้าเบียร์ การดำเนินการนี้จะแบ่งไฟล์เป็นไฟล์ขนาดเล็กจำนวนมากแต่ละไฟล์มี 10,000 บรรทัด คุณสามารถเพิ่มจำนวนบรรทัดได้ตราบใดที่คุณยังมีขนาดเล็กพอที่ogr2grสามารถจัดการได้

ตอนนี้เรากำลังจะติดหัวและก้อยกับแต่ละไฟล์

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

ไปคว้างู สองคำสั่งแรกเพียงแค่สร้างไฟล์ส่วนหัวและส่วนท้ายที่มีเนื้อหาที่ถูกต้อง (เพื่อความสะดวกจริงๆ) ในขณะที่คำสั่งสุดท้ายจะเพิ่มส่วนหัวและส่วนท้ายให้กับแต่ละส่วนที่เราแยกด้านบนและลบส่วนหัว / ส่วนท้าย (เพื่อประหยัดพื้นที่ )

ณ จุดนี้คุณหวังว่าจะสามารถประมวลผลplaces-chunks - *. json files จำนวนมากด้วย ogr2ogr:

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

1
ด้วยวิธีนี้เราจะไม่ต้องตรวจสอบให้แน่ใจว่าไฟล์ "ชิ้น" ถูกแยกที่ท้ายบล็อกฟีเจอร์หรือไม่ เนื่องจากฉันได้ทำการประมวลผลข้อมูลล่วงหน้าใน Python แล้วเพื่อเพิ่มข้อมูลส่วนหัว & ท้ายกระดาษฉันควรจะสามารถเพิ่มตัวนับเพื่อรับข้อมูล ฉันจะให้สิ่งนั้นต่อไป ขอบคุณสำหรับคำแนะนำ
RyanDalton

ข้อมูลตัวอย่างเช่นคุณให้มีคุณลักษณะหนึ่งต่อบรรทัดที่ว่าทำไมผมไปกับแยก -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และนำเข้าไฟล์ข่าวใน FME Desktop เพื่อนำเข้าสู่ PostGIS

1
อาจและถ้ามัน dosent คุณสามารถตะโกนสนับสนุน :)
simplexio

2

ควรตรงไปข้างหน้าเพื่อเขียนผู้อ่านและผู้เขียนขี้เกียจใน Python ที่จะแปลงไฟล์ geojson ของคุณเป็นรูปแบบ shapefile ที่เล็กกว่ามากหรือโดยตรงไปยัง SQL โดยไม่ต้องทำทุกอย่างในหน่วยความจำ เมื่อแปลงแล้วเครื่องมือ PostGIS ดั้งเดิมสามารถนำเข้าชุดข้อมูลขนาดใหญ่ได้ การสนับสนุน geojson ใน OGR ค่อนข้างใหม่และไม่มีแฟล็กสำหรับจัดการไฟล์ขนาดใหญ่

หากคุณสามารถแชร์ไฟล์ของคุณได้ฉันสามารถช่วยคุณได้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.