我目前正致力于通过 OpenStreetMaps 省/州转储创建一种 Python 式的解析方式;据我所知,这只是知道如何处理非常大的 XML 文件(对吗?)。
我目前正在使用lxml etree iterparse模块来解析魁北克省的转储(quebec-latest.osm.bz2)。我想提取任何具有高速公路信息的条目,转换为 JSON,将其保存到文件并刷新,尽管它似乎不起作用。
我目前正在运行 i7-4770、16GB 内存、128GB 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')