Альтернативи ogr2ogr для завантаження великих файлів GeoJson у PostGIS


24

У мене є файл GeoJson 7 Гб, який я хотів би завантажити в базу даних PostGIS. Я намагався використовувати ogr2ogr, але він не вдається, тому що файл занадто великий, щоб ogr2ogr завантажувався в пам'ять, а потім оброблявся.

Чи є інші альтернативи для завантаження цього файлу geojson в PostGIS?

Помилка ogr2ogr, яку я отримую:

ПОМИЛКА 2: CPLMalloc (): Виділення пам'яті виділяє -611145182 байт. Ця програма попросила Runtime припинити її незвичним чином. Для отримання додаткової інформації зверніться до служби підтримки програми.


1
Ви спробували варіант "-gt"? За замовчуванням вона групує 200 функцій на транзакцію.
Пабло

Мені не було відомо про варіант -gt і раніше не пробував. Я просто спробував повторно запустити за допомогою параметра -gt, але, на жаль, зіткнувся з тією ж помилкою. Я також спробував використати параметр -WHERE, щоб обмежити кількість варіантів пошуку, але це, мабуть, не допомогло.
РайанДалтон

GDAL / OGR покращив читання великих файлів GeoJSON в 2.3.0, що значно зменшує накладні витрати на пам'ять.
AndrewHarvey

Відповіді:


10

Зразок, який ви надіслали, показує, що можливо вручну розділити файл за допомогою редактора на зразок блокнота ++

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) Закінчіть шматок:

]}

EDIT - Ось код python, який розділить файл на частини певного розміру (за кількістю функцій):

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, щоб зберегти зміни. Це займе всього пару хвилин.

Тепер ми будемо використовувати абсолютну силу Unix, щоб розділити файл на більш керовані шматки. У типі оболонки:

$ 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

Іди схоплюй закуску. Перші дві команди просто створюють файл заголовка та нижнього колонтитулу з правильним вмістом (просто для зручності), тоді як остання додасть колонтитул та колонтитул до кожного з фрагментів, які ми розділили вище, та видалить безголовий / нижній колонтитул (щоб заощадити місце ).

У цей момент ви можете сподіватися, що обробити безліч файлів - *. Json з 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. Це дуже просто.


Чи обробить такий надзвичайно великий файл, як цей?
RyanDalton

Наприклад, розділіть файл на багато файлів до трансформації. hjsplit.org І імпортуйте файли новин на робочий стіл FME для імпорту в PostGIS.

1
напевно, і якщо це дози, ви можете кричати на підтримку :)
simplexio

2

Слід прямо вперед написати ледачого читача та письменника в Python, який би перетворив ваш файл geojson у набагато менший формат filefile або безпосередньо в SQL, не роблячи це все в пам'яті. Після конвертації нативні інструменти PostGIS можуть імпортувати великі набори даних. Підтримка Geojson в OGR порівняно нова, і немає жодних прапорів для обробки великих файлів.

Якщо ви можете якось поділитися керованим фрагментом вашого файлу, я можу вам допомогти.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.