#Entfernungen berechnen
#Python 2.7
#Author Gunnar Egenolff
#letzte Bearbeitung 22.5.19



import re
import math as m
debug = 0




def EINGABE(startoderziel):#Funktion fuer Eingabe
    
    eingabe = raw_input(startoderziel)#Eingabeaufforderung
    eingabealsliste = list(eingabe)#Umwandlung der Eingabe in Liste
    laenge = len(eingabealsliste)#Laenge der Liste
    if debug == 1: print "Eingabe als Liste: ", (eingabealsliste)
    
    if debug == 1: print "Anzahl der Listenelemente / Laenge der Eingabe: ", (laenge)
    return eingabealsliste

    

def SUCHBEGRIFF(eingabealsliste, suchbegriffealsliste):#Funktion zur Erstellung der regulaeren Ausdruecke
    laenge = len(eingabealsliste)#Laenge der Liste
    i = 0#Zaehlvariable fuer Schleife
    while i <= laenge - 1: #legt Liste mit regulaeren Ausdruecken an
        if debug == 1: print "Ersetzter Buchstabe: ", eingabealsliste[i]
        t = eingabealsliste[:] #Originalliste soll erhalten bleiben, gearbeitet wird mit modifizierter Liste
        t.insert(i,".?.?") #je ein Buchstabe wird durch 2x Punkt Fragezeichen ersetzt. So koennen an dieser Stelle bis zu 2 beliebige Zeichen vorkommen.
        del t[i+1]#ersetzter Buchstabe wird geloescht
        mod = "".join(t)#regulaerer Ausdruck als String
        suchbegriffealsliste.append("\t" + mod + "\s") #Whitespaces stellen sicher, dass Suchbegriff nicht Teil eines laengeren Namens
        if debug == 1: print "geaenderte Liste: ", t
        if debug == 1: print "originale Liste: ", eingabealsliste
        if debug == 1: print "Liste der Suchbegriffe: ", suchbegriffealsliste
    
        i = i + 1
    return suchbegriffealsliste


    

def AUSLESE(x):#Funktion fuer zeilenweises Auslesen der Ortedatei, Abgleich mit Suchbegriff

    
    j = 0#Zaehlvariable fuer Liste mit regulaeren Ausdruecken
    k = 1#Nummer fuer Trefferanzeige
    brt = []#Liste fuer Breitengrade
    lag = []#Liste fuer Laengengrade
    ort = []#Liste fuer Ortsnamen
    schonmalgesehen = []#Liste fuer Treffer, verhindert Mehrfachtreffer
    while j <= len(x) - 1: #fragt nacheinander alle Versionen des Ortsnamens ab
        linenr = 0#Startwert und Reset fuer Zaehlvariable fuer Dateizeilen
        detab = open("DE.tab")#oeffnet Datei
        Suchbegriff = str(x[j])
        while True: # liest Datenbank zeilenweise aus
            line = detab.readline()
            if not line: break
            linenr += 1
            if re.search(Suchbegriff, line) and not linenr in schonmalgesehen: #findet Ortsname, Abgleich mit Trefferliste
                Liste = line.split("\t")#wandelt Dateizeile in Liste um
                print k, Liste[7], Liste[3], Liste[4], Liste[5] #Ausgabe Nummer, Plz, Ortsname, Breite, Laenge
                ort.append(Liste[3])#Trefferlisten
                brt.append(Liste[4])
                lag.append(Liste[5])
                k += 1
                schonmalgesehen.append(linenr)
                if debug == 2: print schonmalgesehen
                if debug == 2: print lon, lat
        if debug == 1: print "Suchbegriff: ", str(x[j])
        j+=1
        line = True
        detab.close()
    vorschlag = [ort, brt, lag]#Zusammenfassung der Trefferlisten fuer return
    return vorschlag
    
    

def AUSWAHL(vorschlag):#Funktion fuer Aufforderung zur Auswahl eines Treffers
    auswahl = 1000#Startwert fuer Abbruchbedingung
    while auswahl - 1 > len(vorschlag[1]):#Eingabefehler abfangen
        while True:
            try:  
                auswahl = raw_input("Bitte geben Sie die Nummer des gewuenschten Orts ein: ")
                auswahl = int(auswahl)
                break
            except ValueError:
                print "Bitte natuerliche Zahl eingeben!"
    Orte = vorschlag[0]#zweistufiges Verfahren zur Isolierung der Werte fuer Ortsname und Koordinaten
    Ort = Orte[auswahl - 1]#umgeht Syntaxprobleme bei vorschlag[0[auswahl - 1]]
    Laengengrade = vorschlag[1]
    Laengengrad = Laengengrade [auswahl - 1]
    Breitengrade = vorschlag[2]
    Breitengrad = Breitengrade [auswahl - 1]
    Koordinaten = []#Zusammenfassung von Ortsname und Koordinaten in Liste fuer return
    Koordinaten.append(Laengengrad)
    Koordinaten.append(Breitengrad)
    Koordinaten.append(Ort)
    return Koordinaten


#Start
suchbegriffealsliste1 = []
suchbegriffealsliste2 = []
treffer1 = []
treffer2 = []
while len(treffer1) == 0:#1. Schleife fuer Start, erneute Suche wenn Suche ohne Treffer
    eingabealsliste1 = EINGABE("Start eingeben: ")#Funktionen GROSS geschrieben
    suchbegriffealsliste1 = SUCHBEGRIFF(eingabealsliste1, suchbegriffealsliste1)
    vorschlag1 = AUSLESE(suchbegriffealsliste1)
    treffer1 = vorschlag1 [0]#Abbruchbedingung fuer Schleife
    if len(treffer1) == 0:
        print "Nichts gefunden :("
Koordinaten1 = AUSWAHL(vorschlag1)

L1 = m.radians(float(Koordinaten1[0]))#Koordinaten in Bogenmass umwandeln
B1 = m.radians(float(Koordinaten1[1]))
O1 = Koordinaten1[2]#Ortsname fuer Ausgabe

while len(treffer2) == 0:#2. Schleife fuer Ziel
    eingabealsliste2 = EINGABE("Ziel eingeben: ")
    suchbegriffealsliste2 = SUCHBEGRIFF(eingabealsliste2, suchbegriffealsliste2)
    vorschlag2 = AUSLESE(suchbegriffealsliste2)
    treffer2 = vorschlag2 [0]
    if len(treffer2) == 0:
        print "Nichts gefunden :("
Koordinaten2 = AUSWAHL(vorschlag2)


L2 = m.radians(float(Koordinaten2[0]))
B2 = m.radians(float(Koordinaten2[1]))
O2 = Koordinaten2[2]

#Berechnung der Entfernung
if debug == 1: print "laenge1", L1, K1[0]
if debug == 1: print "breite1", B1, K1[1]
if debug == 1: print "laenge2", L2, K2[0]
if debug == 1: print "breite2", B2, K2[1]

distanz = 6371.0 * m.acos( m.cos(B1) * m.cos(B2) * m.cos(L2 - L1) + m.sin(B1) * m.sin(B2) )
print "Die Entfernung zwischen", O1,"und", O2,"betraegt: ", distanz, "km."
