Push 05.02.2026

This commit is contained in:
2026-02-05 12:52:27 +01:00
parent 5842255a6a
commit e0796deec6
15 changed files with 38386 additions and 1765 deletions

View File

@@ -1,7 +1,4 @@
from decimal import Decimal
import sympy as sp
from typing import Any
import math
import numpy as np
import Datenbank
@@ -383,92 +380,30 @@ class Berechnungen:
return schraegdistanz_boden, zw_boden
class Einheitenumrechnung:
"""Einheitenumrechnungen für Winkel- und Längeneinheiten.
class ENU:
"""Transformationen zwischen XYZ und lokalem ENU-System.
Die Klasse stellt Methoden zur Verfügung für:
- Umrechnung von Millibogensekunden (mas) in Radiant,
- Umrechnung von Millimetern (mm) in Meter,
- Umrechnung von Gon und Milligon (mgon) in Radiant (Decimal-basiert).
- Bestimmung eines ENU-Referenzpunkts über den Schwerpunkt gegebener XYZ-Koordinaten,
- Aufbau der lokalen Rotationsmatrix R0 (XYZ nach ENU) aus geodätischer Breite B und Länge L,
- Aufbau einer Rotationsmatrix R_ENU für einen gesamten Unbekanntenvektor,
- Transformation der Kovarianz-Matrix Qxx in das ENU-System,
- Transformation von Punktkoordinaten (XYZ) in lokale ENU-Koordinaten relativ zum Schwerpunkt.
"""
def mas_to_rad(mas: float) -> float:
"""Rechnet Millibogensekunden (mas) in Radiant um.
Es gilt: rad = mas * (pi / (180 * 3600 * 1000)).
:param mas: Winkel in Millibogensekunden (mas).
:type mas: float
:return: Winkel in Radiant.
:rtype: float
"""
umrechnungsfaktor = 1 / 1000 * 1 / 3600 * sp.pi / 180
grad = mas * umrechnungsfaktor
return grad
def mm_to_m(mm: float) -> float:
"""Rechnet Millimeter in Meter um.
Es gilt: m = mm / 1000.
:param mm: Länge in Millimeter.
:type mm: float
:return: Länge in Meter.
:rtype: float
"""
m = mm / 1000
return m
def gon_to_rad_Decimal(gon: float) -> Decimal:
"""Rechnet Gon in Radiant um (Decimal-basiert).
Es gilt: 400 gon = 2*pi und damit rad = (gon / 200) * pi.
:param gon: Winkel in Gon.
:type gon: float
:return: Winkel in Radiant als Decimal.
:rtype: Decimal
"""
gon = Decimal(gon)
pi = Decimal(str(math.pi))
rad = (gon / Decimal(200)) * pi
return rad
def mgon_to_rad_Decimal(gon: float) -> Decimal:
"""Rechnet Milligon (mgon) in Radiant um (Decimal-basiert).
Es gilt: 1 mgon = 0.001 gon und damit rad = (mgon / 200000) * pi.
:param gon: Winkel in Milligon (mgon).
:type gon: float
:return: Winkel in Radiant als Decimal.
:rtype: Decimal
"""
gon = Decimal(gon)
pi = Decimal(str(math.pi))
rad = (gon / Decimal(200000)) * pi
return rad
def rad_to_gon_Decimal(rad: float) -> Decimal:
"""Rechnet Radiant in Gon um (Decimal-basiert).
Es gilt: 400 gon = 2*pi und damit rad = (gon / 200) * pi.
:param rad: Winkel in Rad.
:type rad: float
:return: Winkel in Gon als Decimal.
:rtype: Decimal
"""
rad = Decimal(rad)
pi = Decimal(str(math.pi))
gon = (rad / pi) * Decimal(200)
return gon
class ENU:
@staticmethod
def berechne_schwerpunkt_fuer_enu(berechnungen, dict_xyz):
"""
Berechnet die ENU-Referenz (B0, L0) aus dem Schwerpunkt gegebener XYZ-Koordinaten.
:param berechnungen: Hilfsobjekt mit Methoden zur Berechnung von Breite B und Länge L.
:type berechnungen: Any
:param dict_xyz: Dictionary der Koordinaten.
:type dict_xyz: dict
:return: Tuple aus geodätischer Breite B0 und Länge L0 des Schwerpunktes.
:rtype: tuple[float, float]
"""
XYZ = np.array(list(dict_xyz.values()), dtype=float)
X0, Y0, Z0 = XYZ.mean(axis=0)
B0 = float(berechnungen.B(X0, Y0, Z0))
@@ -478,6 +413,18 @@ class ENU:
@staticmethod
def berechne_R0_ENU(berechnungen, B, L):
"""
Erzeugt die 3×3-Rotationsmatrix R0 für die Transformation von XYZ nach ENU.
:param berechnungen: Hilfsobjekt mit Methoden zur Berechnung der ENU-Komponenten.
:type berechnungen: Any
:param B: Geodätische Breite des ENU-Referenzpunkts.
:type B: float
:param L: Geodätische Länge des ENU-Referenzpunkts.
:type L: float
:return: Rotationsmatrix R0 (3×3) für XYZ nach ENU.
:rtype: numpy.ndarray
"""
# East
r11 = berechnungen.E(L, 1, 0)
r12 = berechnungen.E(L, 0, 1)
@@ -504,6 +451,20 @@ class ENU:
@staticmethod
def berechne_R_ENU(unbekannten_liste, R0):
"""
Erstellt eine Rotationsmatrix R für die Umrechnung eines Unbekanntenvektors ins ENU-System.
Für jede Punkt-ID, die über Symbolnamen (z.B. X1, Y1, Z1) in unbekannten_liste erkannt wird,
wird die 3×3-Rotation R0 in die passende Position der Gesamtmatrix eingesetzt.
:param unbekannten_liste: Liste der Unbekannten
:type unbekannten_liste: list
:param R0: Rotationsmatrix (3×3) für XYZ nach ENU.
:type R0: numpy.ndarray
:return: Rotationsmarix R (n×n) für den gesamten Unbekanntenvektor.
:rtype: numpy.ndarray
"""
names = [str(s) for s in unbekannten_liste]
n = len(names)
R = np.eye(n, dtype=float)
@@ -526,6 +487,27 @@ class ENU:
@staticmethod
def transform_Qxx_zu_QxxENU(Qxx, unbekannten_liste, berechnungen, dict_xyz):
"""
Transformiert die Kofaktor-Matrix Qxx in das ENU-System.
Es wird zunächst eine ENU-Referenz über den Schwerpunkt der Koordinaten bestimmt.
Anschließend wird R0 (XYZ nach ENU) und die Matrix R_ENU aufgebaut. Die Transformation
erfolgt über:
Qxx_ENU = R_ENU · Qxx · R_ENUᵀ
:param Qxx: Kofaktor-Matrix der Unbekannten im XYZ-System.
:type Qxx: numpy.ndarray
:param unbekannten_liste: Liste der Unbekannten.
:type unbekannten_liste: list
:param berechnungen: Hilfsobjekt für Breite/Länge und ENU-Komponenten.
:type berechnungen: Any
:param dict_xyz: Dictionary der Koordinaten.
:type dict_xyz: dict
:return: Qxx_ENU, (B0, L0), R0 mit Schwerpunkt-Referenz und lokaler Rotationsmatrix.
:rtype: tuple[numpy.ndarray, tuple[float, float], numpy.ndarray]
"""
B0, L0 = ENU.berechne_schwerpunkt_fuer_enu(berechnungen, dict_xyz)
R0 = ENU.berechne_R0_ENU(berechnungen, B0, L0)
R_ENU = ENU.berechne_R_ENU(unbekannten_liste, R0)
@@ -538,6 +520,17 @@ class ENU:
@staticmethod
def transform_Koord_zu_KoordENU(dict_xyz, R0):
"""
Transformiert Punktkoordinaten (XYZ) in ENU-Koordinaten relativ zum Schwerpunkt.
:param dict_xyz: Dictionary der Koordinaten.
:type dict_xyz: dict
:param R0: Rotationsmatrix (3×3) für XYZ nach ENU.
:type R0: numpy.ndarray
:return: Dictionary der ENU-Koordinaten.
:rtype: dict
"""
XYZ = np.asarray(list(dict_xyz.values()), dtype=float).reshape(-1, 3)
XYZ0 = XYZ.mean(axis=0).reshape(3, )
@@ -546,4 +539,4 @@ class ENU:
xyz = np.asarray(xyz, dtype=float).reshape(3, )
enu = (R0 @ (xyz - XYZ0)).reshape(3, )
Koord_ENU[str(pid)] = (float(enu[0]), float(enu[1]), float(enu[2]))
return Koord_ENU
return Koord_ENU