私は現在、OpenStreetMaps の州/州のダンプを解析する Pythonic の方法の作成に取り組んでいます。私の知る限りでは、非常に大きな XML ファイルを処理する方法を知っているだけです (そうですか?)。
現在、ケベック州のダンプ(quebec-latest.osm.bz2)を解析するために、 lxml etree iterparseモジュールを使用しています。高速道路の情報を含むエントリを取得し、JSON に変換してファイルに保存し、フラッシュしたいのですが、機能していないようです。
現在、i7-4770、16 GB の RAM、128 GB SSD、および OSX 10.9 を実行しています。以下のコードを起動すると、RAM は数秒以内に完全にいっぱいになり、スワップは 30 秒以内に完了します。その後、私のシステムは、アプリケーションを閉じてスペースを空けるか、最終的にフリーズするように要求します。
これが私のコードです。そこにはおそらく多くの悪い/ガベージコードがあることに気付くでしょうが、私はそれが機能することを期待して見つけたものは何でもプラグインするところまで来ました。これに関するヘルプは大歓迎です。ありがとう!
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from lxml import etree
import xmltodict, json, sys, os, gc
hwTypes = ['motorway', 'trunk', 'primary', 'secondary', 'tertiary', 'pedestrian', 'unclassified', 'service']
#Enable Garbadge Collection
gc.enable()
def processXML(tagType):
f = open('quebecHighways.json', 'w')
f.write('[')
print 'Processing '
for event, element in etree.iterparse('quebec-latest.osm', tag=tagType):
data = etree.tostring(element)
data = xmltodict.parse(data)
keys = data[tagType].keys()
if 'tag' in keys:
if isinstance(data[tagType]['tag'], dict):
if data[tagType]['tag']['@k'] == 'highway':
if data[tagType]['tag']['@v'] in hwTypes:
f.write(json.dumps(data)+',')
f.flush() #Flush Python
os.fsync(f.fileno()) #Flush System
gc.collect() #Garbadge Collect
else:
for y in data[tagType]['tag']:
if y['@k'] == 'highway':
if y['@v'] in hwTypes:
f.write(json.dumps(data)+',')
f.flush()
os.fsync(f.fileno())
gc.collect()
break
#Supposedly there is supposed to help clean my RAM.
element.clear()
while element.getprevious() is not None:
del element.getparent()[0]
f.write(']')
f.close()
return 0
processXML('way')