# Funktion: Berechnet die Entfernung zwischen zwei Orten in Deutschland # Autoren: Vinzent Reiss, Nils Dohndorf # Datum: 08.06.2017 Version: 1.0 # # verwendete Module import sys as System import re as Regular import math import logging # # globale Variablen datei = "DE.tab" radius = 6371.0 logging.basicConfig(level=logging.INFO) _name_ = "main" logger = logging.getLogger(_name_) # # Funktionen # # konvertiert einen beliebigen string in einen aus blossen Zahlen bestehenden def toint(string): _name_ = "toint" logger = logging.getLogger(_name_) logger.info("Start eliminating non number characters...") ziffern = ["0","1","2","3","4","5","6","7","8","9"] tmp = "" for i in range(len(string)): if string[i] in ziffern: tmp += string[i] logger.info("finished") if len(tmp) == 0: return "0" return tmp # liest die einzelnwn Zeilen der Tabellen ein def tabelleeinlesen(): _name_ = "tabelleeinlesen" logger = logging.getLogger(_name_) logger.info("Start reading file...") tmptabelle = [] lesen = open(datei) while True: tmp = lesen.readline() if not tmp: break if tmp[0] == "#": continue zeile = tmp.split("\t") tmptabelle.append(zeile) lesen.close() logger.info("finished") return tmptabelle # ermitteln aus einer in Zeilenform gegebenen Tabelle die nte Spalte def spalteermitteln(tmptabelle,spalte): _name_ = "spalteermitteln" logger = logging.getLogger(_name_) logger.info("Determining columns...") tmpspalte = [] logger.info("finished") for i in range(len(tmptabelle)): tmpspalte.append(tmptabelle[i][spalte]) return tmpspalte # eliminiert nicht benoetigte, also redundante, oder ungeeignete Eintraege def tabellenreduzieren(namen,latituden,longituden,plz): _name_ = "tabellenreduzieren" logger = logging.getLogger(_name_) logger.info("Start eliminating redundant entries... This can take a while...") tmpnamen = [] tmplatituden = [] tmplongituden = [] tmpplz = [] for i in range(len(namen)): if (latituden[i] <> "") and (longituden[i] <> "") and (plz[i] <> ""): tmpnamen.append(namen[i]) tmplatituden.append(latituden[i]) tmplongituden.append(longituden[i]) tmpplz.append(plz[i]) logger.info("finished") return (tmpnamen,tmplatituden,tmplongituden,tmpplz) # erstellt eine Liste passender Orte, zu einem Suchbegriff def ortssuche(namen): _name_ = "ortssuche" logger = logging.getLogger(_name_) logger.info("Start creating array of fitting entires main database...") name = raw_input().lower() treffer = [] for i in range(len(name)): treffer.append([]) suchwortlaenge = 1 while suchwortlaenge <= len(name): for i in range(len(namen)): if Regular.search(name[0:suchwortlaenge],namen[i].lower()): treffer[suchwortlaenge-1].append(i) if treffer[suchwortlaenge-1] == []: break suchwortlaenge += 1 logger.info("finished") return treffer[suchwortlaenge-2] # wandelt Polarkoordinaten in Kartesische um def koordinatenberechnung(lat,long): _name_ ="koordinatenberechnung" logger = logging.getLogger(_name_) logger.info("Start converting coordinates...") x = radius*math.cos(long)*math.cos(lat) y = radius*math.sin(long)*math.cos(lat) z = radius*math.sin(lat) logger.info("finished") return (x,y,z) # berechnet den Winkel zwischen zwei dreidimensionalen Vektoren def winkelberechnung(x1,y1,z1,x2,y2,z2): _name_ = "winkelberechnung" logger = logging.getLogger(_name_) logger.info("Start calculating angle between two vectors...") skalarprodukt = x1*x2+y1*y2+z1*z2 betrag1 = math.sqrt(x1*x1+y1*y1+z1*z1) betrag2 = math.sqrt(x2*x2+y2*y2+z2*z2) logger.info("finished") return math.acos(skalarprodukt/(betrag1*betrag2)) # ermittelt die Entfernung zweier Punkte auf einem Kreis def distanzrechnung(startlat,startlong,endlat,endlong): _name_ = "distanzrechnung" logger = logging.getLogger(_name_) logger.info("Start calculating distance...") (xstart,ystart,zstart) = koordinatenberechnung(startlat,startlong) (xend,yend,zend) = koordinatenberechnung(endlat,endlong) kreiswinkel = winkelberechnung(xstart,ystart,zstart,xend,yend,zend) logger.info("finished") return radius*kreiswinkel # gibt Liste mit Vorschlaegen aus def ortsliste(vorschlaege, namen, plz): _name_ = "ortsliste" logger = logging.getLogger(_name_) logger.info("Present search results...") zaehler = 0 antwort = "" System.stdout.write("\f") for i in vorschlaege: zaehler += 1 System.stdout.write("\t%d. Vorschlag: %-32s, PLZ: %8s\n" % (zaehler,namen[i],plz[i])) if (zaehler%16) == 0: System.stdout.write("\tIst der gesuchte Ort unter den gelisteten? ") antwort = raw_input().lower() if antwort[0] == "j": logger.info("finished") break System.stdout.write("\tEs stehen noch %d Antworten zur Verfuegung. Willst du sie sehen? " % (len(vorschlaege)-zaehler)) antwort = raw_input().lower() if antwort[0] == "j": System.stdout.write("\f") continue System.stdout.write("\tSchade.\n") logger.info("Program interrupted.") System.exit() # # Hauptprogramm System.stdout.write("\tBitte haben Sie etwas Geduld, waehrend die Daten verarbeitet werden...\n") tabelle = tabelleeinlesen() namen = spalteermitteln(tabelle,3) latituden = spalteermitteln(tabelle,4) longituden = spalteermitteln(tabelle,5) plz = spalteermitteln(tabelle,7) (namen,latituden,longituden,plz) = tabellenreduzieren(namen,latituden,longituden,plz) tabelle = [] System.stdout.write("\f") System.stdout.write("\tDer Name des 1. Ortes lautet? ") vorschlaege = ortssuche(namen) antwort = "" ortsliste(vorschlaege, namen, plz) System.stdout.write("\tWelcher der Vorschlaege soll fuer die Berechnung der Entfernung verwendet werden? ") antwort = int(toint(raw_input()))-1 startort = namen[vorschlaege[antwort]] logger.info("Calculation startlatitude and -longitude...") startlatitude = float(latituden[vorschlaege[antwort]])*(2*math.pi/360) startlongitude = float(longituden[vorschlaege[antwort]])*(2*math.pi/360) System.stdout.write("\f") System.stdout.write("\tDer Name des 2. Ortes lautet? ") vorschlaege = ortssuche(namen) antwort = "" ortsliste(vorschlaege, namen, plz) System.stdout.write("\tWelcher der Vorschlaege soll fuer die Entfernungsrechnung verwendet werden? ") antwort = int(toint(raw_input()))-1 endort = namen[vorschlaege[antwort]] logger.info("Calculating endlatitude and -longitude") endlatitude = float(latituden[vorschlaege[antwort]])*(2*math.pi/360) endlongitude = float(longituden[vorschlaege[antwort]])*(2*math.pi/360) entfernung = distanzrechnung(startlatitude,startlongitude,endlatitude,endlongitude) System.stdout.write("\tDie Entfernung zwischen %s und %s betraegt %.2f km.\n" % (startort,endort,entfernung))