Push 05.02.2026
This commit is contained in:
159
Berechnungen.py
159
Berechnungen.py
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user