Entwickler-Ecke
Sonstiges (Delphi) - Grosskreisberechnung / Geo-Distanz
BIOS-Crasher - Di 23.06.09 08:15
Titel: Grosskreisberechnung / Geo-Distanz
Hallo!
Ich habe mir ein kleines Programm geschrieben, welches mir die Entfernung zwischen 2 geographischen Koordinaten ausgibt. Ich benutze dazu die Grosskreisberechnung.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| function Tform1.CalcDist(BreitA: Double; LaengA: Double; BreitB: Double; LaengB: Double): Double; var d: Double; begin d := arccos(sin(BreitA)*sin(BreitB)+cos(BreitA)*cos(BreitB)*cos(LaengB-LaengA))*6378; Result := d; end; |
Nun gibt mir mein Programm jedoch falsche Angaben. Ich habe als Koordinaten 2 gegenüberliegende Punkte (Antipoden) genommen. Eigentlich müsste die Entfernung dem halben Erdradius sprich ca 20.000 km entsprechen. Mein Programm gibt jedoch 16.705,3700 aus, also knapp 4.000 km zu wenig. Kann mir jemand dabei helfen?
Moderiert von
Narses: Titel erweitert.
Lemmy - Di 23.06.09 09:13
hoi,
gib mal die Ausgangsdaten an, also die Koordinaten der beiden Punkte. Rechnest Du die Koordinaten auch um? 9° 12" <> 9,12°
Und hast Du daran gedacht, dass die Trig-Funktionen der Math auf RAD basieren, hier also auch nochmal umgerechnet werden muss?
Grüße
Lemmy
wunsiedler - Di 23.06.09 09:27
BIOS-Crasher hat folgendes geschrieben : |
| Eigentlich müsste die Entfernung dem halben Erdradius sprich ca 20.000 km entsprechen. |
Wenn das so wäre, müssten wir auf einer verdammt großen Kugel sitzen :shock:
Ich nehme an, Du sprichst vom Umfang...
Erdradius= 6370 KM
BIOS-Crasher - Di 23.06.09 18:14
Lemmy hat folgendes geschrieben : |
gib mal die Ausgangsdaten an, also die Koordinaten der beiden Punkte. Rechnest Du die Koordinaten auch um? 9° 12" <> 9,12°
Und hast Du daran gedacht, dass die Trig-Funktionen der Math auf RAD basieren, hier also auch nochmal umgerechnet werden muss? |
Ich glaubbe es ist das mit dem umwandelnn und nicht umwandeln (bin ich schon in der schule nich gut :P)
Meine Koordinatenn sind folgende:
• B1 = N50° 12’ 34.5 ’’ L1 = E08° 34’ 56.7’’
• B2 = S50° 12’ 34.5 ’’ L2 = W171° 25’ 3.3’’
und ich hab das ganze so eingegeben:
Delphi-Quelltext
1:
| Calcdist(50.1234,8.3456,-50.1234,-171.253) |
Hätte eventuell jemand den Codeschnipsel parat mit dem ich das ganze korrekt umrechne?
jfheins - Di 23.06.09 18:28
Eine Parserfunktion in Delphi hb ich jetzt nicht da, aber ich kann dir sagen, was du machen musst:
N50° 12’ 34.5"
Wird in Dezimalgrad zu: 50 + 12 / 60 + 34.5 / 3600 also rund 50,2096°
E08° 34’ 56.7" = 8,5824°
;)
BIOS-Crasher - Di 23.06.09 19:05
Hmm jetzt stehen wir bei 17204.662834632 km das sind noch immer ca 3000 km zu wenig ...
Narses - Di 23.06.09 20:45
Moin!
BIOS-Crasher hat folgendes geschrieben : |
| Hätte eventuell jemand den Codeschnipsel parat mit dem ich das ganze korrekt umrechne? |
In den beiden Links oben ist der Code dazu drin (gleich mehrere Verfahren)... keine Ahnung, warum du da nicht reinschaust... :nixweiss:
cu
Narses
jfheins - Di 23.06.09 21:05
Ich weis nicht, wie du auf den Wert kommst - deine Formel dürfte richtig sein:
| Zitat: |
d(BreitA, LaengA, BreitB, LaengB):=acos(sin(BreitA)*sin(BreitB)+cos(BreitA)*cos(BreitB)*cos(LaengB-LaengA))*6378;
==> d(BreitA,LaengA,BreitB,LaengB):=acos(sin(BreitA)*sin(BreitB)+cos(BreitA)*cos(BreitB)*cos(LaengB-LaengA))*6378
degtorad(x):=x*%pi/180;
==> degtorad(x):=(x*%pi)/180
d(degtorad(50.2096),degtorad(8.5824),degtorad(-50.2096),degtorad(-171.4176));
==> 20037.0779445957 |
BIOS-Crasher - Di 23.06.09 22:56
Wie ich jetzt feststelle hab ich 2 fehler gemacht 1. Erhalte ich andere werte beim umrechnen(kann jemand bitte die umrechnung in dezimalgrad für dummies erklären...?) 2. Hab ich vergessen in radiant umzurechnen :-*
jfheins - Di 23.06.09 23:29
Okay, da 2. ja schon gelöst ist:
Du hast eine Angabe in X° Y' Z" oder ausgesprochen X Grad, Y Minuten und Z Sekunden. Da die Sekunde (es geht hier nicht um Zeit, heißt trotzdem so oder "Bogensekunde") die kleinste Zeiteinheit ist, muss man - wenn man noch genauer sein will - diese als Kommazahl schrieben. Ähnlich wie "4 Minuten und 3,5 Sekunden" (Millisekunden mal außen vor gelassen)
Analog zu den Zeiteinheiten ist ein Grad in 60 Minuten unterteilt und eine Minute in 60 Sekunden.
Bei Dezimalgrad verzichtet man nun auf Minuten und Sekunden und nimmt stattdessen die Angabe von Grad mit Dezimalstellen hinterm Komma.
Da ein Grad in 60 Minuten unterteilt ist, entspricht eine Minute 1/60 Grad. Wenn wir also eine Angabe haben wie 5° 59' entspricht das 5° + 59 / 60 = 5,98333333...°
Eine Minute wiederrum ist unterteilt in 60 Sekunden. also 5° 59' 58" entspricht 5 + (59 + 58/60) / 60 = 5 + 59/90 + 58/3600 = 5,9994444444...°
Zusammenfassend: X° Y' Z" [Grad,Minuten,Sekunden] = X + Y/60 + Z/3600 [Dezimalgrad] ;)
Siehe auch:
http://de.wikipedia.org/wiki/Bogensekunde ;)
BIOS-Crasher - Mi 24.06.09 21:33
Ich hab jetzt herausgefunden, dass in meiner umrechnung der fehler liegt, obwohl ich genau so umrechne wie beschrieben... Ich poste morgen den quelltext, momentan ist auf meinem arbeits-pc kein internet verfügbar
BIOS-Crasher - Do 25.06.09 18:10
So hier ist der vollständige quelltext:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| unit Main;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Math, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; function CalcDist(BreitA: Double; LaengA: Double; BreitB: Double; LaengB: Double):Double; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm} function Tform1.CalcDist(BreitA: Double; LaengA: Double; BreitB: Double; LaengB: Double):Double; var d: Double; begin d := arccos(sin(BreitA)*sin(BreitB)+cos(BreitA)*cos(BreitB)*cos(LaengB-LaengA))*6378; Result := d; end;
procedure TForm1.Button1Click(Sender: TObject); var dBreita,dBreitb,dLaengA,dLaengB: Double; begin dBreita := 50+ 12/60+34.5/3600; dbreitb := 8+ 34/60 + 56.7/3600; dlaenga := -50+ 12/60 + 34.5/3600; dlaengb := -171+ 25/60 + 3.3/3600; Label1.Caption:= FloatToStr(Calcdist(degtorad(dBreitA),degtorad(dLaengA),degtorad(dBreitB),degtorad(LaengB))); end;
end. |
jfheins - Do 25.06.09 18:40
Du rechnest falsch um und vertauschst dbreitb und dlaenga ;)
Konket: Das Minuszeichen muss vor alles, nicht nur vor die Gradzahl
Probiers mal so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| unit Main;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Math, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; function CalcDist(BreitA: Double; LaengA: Double; BreitB: Double; LaengB: Double):Double; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm} function Tform1.CalcDist(BreitA: Double; LaengA: Double; BreitB: Double; LaengB: Double):Double; var d: Double; begin d := arccos(sin(BreitA)*sin(BreitB)+cos(BreitA)*cos(BreitB)*cos(LaengB-LaengA))*6378; Result := d; end;
function DMS_to_DD(deg, min, sec: Double) : Double; begin Result := sign(deg) * (abs(deg) + min / 60 + sec / 3600)); end;
procedure TForm1.Button1Click(Sender: TObject); var dBreita,dBreitb,dLaengA,dLaengB: Double; begin dBreita := DMS_to_DD(50, 12, 34.5); dlaenga := DMS_to_DD(8, 34, 56.7); dbreitb := DMS_to_DD(-50, 12, 34.5); dlaengb := DMS_to_DD(-171, 25, 3.3); Label1.Caption:= FloatToStr(Calcdist(degtorad(dBreitA),degtorad(dLaengA),degtorad(dBreitB),degtorad(LaengB))); end;
end. |
Muck - Do 25.06.09 21:26
Hallo zusammen,
mein Web Server TrackDollar.com berechnet die Enternung wie folgt:
Quelltext
1: 2: 3: 4: 5:
| Function Entfernung(sb,sl,zb,zl:Double):Double; begin Result:=arccos(sin(degtorad(sb))*sin(degtorad(zb))+ cos(degtorad(sb))*cos(degtorad(zb))*cos(degtorad(sl-zl)))*6378; end; |
Funktioniert rennt bis jetzt tadellos.
Aufruf Start Altitude,Longitude und Ziel Altitude,Longitude
also von meinem Haus in San Antonio, Texas nach Berlin waeren dann:
Quelltext
1:
| Entfernung(-98.499224,29.664668,13.4,52.5) |
cu
Markus
BIOS-Crasher - Fr 26.06.09 16:35
jfheins hat folgendes geschrieben : |
Du rechnest falsch um und vertauschst dbreitb und dlaenga ;)
Konkret: Das Minuszeichen muss vor alles, nicht nur vor die Gradzahl
|
Siehst du wegen solch einfachen Fehlern funktionierte es nicht... ich sollte mir ehrlich mal überlegen ob ich wirklich Informatik studieren soll ;)
Aya - Fr 26.06.09 19:04
Hi,
da ich das sowieso schon immer mal machen wollte hab ich das ganze eben auch mal nachgebastelt und mir im zuge dessen nen parser geschrieben um die Zeitangaben wie N50° 22'34.566" in Latitude und Longitude umzuwandeln..
Was ich mich jetzt frage, gibt es ne gescheite Möglichkeit das ganze aus Latitude wieder zurückzurechnen...?
Das ist ja dann eine Formel mit 3 unbekannten, wobei 2 davon nur zwischen 0 und 60 liegen können.. das übersteigt dann mein Mathematisches wissen doch ein wenig... weiß da jemand was? :)
Aya~
Kha - Fr 26.06.09 19:25
Trunc(x) sind die ganzen Grad, Trunc(x * 60) mod 60 die Bogenminuten, der Rest mal 3600 (oder FloatMod(x * 3600, 60)) die Bogensekunden :) ...
Aya - Fr 26.06.09 19:27
Hat sich erledigt.. hab's hinbekommen, war doch leichter als ich erst dachte..:)
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| float x = .. float d = floorf(x); x = (x - d) * 60.0f; float m = floorf(x); float s = (x - m) * 60.0f;
|
Aya~
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!