使用 Python 解析 OpenGeoDB PLZ 代码 TSV 文件

问题:

你想解析可从此处获取的 OpenGeoDB Postleitzahl(德国邮政编码)TSV 文件。

解决方案

根据你的用例,访问 OpenGeoDB 在线服务的 PyGeoDB 可能是更合适的解决方案。

如果你需要任务的本地解决方案,这里有一个简单的生成器风格 Python 脚本,将信息存储在 namedtuple 中。它包含一个示例。

parse_opengeodb_plz.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OpenGeoDB PLZ 代码 TSV 解析器

此解析器可用于解析在以下位置找到的 TSV 文件
https://web.archive.org/web/20200110114101/http://www.fa-technik.adfc.de/code/opengeodb/

此脚本旨在用于 Python3。
它应该适用于 python 2.x,但 CSV 的 unicode
可能是个问题。

已用 DE.tsv 测试。其他 TSV 可能需要少量修改,
因为不同国家存储不同数据

版本 1.0
(c) Uli Köhler (2015)
在 CC0 1.0 Universal (公共领域) 下发布
"""
import csv
from collections import namedtuple

__author__  = "Uli Köhler"
__version__ = "1.0"
__license__ = "CC0 1.0 Universal"

PLZEntry = namedtuple('PLZEntry',
    ['loc_id', #OpenGeoDB 位置 ID
    'ags', # AGS - 官方社区代码
    'ascii', # 规范化的仅 ASCII 大写位置名称
    'name', # 实际(unicode)位置名称
    'lat', # 纬度(度)
    'lon', # 经度(度)
    'amt', # 关联到
    'plz', # PLZ 代码列表
    'vorwahl', # 电话前缀
    'einwohner', # 人口数字
    'flaeche', # 面积
    'kz', # KFZ 车牌
    'typ', # ?
    'level', # ?
    'of', # ?
    'invalid'])

def zeroOneToBool(x):
    "将 '0' 转换为 False,其他所有内容转换为 "
    return False if x == '0' else True

def toFloatDefault(s, default=float('NaN')):
    "将字符串转换为浮点数,出错时使用默认值"
    try: return float(s)
    except ValueError: return default

def toIntDefault(s, default=0):
    "将字符串转换为整数,出错时使用默认值"
    try: return int(s)
    except ValueError: return default

def readTSVFile(filename):
    "读取 OpenGeoDB PLZ TSV 文件并生成 PLZEntry 对象"
    with open(filename) as infile:
        csvreader = csv.reader(infile, delimiter='\t', quotechar='"')
        for row in csvreader:
            if row[0] == "#loc_id": continue # 跳过标题
            yield PLZEntry(toIntDefault(row[0]), row[1], row[2], row[3], toFloatDefault(row[4]), toFloatDefault(row[5]),
                           row[6], row[7].split(","), row[8], toIntDefault(row[9]), toFloatDefault(row[10]), row[11],
                           row[12], row[13], row[14], zeroOneToBool(row[15]))


if __name__ == "__main__":
    #如何使用函数的示例
    import argparse
    parser = argparse.ArgumentParser(description="通过 PLZ 代码获取位置名称")
    parser.add_argument("infile", help="要读取的 OpenGeoDB TSV 文件")
    parser.add_argument("plz", help="仅打印具有此 PLZ 的条目名称")
    args = parser.parse_args()
    #运行读取器
    for entry in readTSVFile(args.infile):
        if args.plz in entry.plz:
            print (entry.name)

Check out similar posts by category: Python, Geoinformatics