0

Distanz (Luftlinie) zwischen GPS-Koordinaten berechnen

Hallo allerseits.

Ich versuche mich mal wieder an etwas und merke dabei, dass ich eigentlich nicht genug Ahnung habe. :-) Mit fehlen sowohl die Kenntnisse in der Ninox Programmiersprache und ich hab auch noch Probleme, die Aufgabenstellung in Ninox-Logik zu übertragen.

Also, um sinnvollen Touren (Fahrtzeit und Spritkosten) zu meinen Kunden zugestalten, möchte ich mir gern in meiner Kundendatenbank in einem Gestaltungselemen "Ansicht", diejenigen Kunden anzeigen lassen, die in einem bestimmten Umkreis von dem angezeigten Kunden wohnen. Ich muss also quasi die Entfernung von jedem einzelnen Kunden zu jedem anderen Kunden berechnen und kann dann nach der gewünschten max. Entfernung filtern. 

Ich habe alle Adressen bereits geogodiert und als GPS-Koordinaten in zwei Zahlen-Feldern (Latitude und Longitude) vorliegen. Leo hatte vor einiger Zeit mal diese Formel im Forum gepostet: 

let PI := 3.141592653589793;
let dL := longitude(Standort1) - longitude(Standort2);
let dB := latitude(Standort1) - latitude(Standort2);
let BL := sqrt(sqr(dL) + sqr(dB));
PI * 6371 * BL / 180

So richtig komme ich damit aber nicht weiter. Mal sehen, ob meine Verständnis bis hierher stimmt:

Standort1 ist das Zentrum für die aktuelle Berechnung - also der Kunde/Datensatz, den ich gerade aufgerufe. Standort2 sind dann die Kunden, die in der Ansicht angezeigt werden sollen. Die Formel oben muss ich dann also in ein neu anzulegendes Funktionsfeld (Spalte) in der Ansicht eingeben, richtig? 

So richtig weiß ich jetzt aber noch nicht, wie ich die jeweiligen Koordinaten in der Formel definieren soll. Gebe ich anstelle "longitude(Standort1)" -> "longitude(this)" ein, oder wie? Und wie definiere ich Standort2 für alle anderen Kunden?

Kann mir jemand auf die Sprünge helfen oder mein Verständnis der ganzen Problematik gerade rücken? :-)

Würde mich über Antworten und Lösungsansätze freuen.

13 Antworten

null
    • Martin_K
    • vor 5 Jahren
    • Gemeldet - anzeigen

    das ist die Formel für eine Numbers Tabelle

    ARCCOS(SIN(B1)×SIN(B3)+COS(B1)×COS(B3)×COS(B4−B2))×6367,4445

    b1-4  errechnen sich aus A1-4  in der jeweiligen Formel

    B1 = A1*PI/180

    B2 = A2*PI/180

    usw..

     

    Koordinaten Spalte A

    48,217090
    16,410415
    48,218704
    16,410955

    ergibt für Spalte B

    0,841547
    0,286416
    0,841575
    0,286425

    Ergibt für die Entfernung

    0,183771 = gerundet 184 

    ich hoffe du kannst das umsetzen.. 

    • Phil
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich habe mal eine Beispiel-Datenbank mit dem Namen "Luftlinie berechnen" ins Webinar DE Team gestellt.
    Ich denke, sie ist selbsterklärend. Aber sie funktioniert eben noch nicht richtig.

    Ich habe da die Formel von Leo genommen und sie ein bisschen angepasst (wahrscheinlich kaputt gemacht). Da ich das Ganze später eigentlicht nur in meiner Region benutzen will, würde mir auch eine Berechnung über den Satz des Pythagoras (mit der Entfernung eines Längengrades in meiner Region als Konstante) reichen. Wenn es aber über so eine universelle Formel genauer geht, wäre das natürlich auch ok und dann auch global für jeden anderen Benutzer und Szenario anwendbar.

    Kann da vielleicht mal jemand reingucken? Birger, Alex, Leo? :-)

    Im englischen Webinar von heute waren sich Alex und Birger nicht richtig einig, ob das ganze überhaupt funktioniert. Wenn, dann wäre es aber richtig cool!

    • Birger_H
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich verwende zum (vereinfachten) Berechnen der Luftline folgende einfache Formel:

    –––
    sqrt(sqr(latitute(Punkt1) - latitude(Punkt1)) + sqr(longitude(Punkt1) - longitude(Punkt2))) * 110
    –––

    Ich hoffe, deine Formel ist besser :-)

    Birger

    • Birger_H
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Sorry es heißt natürlich:

    –––
    sqrt(sqr(latitute(Punkt1) - latitude(Punkt2)) + sqr(longitude(Punkt1) - longitude(Punkt2))) * 110
    –––

    • Phil
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Danke Birger. Ich hab's nun auch mit dieser Formel probiert - leider immernoch ohne Erfolg. :-( Es passiert einfach überhaupt nichts. Im Formelfenster werden keine Fehler angezeigt und auch beim Aufrufen der Datensätze und beim Ändern der Umkreis-Variabel passiert einfach gar nix. Nicht mal eine Fehlermeldung.

    Ich glaube eigentlich, dass die Formeln an sich schon richtig sind, ich aber wahrscheinlich einen grundsätzlichen Denkfehler in meinem Datenbank-Aufbau habe. Ich habe nur eine Tabelle mit Orten und deren Koordinaten und ich möchte jeden einzelnen Datensatz zu allen anderen in der selber Tabelle in Relation setzen (Entfernung berechnen). Momentan habe ich es über das Ansicht-Element versucht. Ist das überhaupt der richtige Ansatz?

    Wie gesagt, die Datenbank liegt im Webinar DE 2019 Team unter dem Namen "Luftlinie berechnen". Würde mich freuen, wenn noch mal jemand rein gucken würde. Ich bin ein bisschen ratlos.

    Luftlinie berechnen und filtern

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    So kriegst du leider keine Ergebnisse.Die Tabellenansicht hat keine Ahnung, wo sie sich gerade befindet. D.h. du kannst auf die Koordinaten von Berlin in dieser Ansicht kann nicht greifen. Da muss man eine Zusatztabelle erstellen und die Entfernungen erstmals berechnen. Habe in deiner Datenbank einen Button Vorschlag Leo eingebaut.

    Leo

    • Phil
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ah ... riesiger Denkfehler also. :-) Vielen Dank, Leo.

    Dein Vorschlag scheint ja schon gut zu funktionieren. Deine Formel auf dem "Aktualisieren" Button mit "do as server" und "for" usw. verstehe ich aber überhaupt nicht. Was macht die Formel und der Button? Denn wenn ich den Wert in Umkreis2 ändere, filtert er ja schon in der Ansicht ohne dass ich den "Aktualisieren" Button drücke.

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Der Button aktualisiert die Tabelle Entfernungen. Wenn du neue Orte hinzufügst, müssen diese in der Tabelle auch berechnet werden. Der Button kann auch woanders platziert werden. 

    Falls du mit Cloud arbeitest werden Berechnungen für Button am Client durchgeführt und jedes Ergebnis in der Schleife einzeln am Server gespeichert.

    do as server berechnet die komplette Schleife direkt am Server und beschleunigt die Berechnungen. Bei 10-20 Datensätze ist es nicht so sichtbar. Bei mehreren tausend schon.

    Leo

    • Phil
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ah, ok. Dann habe ich den Button jetzt verstanden.

    Ich hab ca 2000 Datensätze und arbeite nur lokal auf dem Mac. Wird es da schwierig? Sollte man da was anders machen?Das werden dann ja 4 Mio Datensätze.

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Muss du prüfen. Kanst dann auch berichten ob 4 Mio Ninox in die Knie zwingen.

    LEo

    • Phil
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Erstmal vielen Dank, Leo. Mit deiner Hilfe funktioniert das Prinzip immerhin schon mal ganz gut.
    Ich hab das mal auf mein Kundensystem mit den ca. 2000 Kunden übertragen und dann den berüchtigten Button gedrückt und dabei die Apple Aktivitätsanzeige mitlaufen lassen.

     

    Nach ein paar Sekunden stand da bei Ninox schon das berühmte "reagiert nicht". Hab es trotzdem mal ca. eine Stunde so laufen lassen. CPU stand bei Ninox immer auf ca. 100% und der Ventilator lief wie ein Hubschrauber. Ich arbeite übrigens mit nem MacBook Pro von 2010.

     

    Ich hab Ninox dann irgendwann über "Programm sofort beenden" geschlossen. Als ich es dann wieder aufgemacht habe, waren immerhin gut 112000 Einträge in der Tabelle "Entfernungen". Ninox hat also für die ersten 55 Kunden die Entfernungen zu allen anderen Kunden berechnet. Knapp 3% also. :-) Keine Ahnung, ob diese 112000 Berechnungen in den ersten Sekunden erfolgt sind oder die ganze Zeit gedauert haben, bis ich Ninox gekillt habe. Es gibt ja keine Fortschrittsanzeige.

     

    Die 112000 stehen mir jetzt aber immerhin zur Verfügung und das Filtern mit derm Umkreis-Feld funktioniert prima. Ich hab übrigens doch die Formel nach dem Satz des Pythagoras genommen, weil mir die Erdkugel-Formel in der DB im Webinar Team immer sehr merkwürdige (falsche) Ergebnisse ausgespuckt hat. Und da ich sowieso nur hier in meiner Region (max. 2h Autofahrt) arbeite, reicht mir erstmal die Genauigkeit mit dem Satz des Pythagoras. 

     

    Meine Überlegung ist jetzt folgende: Ich brauche ja gar nicht alle 4 Mio Daten auf einmal. Es würde mir auch vollkommen ausreichen, wenn ich beim Aufruf eines Kunden einen Button drücken könnte (oder einen Trigger ausführt wird), der mir die Entfernung dieses einen Kunden zu den 2000 anderen Kunden berechnet und in die Tabelle "Entfernungen" schreibt ohne das irgendwas gelöscht wird. Diese Tabelle wächst dann sozusagen über die Zeit. Bloss wie könnte Formel für so einen Button aussehen?

     

    Ich hab übrigens die DB im Webinar Team mit meinen bisherigen Erkenntnisse verbessert und das alte falsche Zeug von mir gelöscht.

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Phil, 

    die Formel (für den Pythagoras Satz)wäre dann:

    ---

    let i := this;
    do as server
    delete Entfernungen;
    for j in (select Orte)[Id != i.Id] do
    let new := (create Entfernungen);
    new.(Ausgangsort := i);
    new.(Zielort := j);
    let PI := 3.141592653589793;
    let dL := 71 * (i.Longitude - j.Longitude);
    let dB := 111.3 * (i.Latitude - j.Latitude);
    new.(Entfernung := sqrt(dL * dL + dB * dB))
    end
    end

    ---

    habe in der Datenbank unten einen Button hinzugefügt

     

    Leo

    • IT-Manager
    • Thomas_Broich
    • vor 7 Monaten
    • Gemeldet - anzeigen

    Hallo,

    ich bin über diesen Beitrag gestolpert, weil ich für meinen Arbeitgeber ein Script benötigte, dass die Distanz zweier Airports anhand der Eingaben in den Standort-Feldern: "StandortStartFlughafen" und "StandortZielflughafen" ermitteln kann. Die Ergebnisse der hier beschriebenen Vorschläge waren sehr ungenau. Das folgende, zusammen mit ChatGPT, erarbeitete Script funktioniert jedoch einwandfrei:

    let R := 6371;
    let lat1 := latitude(StandortStartFlughafen);
    let lat2 := latitude(StandortZielflughafen);
    let lon1 := longitude(StandortStartFlughafen);
    let lon2 := longitude(StandortZielflughafen);
    let pi := 3.142;
    let phi1 := lat1 * pi / 180;
    let phi2 := lat2 * pi / 180;
    let deltaPhi := (lat2 - lat1) * pi / 180;
    let deltaLambda := (lon2 - lon1) * pi / 180;
    let a := sin(deltaPhi / 2) * sin(deltaPhi / 2) +
        cos(phi1) * cos(phi2) * sin(deltaLambda / 2) * sin(deltaLambda / 2);
    let c := 2 * atan2(sqrt(a), sqrt(1 - a));
    round(R * c)

    Auch wenn dieser Beitrag hier schon sehr alt ist, hilft es vllt. dennoch dem Einen oder Anderen.

Content aside

  • vor 7 MonatenZuletzt aktiv
  • 13Antworten
  • 4722Ansichten
  • 1 Folge bereits