Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   GEO - Functions (https://www.delphipraxis.net/132774-geo-functions.html)

robinWie 19. Apr 2009 13:00


GEO - Functions
 
Hallo,
ich hab eine kleine Funktionssammlung geschrieben mit der man einige Dinge anhand von Koordniaten auf der Erde berechnen kann.
Inhalte in der Sammlung
  • Konstanten
    • Erdbeschleunigung
    • Norm-Luftdruck
  • Funktionen zum Umwandeln von Längen-/Breitengraden-Formaten (z.B. 5°45'13"N zu 5,7539° und umgekehrt)
  • Funktionen zum Umrechnen von Gängigen-Einheiten
    • Geschwindigkeiten [knoten -> km/h,...]
    • Längen, Strecken [Seemeilen -> kilometer,...]
    • Drücken [Pascal -> Bar,...]
    • Temperaturen [Kelvin, Celsius, Fahrenheit]
  • Berechnung von Entfernungen zwischen 2 Koordinaten
  • Berechnung von Kursen von Koordinate 1 -> Koordinate 2

Wollts euch nich vorenthalten, vielleicht kanns ja einer brauchen ;)

Wenn ihr noch irgendwelche weiteren Funktionen oder anderes habt was eurer Meinung da reingehört könnt ihrs ja implementieren und hier Posten ;)

Hier is das gute Stück^^
Delphi-Quellcode:
//_.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._//
//                                                                                 //
//                            //   ) ) //   / /  //   ) )                        //
//                           //        //____    //   / /                          //
//                          //  ____  / ____    //   / /                           //
//                         //    / / //        //   / /                            //
//                        ((____/ / //____/ / ((___/ /                             //
//                                                                                 //
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM//
//MMMMMMMMMMMMWMMMMMMMMM#"7""WMMMMMMMM:     ?"?       ...  ...+g&.7T"""TMMMMMMMMM//
//Mk!JMMMNNggNQXmWMNMMMM"9M#Y ?MMMY""...    .gMMNZJ..+gggNdMMMMMMMMMMMMMMMMMMNNaNM//
//   ?"9??7"TMMMNNMHMa, MN.,  ?        . .9W%.aNNMMMMMMMMMMMMMMMMMMMMMMM"""1.??` //
//           .TMMMMMMM#MNMMN"C.        `.QdMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM?  .    //
//            JMMMMMMMNNN#=            .Nf!.7?#4JgJMpvMMMMNMMMMMMMMMBWF` ;       //
//              TMMMMMWHY           `  .MMMNg.&..JMMMMMMMMMMMNMMMMMMb !`         //
//    `          `?Mb . ... `  `     .MMMMMMMMMMMbWMMgp``WMMM9HMM##"?             //
//                  .?"P ..     `  `.MMMMMMMMMMMMm#5`    UF  JUN ..       `   //
//                       MMMMNg.       7""?YMMMMMMMM%      .  Jn ..`.           //
//         `            JMMMMMMMNg,        .HMMMNMF            ?i?=?  ?4g,.     //
//            `          TMMMMMMM#`          .MMMMMF .               ..g...  `  `//
//   `  `        `    `   .MMMMM"^   `  `    ,MMMM% J%              .NMMMMMN,     //
//         `              JMMM#'             ?MM=                 JM#"YMMM#      //
//                  `     MM"'       `                  `                ?1     ,^//
//      `     `  `      `.M=       `    `                   `                     //
//   `                           `  `                           `                  //
//         `          `  ..J#!           .............gg....JgggMMagggggNggJ..... //
//.......&gNgMMNNMNMMMMNMMMMN&.......NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMmJ.//
//NMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM//
//                                                                                 //
//       //   / /                                                                  //
//      //___             __      ___    __  ___ ( ) ___       __      ___        //
//     / ___  //   / / //   ) ) //   ) ) / /   / / //   ) ) //   ) ) ((   ) )    //
//    //     //   / / //   / / //        / /   / / //   / / //   / /   \ \         //
//   //     ((___( ( //   / / ((____    / /   / / ((___/ / //   / / //   ) )      //
//                                                                                 //
//             ASCII-Font by [url]http://www.network-science.de/ascii/[/url]                 //
//                   ASCII-Art by JavE [url]http://www.jave.de/[/url]                        //
//                                                                                 //
//                                                                                 //
//                                                                                 //
//                                                                                 //
//Konvertierungs Funktionen                                                       //
//=================================================================================//
//Diese Funktionen wandeln Längen- und Breitengrade von der Standartangabe        //
//(Grad, Minute, Sekunden...) in ein, zum Rechnen verwendbares, Format um         //
//---------------------------------------------------------------------------------//
//                                                                                 //
//DecimalLon     Wandelt einen Breitengrad in einen Dezimalgrad um. Unterstüzt   //
//                werden die Formate (d steht für die Hämisphäre)                 //
//                  x°dx'x" Beispiel: 47°N45'23"                                  //
//                  x°x'x"d Beispiel: 47°45'23"N                                  //
//                                                                                 //
//                  x°d x' x" Beispiel: 47°N 45' 23"                             //
//                  x° x' x" d Beispiel: 47° 45' 23" N                            //
//                Gibt bei Leeren Parameter -181 aus                              //
//                                                                                 //
//DecimalLat     Wandelt einen Längengrad in einen Dezimalgrad um.               //
//                Wie DecimalLon                                                  //
//                Gibt bei Leeren Parameter -91 aus                               //
//                                                                                 //
//Longitude      Wandelt einen Dezimalgrad in einen Längengrad um.               //
//                (Grad < 0 = West; Grad >=0 Ost                                  //
//                Parameter:                                                      //
//                |-> Digits      Gibt an auf wie viele Nachkommastellen die     //
//                |                Sekunden gerundet werden sollen.               //
//                |-> EastShort   Gibt an wie die Himmelsrichtung "Ost"          //
//                                 Abgekürzt werden soll (deutsch mit "O" oder    //
//                                 Englisch mit "E"). Standart ist "O"            //
//                                                                                 //
//Latitude       Wandelt einen Dezimalgrad in einen Breitengrad um.              //
//                (Grad < 0 = Nord; Grad >=0 Süd                                  //
//                Parameter:                                                      //
//                |-> Digits     Gibt an auf wie viele Nachkommastellen die      //
//                                Sekunden gerundet werden sollen.                //
//                                                                                 //
//                                                                                 //
//Umrechungs Funktion für Einheiten                                               //
//=================================================================================//
//                                                                                 //
//Geschwindigkeiten                                                               //
//---------------------------------------------------------------------------------//
//Knots2Kmph     Wandelt Knoten in Kilometer / Stunde um                         //
//Kmph2Knots     Wandelt Kilometer / Stunde in Knoten um                         //
//Kmph2mps       Wandelt km/h in m/s um                                          //
//mps2kmph       Wandelt m/s in km/h um                                          //
//                                                                                 //
//Längen / Strecken / Entfernungen                                                //
//---------------------------------------------------------------------------------//
//sm2km          Wandelt Seemeilen zu Kilometern um                              //
//km2sm          Wandelt Kilometer zu Seemeilen um                               //
//m2km           Wandelt Meter in Kilometer um                                   //
//km2m           Wandelt Kilometer in Meter um                                   //
//inch2cm        Wandelt Inch (Zoll) in Zentimeter um                            //
//cm2inch        Wandelt Zentimeter in Inch (Zoll) um                            //
//                                                                                 //
//Drücke                                                                          //
//---------------------------------------------------------------------------------//
//psi2pa         Wandelt PSI (Poundforce per SquareInch) in Pa (Pascal) um       //
//pa2psi         Wandelt Pa (Pascal) in PSI (Poundforce per SquareInch) um       //
//pa2bar         Wandelt Pa (Pascal) in bar um                                   //
//bar2pa         Wandelt bar in Pa (Pascal) um                                   //
//torr2pa        Wandelt Torr [mmHg] in Pascal [Pa] um                           //
//pa2torr        Wandelt Pascal [Pa] in Torr [mmHg] um                           //
//                                                                                 //
//Temperaturen                                                                    //
//---------------------------------------------------------------------------------//
//Kelvin2Celsius     Wandelt Kelvin in Grad Celsius um                           //
//Celsius2Kelvin     Wandelt Grad Celsius in Kelvin um                           //
//Fahrenheit2Celsius Wandelt Grad Fahrenheit in Grad Celsius um                  //
//Celsius2Fahrenheit Wandelt Grad Celsius in Grad Fahrenheit um                  //
//                                                                                 //
//                                                                                 //
//Berechungs Funktionen                                                           //
//=================================================================================//
//Diese Funktionen erwarten bei den Koordinaten alle einen Dezimalen Grad!         //
// -> Breite: negative Zahlen = Süd; positive Zahlen = Nord                      //
// -> Länge: negative Zahlen = West; positive Zahlen = Ost                       //
//---------------------------------------------------------------------------------//
//                                                                                 //
//SimpleDistance Rechnet die Entfernung zwischen 2 Koordinaten aus [Meter]       //
//                                                                                 //
//Distance       Rechnet die Entfernung zwischen 2 Koordinaten, unter            //
//                berücksichtigung Der Krümmung aus (+/- 50m) [Meter]. Genauer    //
//                als SimpleDistance.                                             //
//                                                                                 //
//                Die Einheit der Funktion ist die gleiche, in der der Radius     //
//                (Planet_r) angegeben wurde.                                     //
//                Mehr zur Berechnung sihe:                                       //
//                -> [url]http://de.wikipedia.org/wiki/Orthodrome[/url]                      //
//                                                                                 //
//AlphaCurse     Errechnet den Abfahrts-Kurs von Koord. 1 zu Koord. 2 in Grad    //
//                Wenn Koord. 1 = Koord. 2 ist, wird der Wert -1 ausgegeben       //
//                                                                                 //
//BetaCurse      Errechnet den Ankufts-Kurs von Koord. 1 zu Korrd. 2 in Grad     //
//                Wenn Koord. 1 = Koord. 2 ist, wird der Wert -1 ausgegeben       //
//                                                                                 //
//                Siehe Auch                                                      //
//                 -> [url]http://rainerstumpe.de/HTML/navigation.html[/url]                 //
//                                                                                 //
//CurseToStr     Wandelt einen Kurs von ° in eine Himmelsrichtung um. 16          //
//                Unterteilungen. Parameter LongString bestimmt ob die Richtung   //
//                abgekürzt (False) oder ausgeschrieben (True) ausgegeben wird.   //
//                                                                                 //
//_.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._//

unit GEO_Functions;

interface

uses Math, SysUtils;

const
      Normluftdruck: integer = 101300; // Normluftdruck in Pascal [Pa]
      ErdBeschleunigung: single = 9.81; // Erdbeschleunigung in m/s^2

//  Konstanten aus dem WGS84 (World Geodetic System 1984)
//    WGS84_w: Extended = 7.292115 * Power(10,-5); // Rotationsgeschwindigkeit in rad/s
//    WGS84_wD: Extended = RadToDeg(7.292115 * Power(10,-5)); // Rotationsgeschwindigkeit in °/s
//   f-Wert für die Distance Funktion
      WGS84_f: Extended = 1/298.257223563; // Abplattung
//   a-Wert für die Distance Funktion
      WGS84_a: Extended = 6378137;        // Radius in Meter

var
  // Planet_f: Planetenabflachung. Wird für die Funktion "Distance" benötigt
  Planet_f: Extended = 1/298.257223563;
  // Planet_r: Planetenradius. Wird für die Distance Funktionen benötigt
  Planet_r: Extended = 6378137; // in Meter

// Umwandlen von Winkeln
function DecimalLon(Longitude: string): Single;
function DecimalLat(Latitude: string): Single;
function Longitude(DecimalLongitude: Extended; EastShort: string = 'O'; Digits: integer = 4): string;
function Latitude(DecimalLatitude: Extended; Digits: integer = 4): string;

// Umwandeln von Geschwindigkeiten
function Knots2Kmph(Kn: Extended): Extended;
function Kmph2Knots(Kmph: Extended): Extended;
function Kmph2mps(Kmph: Extended): Extended;
function mps2Kmph(mps: Extended): Extended;

// Umwandeln von Entfernungen
function sm2km(sm: Extended): Extended;
function km2sm(km: Extended): Extended;
function m2km(m: Extended): Extended;
function km2m(km: Extended): Extended;
function inch2cm(inch: Extended): Extended;
function cm2inch(cm: Extended): Extended;

// Umwandeln von Drücken
function psi2pa(psi: Extended): Extended;
function pa2psi(pa: Extended): Extended;
function bar2pa(bar: Extended): Extended;
function pa2bar(pa: Extended): Extended;
function torr2pa(torr: Extended): Extended;
function pa2torr(pa: Extended): Extended;

// Umwandeln von Temperaturen
function Celsius2Kelvin(Celsius: Extended): Extended;
function Kelvin2Celsius(Kelvin: Extended): Extended;
function Celsius2Fahrenheit(Celsius: Extended): Extended;
function Fahrenheit2Celsius(Fahrenheit: Extended): Extended;

// Berechnungen mit Koordinaten
function SimpleDistance(Lat1, Lat2, Lon1, Lon2: Extended): Extended;
function Distance(Lat1,Lat2,Lon1,Lon2: Extended): Extended;
function AlphaCurse(Lat1, Lat2, Lon1, Lon2: Extended): single;
function BetaCurse(Lat1, Lat2, Lon1, Lon2: Extended): single;
function CurseToStr(Curse: single; LongString: Boolean = False): string;

implementation

//==============================================================================//
//                        Konvertierungsfunktionen                             //
//==============================================================================//

function DecimalLon(Longitude: string): Single;
var
 sGrad: string;
 sMinute: string;
 sSekunde: string;

 i: integer;

 Grad: Extended;
 Minute: Extended;
 Sekunde: Extended;
begin
  if Longitude = '' then
   begin
     Result := - 181;
     Exit;
   end;

  Longitude := UpperCase(Longitude);

  if (Pos('°W', Longitude) > 0) or (Longitude[length(Longitude)] = 'W') then
   Longitude := '-' + Longitude;

  Longitude := StringReplace(Longitude, '°W', '°', [rfReplaceAll, rfIgnoreCase]);
  Longitude := StringReplace(Longitude, '°O', '°', [rfReplaceAll, rfIgnoreCase]);
  Longitude := StringReplace(Longitude, '°E', '°', [rfReplaceAll, rfIgnoreCase]);

  if (Longitude[length(longitude)] = 'O') or
     (Longitude[length(longitude)] = 'W') or
     (Longitude[length(longitude)] = 'E') then
    Delete(Longitude, length(Longitude), 1);

  // Entferne Leerzeichen aus dem String
  i := 1;
  while i < Length(Longitude) do
    begin
      if Longitude[i] = ' ' then
        Delete(Longitude, i, 1);
      Inc(i);
    end;

  // Splitte String
  sGrad := Copy(Longitude, 1, Pos('°', Longitude) -1);
  Delete(Longitude, 1, Pos('°', Longitude));

  sMinute := Copy(Longitude, 1, Pos(#39, Longitude) -1);
  Delete(Longitude, 1, Pos(#39, Longitude));

  sSekunde := Copy(Longitude, 1, Pos('"', Longitude) -1);
  Delete(Longitude, 1, Pos('"', Longitude));

  Grad := StrToFloat(sGrad);
  Minute := StrToFloat(sMinute);
  Sekunde := StrToFLoat(sSekunde);

  Result := Grad + Minute / 60 + Sekunde / 3600;
end;

function DecimalLat(Latitude: string): Single;
var
 sGrad: string;
 sMinute: string;
 sSekunde: string;

 i: integer;

 Grad: Extended;
 Minute: Extended;
 Sekunde: Extended;
begin
  if Latitude = '' then
   begin
    Result := - 91;
    Exit;
   end;

  UpperCase(Latitude);

  if (Pos('°S', Latitude) > 0) or (Latitude[length(Latitude)] = 'S') then
   Latitude := '-' + Latitude;

  Latitude := StringReplace(Latitude, '°N', '°', [rfReplaceAll, rfIgnoreCase]);
  Latitude := StringReplace(Latitude, '°S', '°', [rfReplaceAll, rfIgnoreCase]);

  if (Latitude[length(Latitude)] = 'S') or (Latitude[length(Latitude)] = 'N') then
    Delete(Latitude, length(Latitude), 1);

  // Entferne Leerzeichen aus dem String
  i := 1;
  while i < Length(Latitude) do
    begin
      if Latitude[i] = ' ' then
        Delete(Latitude, i, 1);
      Inc(i);
    end;

  // Splitte String
  sGrad := Copy(Latitude, 1, Pos('°', Latitude) -1);
  Delete(Latitude, 1, Pos('°', Latitude));

  sMinute := Copy(Latitude, 1, Pos(#39, Latitude) -1);
  Delete(Latitude, 1, Pos(#39, Latitude));

  sSekunde := Copy(Latitude, 1, Pos('"', Latitude) -1);
  Delete(Latitude, 1, Pos('"', Latitude));

  Grad := StrToFloat(sGrad);
  Minute := StrToFloat(sMinute);
  Sekunde := StrToFLoat(sSekunde);

  Result := Grad + Minute / 60 + Sekunde / 3600;
end;

function Longitude(DecimalLongitude: Extended; EastShort: string = 'O'; Digits: integer = 4): string;
var
 Grad: Extended;
 Minute: Extended;
 Sekunde: Extended;
 sGrad: string;
 sMinute: string;
 sSekunde: string;
 Direction: string;
begin
  if DecimalLongitude < 0 then
    Direction := 'W'
  else
    Direction := EastShort;

  DecimalLongitude := abs(DecimalLongitude);

  Grad            := Int(DecimalLongitude);
  DecimalLongitude := Frac(DecimalLongitude);
  Minute          := Int(60 * DecimalLongitude);
  Sekunde         := Frac(60 * DecimalLongitude) * 60;

  sGrad   := FloatToStr(Grad)   + '°';
  sMinute := FloatToStr(Minute) + #39;
  sSekunde := FloatToStrF(Sekunde, ffNumber, 9, Digits) + '"';

  Result := sGrad + ' ' + sMinute + ' ' + sSekunde + ' ' + Direction;
end;

function Latitude(DecimalLatitude: Extended; Digits: integer = 4): string;
var
 Grad: Extended;
 Minute: Extended;
 Sekunde: Extended;
 sGrad: string;
 sMinute: string;
 sSekunde: string;
 Direction: string;
begin
  if DecimalLatitude < 0 then
    Direction := 'S'
  else
    Direction := 'N';

  DecimalLatitude := abs(DecimalLatitude);

  Grad            := Int(DecimalLatitude);
  DecimalLatitude := Frac(DecimalLatitude);
  Minute          := Int(60 * DecimalLatitude);
  Sekunde         := Frac(60 * DecimalLatitude) * 60;

  sGrad   := FloatToStr(Grad)   + '°';
  sMinute := FloatToStr(Minute) + #39;
  sSekunde := FloatToStrF(Sekunde, ffNumber, 9, Digits) + '"';

  Result := sGrad + ' ' + sMinute + ' ' + sSekunde + ' ' + Direction;
end;

//==============================================================================//
//                    Umrechungsfunktion für Einheiten                         //
//==============================================================================//

// Umwandlung von Geschwindigkeiten

function Knots2Kmph(Kn: Extended): Extended;
begin
  Result := Kn * 1.852;
end;

function Kmph2Knots(Kmph: Extended): Extended;
begin
  Result := Kmph / 1.852;
end;

function Kmph2mps(Kmph: Extended): Extended;
begin
  Result := Kmph / 3.6;
end;

function mps2Kmph(mps: Extended): Extended;
begin
  Result := mps * 3.6;
end;

// Umwandlung von Längen

function sm2km(sm: Extended): Extended;
begin
  Result := 1.852 * sm;
end;

function km2sm(km: Extended): Extended;
begin
  Result := km / 1.852;
end;

function m2km(m: Extended): Extended;
begin
  Result := m / 1000;
end;

function km2m(km: Extended): Extended;
begin
  Result := km * 1000;
end;

function inch2cm(inch: Extended): Extended;
begin
  Result := inch * 2.54;
end;

function cm2inch(cm: Extended): Extended;
begin
  Result := cm / 2.54;
end;

// Umwandeln von Drücken

function psi2pa(psi: Extended): Extended;
begin
  Result := psi * 6894.757293168;
end;

function pa2psi(pa: Extended): Extended;
begin
  Result := pa / 6894.757293168;
end;

function bar2pa(bar: Extended): Extended;
begin
  Result := bar * 100000;
end;

function pa2bar(pa: Extended): Extended;
begin
  Result := pa / 100000;
end;

function torr2pa(torr: Extended): Extended;
begin
  Result := torr * (101325/760);
end;

function pa2torr(pa: Extended): Extended;
begin
  Result := Pa / (101325/760);
end;

// Umwandlung von Temperaturen

function Celsius2Kelvin(Celsius: Extended): Extended;
begin
  Result := Celsius + 273.15;
end;

function Kelvin2Celsius(Kelvin: Extended): Extended;
begin
  Result := Kelvin - 273.15;
end;

function Celsius2Fahrenheit(Celsius: Extended): Extended;
begin
  Result := Celsius * 1.8 + 32;
end;

function Fahrenheit2Celsius(Fahrenheit: Extended): Extended;
begin
  Result := (Fahrenheit - 32) * (5/9)
end;

function SimpleDistance(Lat1, Lat2, Lon1, Lon2: Extended): Extended;
begin
  Result := Planet_r * ArcCos(Sin(DegToRad(Lat1))*Sin(DegToRad(Lat2))+Cos(DegToRad(Lat1))*Cos(DegToRad(Lat2))*Cos(DegToRad(Lon1-Lon2)));
end;

//==============================================================================//
//                         Berechungs Funktionen                               //
//==============================================================================//

function Distance(Lat1, Lat2, Lon1, Lon2: Extended): Extended;
var
  F: Extended;
  G: Extended;
  l: Extended;
  D: Extended;
  S: Extended;
  C: Extended;
  H_1: Extended;
  H_2: Extended;
  R: Extended;
  w: Extended;
begin
  F := (lat1+lat2) / 2;
  G := (lat1-lat2) / 2;
  l := (lon1-lon2) / 2;

  // Umrechung ins Bogenmaß
  F := DegToRad(F);
  G := DegToRad(G);
  l := DegToRad(l);

  // Grober Abstand D
  //    (sin G)^2       *     (cos l)^2     +   (cos F)^2   +   (sin l)^2
  S := Power(sin(G), 2) * Power(cos(l),2) + Power(cos(F),2) * Power(sin(l), 2);
  C := Power(cos(G), 2) * Power(cos(l),2) + Power(sin(F),2) * Power(sin(l), 2);

  w := ArcTan(SQRT(S/C));
  D := 2*w*Planet_r;

  // Korriktur Maße H1&H2
  R  := SQRT(S*C)/w;
  H_1 := (3*R-1)/(2*C);
  H_2 := (3*R+1)/(2*S);

  // Berechnung des Abstands s (Stat s wird Result verwendet)
  Result := D*(1+Planet_f*H_1*Power(sin(F),2)*Power(cos(G),2) - Planet_f*H_2*Power(cos(F),2)*Power(sin(G),2));
end;

function AlphaCurse(Lat1, Lat2, Lon1, Lon2: Extended): single;
var
 c: Single;
 Lt1,Lt2,Lo1,Lo2: Extended;
 a: single;
begin
  // Umrechnung ins Bogemaß
  Lt1 := DegToRad(Lat1);
  Lt2 := DegToRad(Lat2);
  Lo1 := DegToRad(Lon1);
  Lo2 := DegToRad(Lon2);

  // Winkel für A -> B (West -> Ost Richtung)
  if (Lo2 - Lo1) > 0 then
    begin
      c := sin(Lt1) * sin(Lt2) + cos(Lt1) * cos(Lt2) * cos(Lo1 - Lo2);
      c := arccos(c);

      a := (sin(Lt2) - sin(Lt1) * cos(c)) / (cos(Lt1) * sin(c));
      a := arccos(a);

      Result := RadToDeg(a);
    end else

  // Winkel für B <- A (Ost -> West Richtung)
  if (Lo2 - Lo1) < 0 then
    begin
      c := sin(Lt1) * sin(Lt2) + cos(Lt1) * cos(Lt2) * cos(Lo1 - Lo2);
      c := arccos(c);

      a := (sin(Lt2) - sin(Lt1) * cos(c)) / (cos(Lt1) * sin(c));
      a := arccos(a);

      Result := 360 - RadToDeg(a);
    end else

  // Winkel bei einfacher Nord/Süd bewegng
  if (Lo2 - Lo1) = 0 then
    begin
      // Süd -> Nord
      if (Lt2 - Lt1) > 0 then
        Result := 0 else
      // Nord -> Süd
      if (Lt2 - Lt1) < 0 then
        Result := 180 else

      // Keine Bewegung
      if (Lt2 - Lt1) = 0 then
        Result := -1;
    end;
end;

function BetaCurse(Lat1, Lat2, Lon1, Lon2: Extended): single;
var
 c: Single;
 Lt1,Lt2,Lo1,Lo2: Extended;
 b: single;
begin
  // Umrechnung ins Bogemaß
  Lt1 := DegToRad(Lat1);
  Lt2 := DegToRad(Lat2);
  Lo1 := DegToRad(Lon1);
  Lo2 := DegToRad(Lon2);

  // Winkel für A -> B (West -> Ost Richtung)
  if (Lo2 - Lo1) > 0 then
    begin
      c := sin(Lt1) * sin(Lt2) + cos(Lt1) * cos(Lt2) * cos(Lo1 - Lo2);
      c := arccos(c);

      b := (sin(Lt1) - sin(Lt2) * cos(c)) / (cos(Lt2) * sin(c));
      b := arccos(b);

      Result := RadToDeg(b);
    end else

  // Winkel für B <- A (Ost -> West Richtung)
  if (Lo2 - Lo1) < 0 then
    begin
      c := sin(Lt1) * sin(Lt2) + cos(Lt1) * cos(Lt2) * cos(Lo1 - Lo2);
      c := arccos(c);

      b := (sin(Lt1) - sin(Lt2) * cos(c)) / (cos(Lt2) * sin(c));
      b := arccos(b);

      Result := 360 - RadToDeg(b);
    end else

  // Winkel bei einfacher Nord/Süd bewegng
  if (Lo2 - Lo1) = 0 then
    begin
      // Süd -> Nord
      if (Lt2 - Lt1) > 0 then
        Result := 0 else
      // Nord -> Süd
      if (Lt2 - Lt1) < 0 then
        Result := 180 else

      // Keine Bewegung
      if (Lt2 - Lt1) = 0 then
        Result := -1;
    end;
end;

function CurseToStr(Curse: single; LongString: Boolean = False): string;
var c: integer;
begin
  c := Round(Curse * 10000);
  if not LongString then
    begin
     case c of
      3487510..3600000: Result := 'N';
      0..112500:        Result := 'N';
      112510..337500:   Result := 'NNO';
      337510..562500:   Result := 'NO';
      562510..787500:   Result := 'NOO';
      787510..1012500:  Result := 'O';
      1012510..1237500: Result := 'SOO';
      1237510..1462500: Result := 'SO';
      1462510..1687500: Result := 'SSO';
      1687510..1912500: Result := 'S';
      1912510..2137500: Result := 'SSW';
      2137510..2362500: Result := 'SW';
      2362510..2587500: Result := 'SWW';
      2587510..2812500: Result := 'W';
      2812510..3037500: Result := 'NWW';
      3037510..3262500: Result := 'NW';
      3262510..3487500: Result := 'NNW';
     end;
    end else begin
      case c of
      3487510..3600000: Result := 'Norden';
      0..112500:        Result := 'Norden';
      112510..337500:   Result := 'Nord Nord Ost';
      337510..562500:   Result := 'Nord Ost';
      562510..787500:   Result := 'Nord Ost Ost';
      787510..1012500:  Result := 'Osten';
      1012510..1237500: Result := 'Süd Ost Ost';
      1237510..1462500: Result := 'Süd Ost';
      1462510..1687500: Result := 'Süd Süd Ost';
      1687510..1912500: Result := 'Süd';
      1912510..2137500: Result := 'Süd Süd West';
      2137510..2362500: Result := 'Süd West';
      2362510..2587500: Result := 'Süd West West';
      2587510..2812500: Result := 'Westen';
      2812510..3037500: Result := 'Nord West West';
      3037510..3262500: Result := 'Nord West';
      3262510..3487500: Result := 'Nord Nord West';
     end;
    end;
end;


end.
mfg
Robin

jfheins 19. Apr 2009 13:10

Re: GEO - Functions
 
Es ist zwar egal, da die Konstante nicht verwendet wird, aber:
Zitat:

Normluftdruck: integer = 1013; // Normluftdruck in Pascal [Pa]
1013 ist nicht der Normluftdruck in Pascal ;)

Der Normluftdruck ist 1013 hektoPascal also 101300 Pascal ;)

himitsu 19. Apr 2009 13:15

Re: GEO - Functions
 
Eine kleine Fehlerbehandlung wäre nicht schlecht, wenn man mal einen Leerstring übergibt.

z.B. bei DecimalLat('') bekomm ich mit Sicherheit eine nette Exception
(und nein, ich hab's jetzt nicht getestet ... ich weiß es so :angel: )

Und bei CurseToStr könntest du statt der vielen IF ein schönes CASE verwenden, indem du den Winkel z.B. mit 100 multiplizierst und dann noch etwas rundest.

robinWie 19. Apr 2009 14:11

Re: GEO - Functions
 
danke für die hinweise. Ich habs geändert ;)

wurzelzwerg 11. Aug 2012 12:41

AW: GEO - Functions
 
Super!:thumb:

Wie würde man einer Koordinate x Meter addieren/subtrahieren?
(also nur Lat +- x Meter oder Lon +- x Meter. Nicht diagonal)
Bin leider eine absolute Mathe-Null.

Gruss
Udo

jfheins 11. Aug 2012 13:22

AW: GEO - Functions
 
Hi,
also du kannst die Erdoberfläche lokal als Ebene annähern.
Das geht aber immer nur in der Umgebung von einem Bestimmten Punkt!
Da alle Längengrade gleich lang sind, entspricht ein Grad in Nord-Süd-Richtung ca. 111,7km.
Bei dem Breitengrad ist das etwas schwieriger:
Nehmen wir z.B. Hamburg: 53,55° N, 10° O.
An dieser Stelle entspricht ein Grad in Ost-West-Richtung ungefähr 67,2km.
In Freiburg im Breisgau sind es schon 74,7 km.

Das errechnet man wie folgt:
Zitat:

Bogenlänge von einem Grad geographischer Länge: 2*PI*6400km/360° = 111,7 km/°
Bogenlänge eines Grads geographischer Breite: 2*PI*6400km * cos(Breitengrad)/360°
Ich hoffe das war jetzt verständlich. Ich weiß leider nicht, was du schon für Mathe-Vorkenntnisse hast :angel:

wurzelzwerg 11. Aug 2012 14:58

AW: GEO - Functions
 
Danke,
habe auch diesen Java-Code gefunden:

Code:
double lat1 = (52.523405d * Math.PI) / 180.0d;
double lon1 = (13.411400d * Math.PI) / 180.0d;
     
double distance = (150000.0d) / 6378388.0d;
double winkel = (208.78d * Math.PI) / 180.0d;
     
double lat2 = Math.asin(Math.sin(lat1) * Math.cos(distance) + Math.cos(lat1) * Math.sin(distance) * Math.cos(-winkel));
double lon2;
if(Math.cos(lat1) == 0){
   lon2 = lon1;
}else{
   lon2 = ((lon1 - Math.asin(Math.sin(-winkel) * Math.sin(distance) / Math.cos(lat1)) + Math.PI) % (2*Math.PI)) - Math.PI;
}
lat2 = (lat2 * 180.0d) / Math.PI;
lon2 = (lon2 * 180.0d) / Math.PI;
     
log.debug("Lat: " + lat2 + " Lon: " + lon2);
Soweit ok, nur wie setzt man das hier in Dephi um:
Code:
lon2 = ((lon1 - Math.asin(Math.sin(-winkel) * Math.sin(distance) / Math.cos(lat1)) + Math.PI) % (2*Math.PI)) - Math.PI;
Das hier funktioniert nicht:
Delphi-Quellcode:
lon2:= lon1 - arcsin(sin(-winkel) * sin(distance) / cos(lat1)) + PI;
lon2:= (lon2 - (Trunc(lon2 / (2*PI)) * (2*PI))) - PI; // falsch
Was macht "%" in Java?

jfheins 11. Aug 2012 22:30

AW: GEO - Functions
 
Hi,
Zitat:

Zitat von wurzelzwerg (Beitrag 1177821)
Was macht "%" in Java?

Das ist der modulo-Operator. "mod" unter Delphi.

wurzelzwerg 11. Aug 2012 22:53

AW: GEO - Functions
 
Zitat:

Zitat von jfheins (Beitrag 1177854)
Das ist der modulo-Operator. "mod" unter Delphi.

Ja, klar. Nur in Delphi geht mod nur mit Ganzzahlen.

Ich hab das jetzt so gemacht:
Delphi-Quellcode:
procedure AddDistance(var Lat, Lon: Extended; direction, Distance: Extended);
var
  Lat1, Lon1, dist, winkel, Lat2, Lon2: Extended;
begin
  Lat1:= (Lat * PI) / 180;
  Lon1:= (Lon * PI) / 180;
  dist:= Distance / 6378388;
  winkel:= (direction * PI) / 180;
  Lat2:= arcsin(Sin(Lat1) * Cos(dist) + Cos(Lat1) * Sin(dist) * Cos(-winkel));
  if (Cos(Lat1) = 0) then
    Lon2:= Lon1
  else
  begin
     lon2:= lon1 - arcsin(sin(-winkel) * sin(dist) / cos(lat1)) + PI;
     lon2:= (lon2 - (Trunc(lon2 / (2*PI)) * (2*PI))) - PI;
  end;
  Lat:= (Lat2 * 180.0) / PI;
  Lon:= (Lon2 * 180.0) / PI;
end;

wurzelzwerg 2. Aug 2014 11:12

AW: GEO - Functions
 
DecimalLon, DecimalLat haben einen Fehler.
Man muss bei W und S das Ergebnis negieren. So wie das jetzt ist wird nur der Anfang(Grad) negiert.

8°28''58.3"W ergibt jetzt -7,48286151885986. Das sollte aber -8,48286151885986 sein.


Delphi-Quellcode:
 
//if (Pos('°W', Longitude) > 0) or (Longitude[length(Longitude)] = 'W') then
//   Longitude := '-' + Longitude;
....
// erst am Ende prüfen
if (Pos('°W', Longitude) > 0) or (Longitude[length(Longitude)] = 'W') then
  Result := -Result;


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:12 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz