Alternatif untuk ogr2ogr untuk memuat file GeoJson besar ke PostGIS

24

Saya memiliki file GeoJson 7GB yang ingin saya muat ke dalam database PostGIS. Saya sudah mencoba menggunakan ogr2ogr tetapi gagal karena file terlalu besar untuk ogr2ogr dimuat ke dalam memori dan kemudian proses.

Apakah ada alternatif lain untuk memuat file geojson ini ke PostGIS?

Kesalahan ogr2ogr yang saya dapatkan adalah:

GALAT 2: CPLMalloc (): Kehabisan memori yang dialokasikan -611145182 byte. Aplikasi ini telah meminta Runtime untuk menghentikannya dengan cara yang tidak biasa. Silakan hubungi tim dukungan aplikasi untuk informasi lebih lanjut.

Ryan Dalton
sumber
1
Sudahkah Anda mencoba opsi "-gt"? Secara default ia mengelompokkan 200 fitur per transaksi.
Pablo
Saya tidak mengetahui opsi -gt dan belum mencobanya sebelumnya. Saya baru saja mencoba menjalankan kembali menggunakan opsi-gt, dan sayangnya mengalami kesalahan yang sama. Saya juga berusaha untuk menggunakan opsi-DI MANA untuk membatasi jumlah opsi yang bisa dicari, tetapi itu sepertinya juga tidak membantu.
RyanDalton
GDAL / OGR telah meningkatkan pembacaan file GeoJSON besar di 2.3.0 yang sangat mengurangi overhead memori.
AndrewHarvey

Jawaban:

10

Sampel yang Anda kirim menunjukkan bahwa dimungkinkan untuk membagi file secara manual menggunakan editor seperti notepad ++

1) Untuk setiap chunk buat header:

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

2) Setelah tajuk menempatkan banyak fitur:

{"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/[email protected]", "address": "Le\u00f3n Tolstoi #18 PH Col. Anzures", "owner": "simplegeo", "postcode": "11590"}},

3) Selesai potongan dengan:

]}

EDIT - Ini adalah kode python yang akan membagi file menjadi beberapa ukuran yang ditentukan (dalam sejumlah fitur):

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.
Pablo
sumber
19

Sayangnya JSON, seperti halnya XML, sangat tidak cocok untuk pemrosesan aliran sehingga hampir semua implementasi mengharuskan seluruh dataset dimuat dalam memori. Meskipun ini ok untuk set kecil dalam kasus Anda, tidak ada pilihan lain selain memecah dataset menjadi potongan yang lebih kecil dan dapat dikelola.

Memperbaiki solusi Pablo, berikut ini salah satu yang tidak mengharuskan Anda untuk benar-benar membuka dan memuat file ke dalam editor dan dibagi dengan tangan tetapi mencoba untuk mengotomatisasi sebanyak mungkin seluruh proses.

Salin file json ke host Unix (linux, osx) atau instal alat cygwin di Windows. Kemudian buka shell dan gunakan vim untuk menghapus baris pertama dan terakhir dari file:

$ vim places.json

ketik dd untuk menghapus baris pertama, lalu SHIFT-G untuk memindahkan akhir file, ketik dd lagi untuk menghapus baris terakhir. Sekarang ketik : wq untuk menyimpan perubahan. Ini harus paling lama hanya beberapa menit.

Sekarang kita akan memanfaatkan kekuatan unix untuk membagi file menjadi potongan yang lebih mudah dikelola. Dalam jenis shell:

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

Pergi minum bir. Ini akan membagi file menjadi banyak file yang lebih kecil, masing-masing berisi 10.000 baris. Anda dapat menambah jumlah garis, asalkan Anda cukup kecil sehingga ogr2gr dapat mengelolanya.

Sekarang kita akan menempelkan kepala dan ekor ke masing-masing file:

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

Pergi ambil seekor ular. Dua perintah pertama cukup membuat file header dan footer dengan konten yang benar (hanya untuk kenyamanan benar-benar), sedangkan yang terakhir akan menambahkan header dan footer ke setiap potongan yang kita pisah di atas dan menghapus potongan tanpa header / tanpa footer (untuk menghemat ruang ).

Pada titik ini semoga Anda dapat memproses banyak tempat-potongan - *. File json dengan ogr2ogr:

$ for f in places-chunks-*.json ; do ogr2ogr -your-options-here $f ; done
unicoletti
sumber
1
Dengan metode ini, bukankah kita harus memastikan file "chunks" terpecah di akhir blok fitur? Karena saya sudah melakukan pra-pemrosesan data dalam Python untuk menambahkan informasi header & footer, saya harus dapat menambahkan penghitung untuk memotong data. Saya akan mencobanya nanti. Terima kasih untuk sarannya.
RyanDalton
Contoh data yang Anda berikan memiliki satu fitur per baris, itu sebabnya saya menggunakan split -l . Jika itu tidak terjadi dengan data aktual maka saya khawatir itu tidak akan berfungsi.
unicoletti
Ya, tentu saja Anda benar, di mana setiap fitur berada pada jalur yang terpisah. Saya tidak memikirkan hal itu sepanjang jalan.
RyanDalton
Untuk menghapus garis tanpa membuka file. Hapus baris pertama: sed -i "1d" places.json Hapus 4 baris pertama: sed -i "1,4d" places.json Hapus 4 baris terakhir: head -n -4 places.json > places2.json
egofer
2

Dimungkinkan untuk memuat data Anda dengan FME Desktop. Sangat mudah.


sumber
Apakah ini akan memproses file yang sangat besar seperti ini?
RyanDalton
Misalnya, bagi file menjadi banyak file sebelum transformasi. hjsplit.org Dan impor file berita di Desktop FME untuk impor ke PostGIS.
1
mungkin, dan jika itu dosis Anda dapat berteriak untuk mendukung :)
simplexio
2

Seharusnya lurus ke depan untuk menulis pembaca dan penulis malas dengan Python yang akan mengubah file geojson Anda ke format shapefile yang jauh lebih kecil atau langsung ke SQL tanpa melakukan semuanya dalam memori. Setelah dikonversi, alat PostGIS asli dapat mengimpor set data besar. Dukungan geojson di OGR relatif baru dan tidak ada bendera untuk menangani file besar.

Jika Anda entah bagaimana dapat berbagi file yang dapat dikelola, saya dapat membantu Anda.

GeospatialPython.com
sumber