我有一个7GB的GeoJson文件,我想将其加载到PostGIS数据库中。我曾尝试使用ogr2​​ogr,但由于文件太大而无法加载到内存中然后进行处理,因此失败了。

是否还有其他替代方法可以将此geojson文件加载到PostGIS中?

我遇到的ogr2ogr错误是:


错误2 :CPLMalloc():内存不足,分配-611145182字节。此
应用程序已请求运行时以异常的方式终止它。请与应用程序的支持团队联系以获取更多信息。


评论

您是否尝试过“ -gt”选项?默认情况下,每个事务将200个功能分组。

我不知道-gt选项,之前也没有尝试过。我只是尝试使用-gt选项重新运行,但是不幸地遇到了相同的错误。我还尝试使用-WHERE选项限制可搜索选项的数量,但这似乎也无济于事。

GDAL / OGR在2.3.0中改进了对大型GeoJSON文件的读取,这大大减少了内存开销。

#1 楼

您发送的样本表明,可以使用记事本++之类的编辑器手动拆分文件
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.


#2 楼

不幸的是,JSON非常类似于XML,非常不适合流处理,因此几乎所有实现都需要将整个数据集加载到内存中。尽管对于您的小型集合来说这是可以的,但除了将数据集分成更小的,可管理的块之外,别无选择。

改进了Pablo的解决方案,这是不需要您实际打开和加载的解决方案将该文件放入编辑器中,然后手动拆分,但尝试使整个过程尽可能自动化。

将json文件复制到Unix主机(Linux,osx)上或在Windows上安装cygwin工具。 br />然后打开一个shell并使用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


抓个蛇。
前两个命令只是创建一个具有正确内容的页眉和页脚文件(实际上只是为了方便起见),最后一个命令将添加页眉和页脚添加到上面拆分的每个块中,并删除无标题/无页脚的块(以节省空间)。

此时,您可以希望使用ogr2​​ogr处理很多place-chunks-*。json文件:

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


评论


使用这种方法,我们是否不必确保在功能块的末尾拆分文件“块”?由于我已经在Python中预处理了数据以添加页眉和页脚信息,因此我应该能够添加一个计数器来对数据进行分块。接下来,我会尝试一下。谢谢你的建议。

– RyanKDalton
2011年10月31日14:14

您提供的示例数据每行只有一个功能,这就是为什么我使用split -l。如果实际数据不是这种情况,那么恐怕将无法正常工作。

– Unicoletti
2011年10月31日14:27

是的,您当然是正确的,其中每个功能都位于单独的行上。我并不是一直都这么想。

– RyanKDalton
2011年10月31日14:34

删除行而不打开文件。删除第一行:sed -i“ 1d” places.json删除前4行:sed -i“ 1,4d” places.json删除最后4行:head -n -4 place.json> places2.json

– egofer
16年8月3日,11:49



#3 楼

用Python编写一个懒惰的读取器和写入器应该很简单,该读取器和写入器会将您的geojson文件转换为小得多的shapefile格式,或者直接转换为SQL,而无需在内存中完成所有操作。转换后,本地PostGIS工具可以导入大数据集。 OGR中对geojson的支持相对较新,并且没有任何用于处理大文件的标志。

如果您可以以某种方式共享文件的可管理部分,我可以为您提供帮助。

#4 楼

GDAL 2.3.0中对此进行了改进https://trac.osgeo.org/gdal/wiki/Release/2.3.0-News现在读取大型GeoJSON文件的内存效率更高。

#5 楼

可以使用FME Desktop加载数据。
非常容易。

评论


它会像这样处理一个非常大的文件吗?

– RyanKDalton
2011年10月31日,0:36

例如,在转换之前将文件拆分为多个文件。 hjsplit.org并将新闻文件导入FME Desktop,以导入到PostGIS。

–user3120
2011年10月31日,下午1:42

可能,如果有帮助,您可以大声支持:)

–simplexio
2013年9月6日下午5:58