std.geodesy.frames — geodätisch, ECEF, ENU, NED
import std.geodesy.frames;
Die Umrechnung zwischen den vier Bezugsrahmen: geodätische Koordinaten (Breite, Länge, Höhe), erdfestes ECEF und die beiden örtlichen Rahmen ENU und NED.
→ std.geodesy Übersicht · std.geodesy.ellipsoid · Guide: Kurs und Lage im 3D-Raum
1. Geodätische Koordinaten
pub type Geodetic = struct { latRad: f64; lonRad: f64; hEll: f64; }
| Signatur | Zweck |
|---|---|
GeodNew(latRad, lonRad, hEll): Geodetic | aus Bogenmaß |
GeodFromDeg(latDeg, lonDeg, hEll): Geodetic | aus Grad — der übliche Einstieg |
GeodLatDeg(g: Geodetic): f64 · GeodLonDeg(g: Geodetic): f64 | zurück in Grad |
hEll ist die Höhe über dem Ellipsoid, nicht über dem Meeresspiegel. Der Unterschied (Geoidundulation) beträgt in Mitteleuropa rund 45 m — wer eine GPS-Höhe unbesehen als Höhe über NN nimmt, liegt genau um diesen Betrag daneben. Ein Geoidmodell bringt diese Unit nicht mit.
2. Geodätisch ↔ ECEF
| Signatur | Zweck |
|---|---|
GeodToEcef(e: Ellipsoid, g: Geodetic): V3 | nach erdfest-kartesisch |
EcefToGeod(e: Ellipsoid, p: V3): Geodetic | zurück |
Die Rückrechnung ist der schwierigere Weg — die Breite steht in einer Gleichung, die sich nicht geschlossen auflösen lässt. Die Umrechnung hin und zurück trifft im Test wieder denselben Wert (53.630400 → 53.630400).
Drei Proben, die man nachrechnen kann
45N/45O: 3194419.145 | 3194419.145 | 4487348.409
Aequator: 6378137.000 | 0.000 | 0.000
Nordpol: 0.000 | 0.000 | 6356752.314
- 45° N / 45° O stimmt bis auf drei Nachkommastellen mit dem Literaturwert überein — die übliche Kontrollstelle, weil dort x und y gleich groß sein müssen.
- Am Äquator ist x genau die große Halbachse (
EllWgs84().a= 6378137.000), y und z sind null. - Am Pol ist z genau die kleine Halbachse (
EllB(e)= 6356752.314).
Diese drei Fälle sind die schnellste Probe, ob ein Ellipsoid richtig eingesetzt und die Breite nicht versehentlich in Grad statt Bogenmaß übergeben wurde: schon ein vertauschtes Winkelmaß verschiebt den Äquatorpunkt um Tausende Kilometer.
ECEF ist die Drehscheibe dieser Unit: alles andere führt über diesen Rahmen.
3. Örtliche Rahmen
| Signatur | Zweck |
|---|---|
EcefToEnu(e: Ellipsoid, origin: Geodetic, p: V3): V3 | ECEF → Ost, Nord, Oben |
EnuToEcef(e: Ellipsoid, origin: Geodetic, enu: V3): V3 | zurück |
EcefToNed(e: Ellipsoid, origin: Geodetic, p: V3): V3 | ECEF → Nord, Ost, Unten |
NedToEcef(e: Ellipsoid, origin: Geodetic, ned: V3): V3 | zurück |
EnuToNed(enu: V3): V3 · NedToEnu(ned: V3): V3 | direkt umtauschen |
EnuToNed rechnet (e, n, u) → (n, e, −u).
Das Vorzeichen ist die Falle: wer ENU-Werte als NED liest, bekommt eine Höhe, die unter der Erde liegt — und in einer Regelschleife eine Steuergröße mit falschem Vorzeichen. Luftfahrt und Regelungstechnik rechnen in NED, Vermessung und Antennentechnik in ENU.
4. Sichtlinie
| Signatur | Zweck |
|---|---|
EnuAzimuth(enu: V3): f64 | Azimut in Bogenmaß, von Nord über Ost |
EnuElevation(enu: V3): f64 | Erhebungswinkel über der Horizontebene |
EnuSlantRange(enu: V3): f64 | Schrägentfernung — die Luftlinie, nicht die Grundstrecke |
5. Beispiel
unit main;
import std.coordinates.vec3;
import std.coordinates.transform;
import std.geodesy.ellipsoid;
import std.geodesy.frames;
import std.io;
import std.string;
fn main(): int64 {
var e: Ellipsoid := EllWgs84();
var hh: Geodetic := GeodFromDeg(53.6304, 9.9882, 0.0);
var zz: Geodetic := GeodFromDeg(53.5511, 9.9937, 0.0);
var enu: V3 := EcefToEnu(e, hh, GeodToEcef(e, zz));
PrintLn(StrConcat("Ost (m): ", FloatToStr(enu.x, 1)));
PrintLn(StrConcat("Nord (m): ", FloatToStr(enu.y, 1)));
PrintLn(StrConcat("Azimut (Grad):", FloatToStr(RadToDeg(EnuAzimuth(enu)), 2)));
PrintLn(StrConcat("Entfernung: ", FloatToStr(EnuSlantRange(enu), 1)));
return 0;
}
Ost (m): 363.4
Nord (m): -8825.9
Azimut (Grad):177.63
Entfernung: 8833.4
Nord ist negativ, weil das Ziel südlich liegt — und der Azimut 177,6° sagt dasselbe noch einmal. Beides zusammen ist die Probe, ob der Rahmen richtig herum steht.
Letzte Aktualisierung: 2026-09-07 — Abschnitt „Drei Proben„ ergänzt: 45°N/45°O gegen den Literaturwert, Äquator gegen die große und Pol gegen die kleine Halbachse; nachgemessen mit lyxc 1.2.2D.
Vorherige letzte Aktualisierung: 2026-09-06 — Seite neu angelegt; erhoben aus std/geodesy/frames.lyx, Beispiel gegen lyxc 1.2.2D übersetzt und ausgeführt.
