Альтернативы ogr2ogr для загрузки больших файлов GeoJson в PostGIS

24

У меня есть 7 ГБ файл GeoJson, который я хотел бы загрузить в базу данных PostGIS. Я пытался использовать ogr2ogr, но это не удается, потому что файл слишком велик для загрузки ogr2ogr в память и последующей обработки.

Существуют ли другие варианты загрузки этого файла геоджона в PostGIS?

Я получаю ошибку ogr2ogr:

ОШИБКА 2: CPLMalloc (): Недостаточно памяти, выделяющей -611145182 байта. Это приложение запросило Runtime прекратить его необычным способом. Пожалуйста, обратитесь в службу поддержки приложения для получения дополнительной информации.

RyanDalton
источник
1
Вы пробовали опцию "-gt"? По умолчанию он группирует 200 объектов на транзакцию.
Пабло
Я не знал о опции -gt и не пробовал ее раньше. Я только что попытался перезапустить, используя опцию -gt, и, к сожалению, столкнулся с той же ошибкой. Я также попытался использовать опцию -WHERE, чтобы ограничить количество доступных для поиска опций, но это тоже не помогло.
RyanDalton
В версии 2.3.0 GDAL / OGR улучшено чтение больших файлов GeoJSON, что значительно снижает нагрузку на память.
ЭндрюХарви,

Ответы:

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) Закончить кусок с:

]}

РЕДАКТИРОВАТЬ - Вот код 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.
Pablo
источник
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Теперь файлов place .json с помощью ogr2ogr:

$ for f in places-chunks-*.json ; do ogr2ogr -your-options-here $f ; done
unicoletti
источник
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
вероятно, и если это не так, вы можете кричать, чтобы поддержать :)
Simplexio
2

Должно быть просто написать ленивого читателя и писателя на Python, который конвертировал бы ваш файл geojson в гораздо меньший формат шейп-файла или непосредственно в SQL, не делая все это в памяти. После преобразования собственные инструменты PostGIS могут импортировать большие наборы данных. Поддержка geojson в OGR относительно нова, и нет никаких флагов для обработки больших файлов.

Если вы можете как-то поделиться управляемым фрагментом вашего файла, я могу вам помочь.

GeospatialPython.com
источник