OpenGeoDB PLZ-TSV-Dateien mit Python parsen
English
Deutsch
Problem:
Du möchtest die OpenGeoDB Postleitzahl-TSV-Dateien parsen, die hier verfügbar sind.
Lösung
Je nach Anwendungsfall könnte PyGeoDB, das auf den OpenGeoDB-Online-Dienst zugreift, eine besser geeignete Lösung sein.
Wenn du eine lokale Lösung für deine Aufgabe benötigst, ist hier ein einfaches Python-Skript im Generator-Stil, das die Informationen in einem namedtuple speichert. Es enthält ein Beispiel.
parse_opengeodb_plz.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Ein OpenGeoDB PLZ-TSV-Parser
Dieser Parser kann verwendet werden, um TSV-Dateien zu parsen, die unter
https://web.archive.org/web/20200110114101/http://www.fa-technik.adfc.de/code/opengeodb/
gefunden werden können.
Dieses Skript ist für die Verwendung mit Python3 gedacht.
Es sollte mit Python 2.x funktionieren, jedoch könnte Unicode mit CSV
ein Problem darstellen.
Getestet mit DE.tsv. Kleinere Änderungen könnten für andere TSVs notwendig sein,
da für verschiedene Länder unterschiedliche Daten gespeichert werden.
Version 1.0
(c) Uli Köhler (2015)
Veröffentlicht unter CC0 1.0 Universal (public domain)
"""
import csv
from collections import namedtuple
__author__ = "Uli Köhler"
__version__ = "1.0"
__license__ = "CC0 1.0 Universal"
PLZEntry = namedtuple('PLZEntry',
['loc_id', #OpenGeoDB Location ID
'ags', # AGS - Amtlicher Gemeindeschluessel
'ascii', # Normalisierter ASCII-only Großbuchstaben-Ortsname
'name', # Tatsächlicher (Unicode) Ortsname
'lat', # Breitengrad in Grad
'lon', # Längengrad in Grad
'amt', # Zugehörig zu
'plz', # Liste von PLZ-Codes
'vorwahl', # Telefonvorwahl
'einwohner', # Einwohnerzahl
'flaeche', # Fläche
'kz', # KFZ Kennzeichen
'typ', # ?
'level', # ?
'of', # ?
'invalid'])
def zeroOneToBool(x):
"Wandelt '0' in False um, alles andere in "
return False if x == '0' else True
def toFloatDefault(s, default=float('NaN')):
"Wandelt einen String in einen float um, mit einem Standardwert im Fehlerfall"
try: return float(s)
except ValueError: return default
def toIntDefault(s, default=0):
"Wandelt einen String in einen int um, mit einem Standardwert im Fehlerfall"
try: return int(s)
except ValueError: return default
def readTSVFile(filename):
"Liest eine OpenGeoDB PLZ-TSV-Datei und yielded PLZEntry-Objekte"
with open(filename) as infile:
csvreader = csv.reader(infile, delimiter='\t', quotechar='"')
for row in csvreader:
if row[0] == "#loc_id": continue # Header überspringen
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__":
#Beispiel für die Verwendung der Funktionen
import argparse
parser = argparse.ArgumentParser(description="Den Namen eines Ortes anhand seines PLZ-Codes abrufen")
parser.add_argument("infile", help="Die OpenGeoDB-TSV-Datei zum Lesen")
parser.add_argument("plz", help="Nur Eintragsnamen mit dieser PLZ ausgeben")
args = parser.parse_args()
#Reader ausführen
for entry in readTSVFile(args.infile):
if args.plz in entry.plz:
print (entry.name)Check out similar posts by category:
Python, Geoinformatics
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow