anpassung ellipsoide und so
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -393,7 +393,7 @@ class ENU:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def berechne_schwerpunkt_fuer_enu(berechnungen, dict_xyz: dict) -> tuple:
|
def berechne_schwerpunkt_fuer_enu(berechnungen: Any, dict_xyz: dict) -> tuple:
|
||||||
"""
|
"""
|
||||||
Berechnet die ENU-Referenz (B0, L0) aus dem Schwerpunkt gegebener XYZ-Koordinaten.
|
Berechnet die ENU-Referenz (B0, L0) aus dem Schwerpunkt gegebener XYZ-Koordinaten.
|
||||||
|
|
||||||
@@ -413,7 +413,7 @@ class ENU:
|
|||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def berechne_R0_ENU(berechnungen, B: float, L:float) -> np.ndarray:
|
def berechne_R0_ENU(berechnungen: Any, B: float, L:float) -> np.ndarray:
|
||||||
"""
|
"""
|
||||||
Erzeugt die 3×3-Rotationsmatrix R0 für die Transformation von XYZ nach ENU.
|
Erzeugt die 3×3-Rotationsmatrix R0 für die Transformation von XYZ nach ENU.
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ class Genauigkeitsmaße:
|
|||||||
|
|
||||||
Die Klasse stellt Methoden zur Verfügung für:
|
Die Klasse stellt Methoden zur Verfügung für:
|
||||||
|
|
||||||
- Berechnung der a-posteriori Standardabweichung der Gewichtseinheit σ̂₀
|
- Berechnung der a posteriori Standardabweichung der Gewichtseinheit σ̂₀
|
||||||
- Berechnung des Helmertschen Punktfehlers (2D/3D),
|
- Berechnung des Helmertschen Punktfehlers (2D/3D),
|
||||||
- Berechnung der Standardellipse (Helmertschen Fehlerellipse),
|
- Berechnung der Standardellipsoide,
|
||||||
- Berechnung der Konfidenzellipse auf Basis eines Konfidenzniveaus (alpha) mit Skalierung über die F-Verteilung,
|
- Berechnung der Konfidenzellipsoide auf Basis eines Konfidenzniveaus (alpha) mit Skalierung über die F-Verteilung,
|
||||||
- Berechnung von Konfidenzellipsen im lokalen ENU-System durch Transformation von Qxx → Qxx_ENU,
|
- Berechnung der Konfidenzellipsen auf Basis eines Konfidenzniveaus (alpha) mit Skalierung über die F-Verteilung,
|
||||||
|
- Berechnung von Konfidenzellipsen im lokalen ENU-System durch Transformation von Qxx zu Qxx_ENU,
|
||||||
inkl. Ausgabe/Export tabellarischer Ergebnisse.
|
inkl. Ausgabe/Export tabellarischer Ergebnisse.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ class Genauigkeitsmaße:
|
|||||||
"""
|
"""
|
||||||
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||||
|
|
||||||
Die a-posteriori Standardabweichung dient als Qualitätsmaß für die
|
Die a posteriori Standardabweichung dient als Qualitätsmaß für die
|
||||||
Ausgleichung nach der Methode der kleinsten Quadrate. Dabei beschreibt
|
Ausgleichung nach der Methode der kleinsten Quadrate. Dabei beschreibt
|
||||||
r die Redundanz (Freiheitsgrade).
|
r die Redundanz (Freiheitsgrade).
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ class Genauigkeitsmaße:
|
|||||||
Berechnet den Helmertschen Punktfehler (2D/3D) anhand der Standardabweichungen der Koordinaten der Punkte.
|
Berechnet den Helmertschen Punktfehler (2D/3D) anhand der Standardabweichungen der Koordinaten der Punkte.
|
||||||
|
|
||||||
Aus der Kofaktor-Matrix der Unbekannten Qxx werden die Kofaktoren punktweise ausgelesen. Durch Multiplikation
|
Aus der Kofaktor-Matrix der Unbekannten Qxx werden die Kofaktoren punktweise ausgelesen. Durch Multiplikation
|
||||||
mit der a-posteriori Standardabweichung der Gewichtseinheit σ̂₀ werden die Standardabweichungen je Koordinate
|
mit der a posteriori Standardabweichung der Gewichtseinheit σ̂₀ werden die Standardabweichungen je Koordinate
|
||||||
(σx, σy, σz) sowie der Helmert'sche Punktfehler σP berechnet:
|
(σx, σy, σz) sowie der Helmert'sche Punktfehler σP berechnet:
|
||||||
|
|
||||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||||
@@ -108,7 +109,7 @@ class Genauigkeitsmaße:
|
|||||||
continue
|
continue
|
||||||
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σ̂x", "σ̂y", "σ̂z", f"σ̂P_{dim}D"])
|
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σ̂x", "σ̂y", "σ̂z", f"σ̂P_{dim}D"])
|
||||||
mittel_sP = helmert_punktfehler[f"σ̂P_{dim}D"].mean()
|
mittel_sP = helmert_punktfehler[f"σ̂P_{dim}D"].mean()
|
||||||
print(f"Mittlerer Helmert-Punktfehler über alle Punkte: {mittel_sP:.4f} [m]")
|
print(f"Mittlerer Helmert-Punktfehler über alle Punkte: {mittel_sP:.6f} [m]")
|
||||||
display(HTML(helmert_punktfehler.to_html(index=False)))
|
display(HTML(helmert_punktfehler.to_html(index=False)))
|
||||||
helmert_punktfehler.to_excel(r"Netzqualitaet\Standardabweichungen_Helmertscher_Punktfehler.xlsx",index=False)
|
helmert_punktfehler.to_excel(r"Netzqualitaet\Standardabweichungen_Helmertscher_Punktfehler.xlsx",index=False)
|
||||||
return helmert_punktfehler
|
return helmert_punktfehler
|
||||||
@@ -118,7 +119,7 @@ class Genauigkeitsmaße:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def standardellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list) -> pd.DataFrame:
|
def standardellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list) -> pd.DataFrame:
|
||||||
"""
|
"""
|
||||||
Berechnet Achsenlängen des Fehlerellipsoids (a, b, c) sowie den 2D-Richtungswinkel θ aus Qxx und σ̂₀ a posteriori.
|
Berechnet das Standardellipsoid aus Qxx und σ̂₀ a posteriori.
|
||||||
|
|
||||||
Für jeden Punkt wird aus der Kofaktor-Matrix der Unbekannten Qxx die 3×3-Submatrix
|
Für jeden Punkt wird aus der Kofaktor-Matrix der Unbekannten Qxx die 3×3-Submatrix
|
||||||
der Koordinaten (X, Y, Z) gebildet. Daraus werden zunächst die Standardabweichungen
|
der Koordinaten (X, Y, Z) gebildet. Daraus werden zunächst die Standardabweichungen
|
||||||
@@ -129,8 +130,9 @@ class Genauigkeitsmaße:
|
|||||||
- Halbachse b aus dem mittleren Eigenwert,
|
- Halbachse b aus dem mittleren Eigenwert,
|
||||||
- Halbachse c aus dem kleinsten Eigenwert.
|
- Halbachse c aus dem kleinsten Eigenwert.
|
||||||
|
|
||||||
Zusätzlich wird zur zweidimensionalen Darstellung ein Richtungswinkel θ in der X/Y-Ebene
|
Die Orientierung des Ellipsoids im Raum wird über die zugehörigen Eigenvektoren bestimmt.
|
||||||
aus den Kovarianzanteilen (qxx, qyy, qyx) berechnet (Winkel in gon).
|
Aus der Modalmatrix M, bestehend aus den sortierten Eigenvektoren, werden die drei Eulerwinkel α, β und γ
|
||||||
|
berechnet.
|
||||||
|
|
||||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||||
Die Ergebnisse werden tabellarisch ausgegeben und in eine Excel-Datei exportiert.
|
Die Ergebnisse werden tabellarisch ausgegeben und in eine Excel-Datei exportiert.
|
||||||
@@ -141,7 +143,7 @@ class Genauigkeitsmaße:
|
|||||||
:type sigma0_apost: float
|
:type sigma0_apost: float
|
||||||
:param unbekannten_liste: Liste der Unbekannten.
|
:param unbekannten_liste: Liste der Unbekannten.
|
||||||
:type unbekannten_liste: list
|
:type unbekannten_liste: list
|
||||||
:return: Tabelle mit Standardabweichungen (σx, σy, σz), Ellipsoid-Halbachsen (a, b, c) und Richtungswinkel θ je Punkt.
|
:return: Tabelle mit Standardabweichungen, Ellipsoid-Halbachsen, Eulerwinkel.
|
||||||
:rtype: pandas.DataFrame
|
:rtype: pandas.DataFrame
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -170,35 +172,44 @@ class Genauigkeitsmaße:
|
|||||||
|
|
||||||
# Eigenwertzerlegung
|
# Eigenwertzerlegung
|
||||||
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||||
eigenwerte = np.sort(eigenwerte)[::-1]
|
reihenfolge = np.argsort(eigenwerte)[::-1]
|
||||||
|
eigenwerte = eigenwerte[reihenfolge]
|
||||||
|
eigenwerte = np.clip(eigenwerte, 0.0, None)
|
||||||
|
M = eigenvektoren[:, reihenfolge]
|
||||||
|
if np.linalg.det(M) < 0:
|
||||||
|
M[:, 2] *= -1
|
||||||
|
|
||||||
# Halbachsen
|
# Halbachsen des Standardellipsoids
|
||||||
s_a = sigma0_apost * np.sqrt(eigenwerte[0]) # Große Halbachse a
|
s_a = sigma0_apost * np.sqrt(eigenwerte[0]) # Große Halbachse a
|
||||||
s_b = sigma0_apost * np.sqrt(eigenwerte[1]) # Mittlere Halbachse b
|
s_b = sigma0_apost * np.sqrt(eigenwerte[1]) # Mittlere Halbachse b
|
||||||
s_c = sigma0_apost * np.sqrt(eigenwerte[2]) # Kleine Halbachse c
|
s_c = sigma0_apost * np.sqrt(eigenwerte[2]) # Kleine Halbachse c
|
||||||
|
|
||||||
# Richtungswinkel theta in gon:
|
# Eulerwinkel aus M
|
||||||
qyx = Q_sub[1, 0]
|
beta = np.arcsin(-M[2, 0])
|
||||||
qxx = Q_sub[0, 0]
|
alpha = np.arctan2(M[2, 1], M[2, 2])
|
||||||
qyy = Q_sub[1, 1]
|
gamma = np.arctan2(M[1, 0], M[0, 0])
|
||||||
t_gon = 0.5 * np.arctan2(2 * qyx, qxx - qyy) * (200 / np.pi)
|
alpha_gon = (alpha * 200 / np.pi)% 400.0
|
||||||
if t_gon < 0:
|
beta_gon = (beta * 200 / np.pi)% 400.0
|
||||||
t_gon += 200
|
gamma_gon = (gamma * 200 / np.pi)% 400.0
|
||||||
|
|
||||||
daten.append([
|
daten.append([
|
||||||
pid, float(sx), float(sy), float(sz),
|
pid,
|
||||||
float(s_a), float(s_b), float(s_c), float(t_gon)
|
float(sx), float(sy), float(sz),
|
||||||
|
float(s_a), float(s_b), float(s_c),
|
||||||
|
float(alpha_gon), float(beta_gon), float(gamma_gon)
|
||||||
])
|
])
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
standardellipsoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a [m]", "Halbachse b [m]", "Halbachse c [m]", "θ [gon]"])
|
standardellipsoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a [m]", "Halbachse b [m]", "Halbachse c [m]", "α [gon]", "β [gon]", "γ [gon]"])
|
||||||
standardellipsoid["σ̂x [m]"] = standardellipsoid["σ̂x [m]"].astype(float).round(4)
|
standardellipsoid["σ̂x [m]"] = standardellipsoid["σ̂x [m]"].astype(float).round(6)
|
||||||
standardellipsoid["σ̂y [m]"] = standardellipsoid["σ̂y [m]"].astype(float).round(4)
|
standardellipsoid["σ̂y [m]"] = standardellipsoid["σ̂y [m]"].astype(float).round(6)
|
||||||
standardellipsoid["σ̂z [m]"] = standardellipsoid["σ̂z [m]"].astype(float).round(4)
|
standardellipsoid["σ̂z [m]"] = standardellipsoid["σ̂z [m]"].astype(float).round(6)
|
||||||
standardellipsoid["Halbachse a [m]"] = standardellipsoid["Halbachse a [m]"].astype(float).round(4)
|
standardellipsoid["Halbachse a [m]"] = standardellipsoid["Halbachse a [m]"].astype(float).round(6)
|
||||||
standardellipsoid["Halbachse b [m]"] = standardellipsoid["Halbachse b [m]"].astype(float).round(4)
|
standardellipsoid["Halbachse b [m]"] = standardellipsoid["Halbachse b [m]"].astype(float).round(6)
|
||||||
standardellipsoid["Halbachse c [m]"] = standardellipsoid["Halbachse c [m]"].astype(float).round(4)
|
standardellipsoid["Halbachse c [m]"] = standardellipsoid["Halbachse c [m]"].astype(float).round(6)
|
||||||
standardellipsoid["θ [gon]"] = standardellipsoid["θ [gon]"].astype(float).round(3)
|
standardellipsoid["α [gon]"] = standardellipsoid["α [gon]"].astype(float).round(3)
|
||||||
|
standardellipsoid["β [gon]"] = standardellipsoid["β [gon]"].astype(float).round(3)
|
||||||
|
standardellipsoid["γ [gon]"] = standardellipsoid["γ [gon]"].astype(float).round(3)
|
||||||
display(HTML(standardellipsoid.to_html(index=False)))
|
display(HTML(standardellipsoid.to_html(index=False)))
|
||||||
standardellipsoid.to_excel(r"Netzqualitaet\Standardellipsoid.xlsx", index=False)
|
standardellipsoid.to_excel(r"Netzqualitaet\Standardellipsoid.xlsx", index=False)
|
||||||
return standardellipsoid
|
return standardellipsoid
|
||||||
@@ -206,29 +217,30 @@ class Genauigkeitsmaße:
|
|||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def konfidenzellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list, R: int, ausgabe_erfolgt: bool) -> tuple[pd.DataFrame, float]:
|
def konfidenzellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list, R: int) -> tuple[pd.DataFrame, float]:
|
||||||
"""
|
"""
|
||||||
Berechnet die Konfidenzellipsoid für Punkte aus Qxx und einem Konfidenzniveau.
|
Berechnet das Konfidenzellipsoid aus Qxx, σ̂₀ a posteriori und einem Konfidenzniveau.
|
||||||
|
|
||||||
Auf Basis der Kovarianz-Matrix der Unbekannten Qxx und der a-posteriori
|
Auf Basis der Kovarianz-Matrix der Unbekannten Qxx und der a posteriori
|
||||||
Standardabweichung der Gewichtseinheit σ̂₀ werden für jeden Punkt die Parameter
|
Standardabweichung der Gewichtseinheit σ̂₀ werden für jeden Punkt die Parameter
|
||||||
des Konfidenzellipsoids berechnet. Das Konfidenzniveau wird mittels einer Eingabe
|
des Konfidenzellipsoids berechnet. Das Konfidenzniveau wird mittels einer Eingabe
|
||||||
über alpha festgelegt (Standard: 0.05 für 95%).
|
über alpha festgelegt.
|
||||||
|
|
||||||
Für jeden Punkt wird die 3×3-Submatrix der Koordinaten (X, Y, Z) aus Qxx gebildet.
|
Für jeden Punkt wird die 3×3-Submatrix der Koordinaten aus Qxx gebildet.
|
||||||
Über eine Eigenwertzerlegung dieser Submatrix werden die drei Hauptachsen des
|
Über eine Eigenwertzerlegung dieser Submatrix werden die drei Hauptachsen des
|
||||||
Fehlerellipsoids bestimmt. Die Halbachsen des Konfidenzellipsoids ergeben sich aus:
|
Ellipsoids bestimmt. Die Halbachsen des Konfidenzellipsoids ergeben sich aus:
|
||||||
|
|
||||||
- Aₖ: große Halbachse des Konfidenzellipsoids,
|
- Aₖ: große Halbachse des Konfidenzellipsoids,
|
||||||
- Bₖ: mittlere Halbachse des Konfidenzellipsoids,
|
- Bₖ: mittlere Halbachse des Konfidenzellipsoids,
|
||||||
- Cₖ: kleine Halbachse des Konfidenzellipsoids,
|
- Cₖ: kleine Halbachse des Konfidenzellipsoids,
|
||||||
|
|
||||||
unter Verwendung eines Faktors aus der F-Verteilung in Abhängigkeit vom
|
unter Verwendung eines Faktors aus der F-Verteilung in Abhängigkeit vom Konfidenzniveau und den Freiheitsgraden.
|
||||||
Konfidenzniveau und den Freiheitsgraden.
|
Die Orientierung des Ellipsoids im Raum wird über die zugehörigen Eigenvektoren bestimmt.
|
||||||
|
Aus der Modalmatrix M, bestehend aus den sortierten Eigenvektoren, werden die drei Eulerwinkel α, β und γ
|
||||||
|
berechnet.
|
||||||
|
|
||||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||||
Optional wird die Tabelle ausgegeben und als Excel-Datei exportiert, abhängig von
|
Optional wird die Tabelle ausgegeben und als Excel-Datei exportiert.
|
||||||
ausgabe_erfolgt.
|
|
||||||
|
|
||||||
:param Qxx: Kofaktor-Matrix der geschätzten Unbekannten.
|
:param Qxx: Kofaktor-Matrix der geschätzten Unbekannten.
|
||||||
:type Qxx: np.ndarray
|
:type Qxx: np.ndarray
|
||||||
@@ -238,8 +250,6 @@ class Genauigkeitsmaße:
|
|||||||
:type unbekannten_liste: list
|
:type unbekannten_liste: list
|
||||||
:param R: Redundanz (Freiheitsgrade) für die F-Verteilung.
|
:param R: Redundanz (Freiheitsgrade) für die F-Verteilung.
|
||||||
:type R: int
|
:type R: int
|
||||||
:param ausgabe_erfolgt: Steuert, ob eine Ausgabe/Dateischreibung erfolgen soll (False = Ausgabe).
|
|
||||||
:type ausgabe_erfolgt: bool
|
|
||||||
:return: Tabelle der Konfidenzellipse je Punkt, verwendetes alpha.
|
:return: Tabelle der Konfidenzellipse je Punkt, verwendetes alpha.
|
||||||
:rtype: tuple[pandas.DataFrame, float]
|
:rtype: tuple[pandas.DataFrame, float]
|
||||||
"""
|
"""
|
||||||
@@ -274,36 +284,137 @@ class Genauigkeitsmaße:
|
|||||||
|
|
||||||
# Eigenwertzerlegung
|
# Eigenwertzerlegung
|
||||||
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||||
eigenwerte = np.sort(eigenwerte)[::-1]
|
order = np.argsort(eigenwerte)[::-1]
|
||||||
|
eigenwerte = eigenwerte[order]
|
||||||
|
eigenwerte = np.clip(eigenwerte, 0.0, None)
|
||||||
|
M = eigenvektoren[:, order]
|
||||||
|
if np.linalg.det(M) < 0:
|
||||||
|
M[:, 2] *= -1
|
||||||
|
|
||||||
# Halbachsen des Konfidenzellipoid
|
# Halbachsen des Konfidenzellipoid
|
||||||
A_K = k * sigma0_apost * np.sqrt(eigenwerte[0])
|
A_K = k * sigma0_apost * np.sqrt(eigenwerte[0])
|
||||||
B_K = k * sigma0_apost * np.sqrt(eigenwerte[1])
|
B_K = k * sigma0_apost * np.sqrt(eigenwerte[1])
|
||||||
C_K = k * sigma0_apost * np.sqrt(eigenwerte[2])
|
C_K = k * sigma0_apost * np.sqrt(eigenwerte[2])
|
||||||
|
|
||||||
# Richtungswinkel theta in gon:
|
# Eulerwinkel aus M
|
||||||
qyx = Q_sub[1, 0]
|
beta = np.arcsin(-M[2, 0])
|
||||||
qxx = Q_sub[0, 0]
|
alpha_ = np.arctan2(M[2, 1], M[2, 2])
|
||||||
qyy = Q_sub[1, 1]
|
gamma = np.arctan2(M[1, 0], M[0, 0])
|
||||||
t_gon = 0.5 * np.arctan2(2 * qyx, qxx - qyy) * (200 / np.pi)
|
|
||||||
if t_gon < 0:
|
alpha_gon = (alpha_ * 200.0 / np.pi) % 400.0
|
||||||
t_gon += 200
|
beta_gon = (beta * 200.0 / np.pi) % 400.0
|
||||||
|
gamma_gon = (gamma * 200.0 / np.pi) % 400.0
|
||||||
|
|
||||||
daten.append([
|
daten.append([
|
||||||
pid, float(sx), float(sy), float(sz),
|
pid,
|
||||||
float(A_K), float(B_K), float(C_K), float(t_gon)
|
float(sx), float(sy), float(sz),
|
||||||
|
float(A_K), float(B_K), float(C_K),
|
||||||
|
float(alpha_gon), float(beta_gon), float(gamma_gon)
|
||||||
])
|
])
|
||||||
|
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
konfidenzellipoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a_k [m]", "Halbachse b_k [m]", "Halbachse c_k [m]", "θ [gon]"])
|
konfidenzellipoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a_k [m]", "Halbachse b_k [m]", "Halbachse c_k [m]", "α [gon]", "β [gon]", "γ [gon]"])
|
||||||
if ausgabe_erfolgt == False:
|
konfidenzellipoid["σ̂x [m]"] = konfidenzellipoid["σ̂x [m]"].astype(float).round(6)
|
||||||
|
konfidenzellipoid["σ̂y [m]"] = konfidenzellipoid["σ̂y [m]"].astype(float).round(6)
|
||||||
|
konfidenzellipoid["σ̂z [m]"] = konfidenzellipoid["σ̂z [m]"].astype(float).round(6)
|
||||||
|
konfidenzellipoid["Halbachse a_k [m]"] = konfidenzellipoid["Halbachse a_k [m]"].astype(float).round(6)
|
||||||
|
konfidenzellipoid["Halbachse b_k [m]"] = konfidenzellipoid["Halbachse b_k [m]"].astype(float).round(6)
|
||||||
|
konfidenzellipoid["Halbachse c_k [m]"] = konfidenzellipoid["Halbachse c_k [m]"].astype(float).round(6)
|
||||||
|
konfidenzellipoid["α [gon]"] = konfidenzellipoid["α [gon]"].astype(float).round(3)
|
||||||
|
konfidenzellipoid["β [gon]"] = konfidenzellipoid["β [gon]"].astype(float).round(3)
|
||||||
|
konfidenzellipoid["γ [gon]"] = konfidenzellipoid["γ [gon]"].astype(float).round(3)
|
||||||
display(HTML(konfidenzellipoid.to_html(index=False)))
|
display(HTML(konfidenzellipoid.to_html(index=False)))
|
||||||
konfidenzellipoid.to_excel(r"Netzqualitaet\Konfidenzellipoid.xlsx", index=False)
|
konfidenzellipoid.to_excel(r"Netzqualitaet\Konfidenzellipoid.xlsx", index=False)
|
||||||
return konfidenzellipoid, alpha
|
return konfidenzellipoid, alpha
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def konfidenzellipsen(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list, r_gesamt: int) -> pd.DataFrame:
|
||||||
|
"""
|
||||||
|
Berechnet Konfidenzellipsen für Punkte aus der Kofaktor-Matrix Qxx.
|
||||||
|
|
||||||
|
Für jeden Punkt werden aus der 2×2-Submatrix der Koordinaten die Parameter der Konfidenzellipse bestimmt.
|
||||||
|
Grundlage ist die a posteriori Standardabweichung der Gewichtseinheit sowie ein Konfidenzniveau, das über
|
||||||
|
die Irrtumswahrscheinlichkeit α festgelegt wird.
|
||||||
|
|
||||||
|
Die Halbachsen der Konfidenzellipse werden aus den Eigenwerten der Kovarianzmatrix berechnet.
|
||||||
|
Der Skalierungsfaktor ergibt sich aus der F-Verteilung.Der Richtungswinkel θ wird aus dem
|
||||||
|
Eigenvektor der großen Halbachse bestimmt und in gon ausgegeben.
|
||||||
|
|
||||||
|
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||||
|
|
||||||
|
:param Qxx: Kofaktor-Matrix der geschätzten Unbekannten.
|
||||||
|
:type Qxx: numpy.ndarray
|
||||||
|
:param sigma0_apost: a posteriori Standardabweichung der Gewichtseinheit.
|
||||||
|
:type sigma0_apost: float
|
||||||
|
:param unbekannten_liste: Liste der Unbekannten.
|
||||||
|
:type unbekannten_liste: list
|
||||||
|
:param r_gesamt: Redundanz (Freiheitsgrade) des Netzes.
|
||||||
|
:type r_gesamt: int
|
||||||
|
:return: Tabelle der Konfidenzellipsen je Punkt.
|
||||||
|
:rtype: pd.DataFrame
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Irrtumswahrscheinlichkeit alpha
|
||||||
|
alpha_input = input("Irrtumswahrscheinlichkeit α wählen (z.B. 0.05, 0.01) [Standard=0.05]: ")
|
||||||
|
if alpha_input.strip() == "":
|
||||||
|
alpha = 0.05
|
||||||
|
else:
|
||||||
|
alpha = float(alpha_input)
|
||||||
|
print(f"→ Verwende alpha = {alpha} (Konfidenz = {(1 - alpha) * 100:.1f}%)")
|
||||||
|
|
||||||
|
Qxx = np.asarray(Qxx, float)
|
||||||
|
daten = []
|
||||||
|
namen_str = [str(sym) for sym in unbekannten_liste]
|
||||||
|
|
||||||
|
punkt_ids = [n[1:] for n in namen_str if n.upper().startswith("X")]
|
||||||
|
|
||||||
|
# Faktor für die Konfidenzellipe (F-Verteilung)
|
||||||
|
k2 = float(np.sqrt(2.0 * f.ppf(1.0 - alpha, 2, r_gesamt)))
|
||||||
|
|
||||||
|
for pid in punkt_ids:
|
||||||
|
try:
|
||||||
|
idx_1 = next(i for i, n in enumerate(namen_str) if n.upper() == f"X{pid}".upper())
|
||||||
|
idx_2 = next(i for i, n in enumerate(namen_str) if n.upper() == f"Y{pid}".upper())
|
||||||
|
|
||||||
|
index = [idx_1, idx_2]
|
||||||
|
Q_sub = Qxx[np.ix_(index, index)]
|
||||||
|
|
||||||
|
# Standardabweichungen
|
||||||
|
sigma1 = sigma0_apost * np.sqrt(Q_sub[0, 0])
|
||||||
|
sigma2 = sigma0_apost * np.sqrt(Q_sub[1, 1])
|
||||||
|
|
||||||
|
# Eigenwertzerlegung 2D
|
||||||
|
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||||
|
reihenfolge = np.argsort(eigenwerte)[::-1]
|
||||||
|
eigenwerte = eigenwerte[reihenfolge]
|
||||||
|
eigenwerte = np.clip(eigenwerte, 0.0, None)
|
||||||
|
eigenvektoren = eigenvektoren[:, reihenfolge]
|
||||||
|
|
||||||
|
# Halbachsen der Konfidenzellipse
|
||||||
|
a = k2 * sigma0_apost * np.sqrt(eigenwerte[0])
|
||||||
|
b = k2 * sigma0_apost * np.sqrt(eigenwerte[1])
|
||||||
|
|
||||||
|
# Winkel aus Eigenvektor der großen Halbachse
|
||||||
|
v = eigenvektoren[:, 0]
|
||||||
|
t_gon = (np.arctan2(v[1], v[0]) * (200.0 / np.pi)) % 400.0
|
||||||
|
|
||||||
|
daten.append([pid, float(sigma1), float(sigma2), float(a), float(b), float(t_gon)])
|
||||||
|
|
||||||
|
except StopIteration:
|
||||||
|
continue
|
||||||
|
|
||||||
|
Konfidenzellipse = pd.DataFrame(daten, columns=[
|
||||||
|
"Punkt", "σ̂x [m]", "σ̂y [m]",
|
||||||
|
"Halbachse a_k [m]", "Halbachse b_k [m]", "θ [gon]"
|
||||||
|
])
|
||||||
|
return Konfidenzellipse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def konfidenzellipsen_enu(a: float, b: float, ausgabe_parameterschaetzung: dict, liste_unbekannte: list, ausgleichungsergebnis: dict, sigma0apost: float, r_gesamt: int) -> tuple[pd.DataFrame, np.ndarray]:
|
def konfidenzellipsen_enu(a: float, b: float, ausgabe_parameterschaetzung: dict, liste_unbekannte: list, ausgleichungsergebnis: dict, sigma0apost: float, r_gesamt: int) -> tuple[pd.DataFrame, np.ndarray]:
|
||||||
"""
|
"""
|
||||||
@@ -312,7 +423,7 @@ class Genauigkeitsmaße:
|
|||||||
Die Funktion transformiert zunächst die Kofaktor-Matrix der Unbekannten Qxx
|
Die Funktion transformiert zunächst die Kofaktor-Matrix der Unbekannten Qxx
|
||||||
in ein East-North-Up-System (ENU) bezogen auf den Schwerpunkt der verwendeten
|
in ein East-North-Up-System (ENU) bezogen auf den Schwerpunkt der verwendeten
|
||||||
Punkte (B0, L0). Anschließend wird auf Basis der transformierten Matrix die
|
Punkte (B0, L0). Anschließend wird auf Basis der transformierten Matrix die
|
||||||
Konfidenzellipse über die Funktion "konfidenzellipsoid" bestimmt.
|
Konfidenzellipse über die Funktion "konfidenzellipsen" bestimmt.
|
||||||
Zum Schluss werden Spaltennamen an die ENU-Notation angepasst, Werte gerundet,
|
Zum Schluss werden Spaltennamen an die ENU-Notation angepasst, Werte gerundet,
|
||||||
tabellarisch ausgegeben und als Excel-Datei exportiert.
|
tabellarisch ausgegeben und als Excel-Datei exportiert.
|
||||||
|
|
||||||
@@ -347,31 +458,29 @@ class Genauigkeitsmaße:
|
|||||||
print(
|
print(
|
||||||
f"ENU-Referenz (Schwerpunkt): B0={Einheitenumrechnung.Einheitenumrechnung.rad_to_gon_Decimal(B0):.8f} rad, L0={Einheitenumrechnung.Einheitenumrechnung.rad_to_gon_Decimal(L0):.8f} rad")
|
f"ENU-Referenz (Schwerpunkt): B0={Einheitenumrechnung.Einheitenumrechnung.rad_to_gon_Decimal(B0):.8f} rad, L0={Einheitenumrechnung.Einheitenumrechnung.rad_to_gon_Decimal(L0):.8f} rad")
|
||||||
|
|
||||||
# 2) Konfidenzellipoid im ENU-System
|
# 2) Konfidenzellipsen im ENU-System
|
||||||
Konfidenzellipse_ENU, alpha = Genauigkeitsmaße.konfidenzellipsoid(
|
Konfidenzellipse_ENU = Genauigkeitsmaße.konfidenzellipsen(
|
||||||
Qxx_enu,
|
Qxx_enu,
|
||||||
sigma0apost,
|
sigma0apost,
|
||||||
liste_unbekannte,
|
liste_unbekannte,
|
||||||
r_gesamt,
|
r_gesamt
|
||||||
ausgabe_erfolgt = True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 3) Spaltennamen anpassen
|
# 3) Spaltennamen anpassen
|
||||||
Konfidenzellipse_ENU = Konfidenzellipse_ENU.rename(columns={
|
Konfidenzellipse_ENU = Konfidenzellipse_ENU.rename(columns={
|
||||||
"σ̂x [m]": "σ̂E [m]",
|
"σ̂x [m]": "σ̂E [m]",
|
||||||
"σ̂y [m]": "σ̂N [m]",
|
"σ̂y [m]": "σ̂N [m]",
|
||||||
"σ̂z [m]": "σ̂U [m]",
|
"Halbachse a_k [m]": "Halbachse a_k_EN [m]",
|
||||||
|
"Halbachse b_k [m]": "Halbachse b_k_EN [m]",
|
||||||
"θ [gon]": "θ_EN [gon]"
|
"θ [gon]": "θ_EN [gon]"
|
||||||
})
|
})
|
||||||
|
|
||||||
# 4) Runden und Anzeigen
|
# 4) Runden und Anzeigen
|
||||||
Konfidenzellipse_ENU["σ̂E [m]"] = Konfidenzellipse_ENU["σ̂E [m]"].round(6)
|
Konfidenzellipse_ENU["σ̂E [m]"] = Konfidenzellipse_ENU["σ̂E [m]"].round(6)
|
||||||
Konfidenzellipse_ENU["σ̂N [m]"] = Konfidenzellipse_ENU["σ̂N [m]"].round(6)
|
Konfidenzellipse_ENU["σ̂N [m]"] = Konfidenzellipse_ENU["σ̂N [m]"].round(6)
|
||||||
Konfidenzellipse_ENU["σ̂U [m]"] = Konfidenzellipse_ENU["σ̂U [m]"].round(6)
|
Konfidenzellipse_ENU["Halbachse a_k_EN [m]"] = Konfidenzellipse_ENU["Halbachse a_k_EN [m]"].round(6)
|
||||||
Konfidenzellipse_ENU["Halbachse a_k [m]"] = Konfidenzellipse_ENU["Halbachse a_k [m]"].round(4)
|
Konfidenzellipse_ENU["Halbachse b_k_EN [m]"] = Konfidenzellipse_ENU["Halbachse b_k_EN [m]"].round(6)
|
||||||
Konfidenzellipse_ENU["Halbachse b_k [m]"] = Konfidenzellipse_ENU["Halbachse b_k [m]"].round(4)
|
Konfidenzellipse_ENU["θ_EN [gon]"] = Konfidenzellipse_ENU["θ_EN [gon]"].round(3)
|
||||||
Konfidenzellipse_ENU["Halbachse c_k [m]"] = Konfidenzellipse_ENU["Halbachse c_k [m]"].round(4)
|
|
||||||
Konfidenzellipse_ENU["θ_EN [gon]"] = Konfidenzellipse_ENU["θ_EN [gon]"].round(4)
|
|
||||||
|
|
||||||
display(HTML(Konfidenzellipse_ENU.to_html(index=False)))
|
display(HTML(Konfidenzellipse_ENU.to_html(index=False)))
|
||||||
|
|
||||||
@@ -406,12 +515,11 @@ class Plot:
|
|||||||
Die Funktion visualisiert das geodätische Netz im East-North-Up-System (ENU) mit Plotly.
|
Die Funktion visualisiert das geodätische Netz im East-North-Up-System (ENU) mit Plotly.
|
||||||
Dabei werden:
|
Dabei werden:
|
||||||
|
|
||||||
- Beobachtungen als Verbindungslinien zwischen Punkten dargestellt (als separate Traces/Legenden-Einträge),
|
- Beobachtungen als Verbindungslinien zwischen Punkten dargestellt,
|
||||||
- Konfidenzellipsen je Punkt (Halbachsen und Richtungswinkel),
|
- Konfidenzellipsen je Punkt,
|
||||||
- Netzpunkte mit Punkt-ID und Koordinaten im Hover-Text angezeigt.
|
- Netzpunkte mit Punkt-ID und Koordinaten im Hover-Text angezeigt.
|
||||||
|
|
||||||
Die Ellipsen werden zur besseren Sichtbarkeit mit dem Faktor "skalierung" vergrößert.
|
Die Ellipsen werden zur besseren Sichtbarkeit mit dem Faktor "skalierung" vergrößert.
|
||||||
Der Richtungswinkel wird in gon erwartet und intern nach Radiant umgerechnet.
|
|
||||||
Zusätzlich wird eine PNG-Grafik über "plot.write_image(...)" exportiert.
|
Zusätzlich wird eine PNG-Grafik über "plot.write_image(...)" exportiert.
|
||||||
|
|
||||||
:param Koord_ENU: Dictionary der Punktkoordinaten im ENU-System.
|
:param Koord_ENU: Dictionary der Punktkoordinaten im ENU-System.
|
||||||
@@ -484,9 +592,9 @@ class Plot:
|
|||||||
if pid not in Koord_ENU:
|
if pid not in Koord_ENU:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
a = float(row["Halbachse a_k [m]"]) * skalierung
|
a = float(row["Halbachse a_k_EN [m]"]) * skalierung
|
||||||
b = float(row["Halbachse b_k [m]"]) * skalierung
|
b = float(row["Halbachse b_k_EN [m]"]) * skalierung
|
||||||
theta = float(row[theta_col]) * np.pi / 200.0 # gon->rad
|
theta = float(row["θ_EN [gon]"]) * np.pi / 200.0
|
||||||
|
|
||||||
ex = a * np.cos(t)
|
ex = a * np.cos(t)
|
||||||
ey = b * np.sin(t)
|
ey = b * np.sin(t)
|
||||||
|
|||||||
Reference in New Issue
Block a user