zusammenfügen 02.2.

This commit is contained in:
2026-02-05 22:26:33 +01:00
parent 3828de1f9b
commit 3f16cbdb2b
8 changed files with 60527 additions and 283 deletions
+60315 -208
View File
File diff suppressed because one or more lines are too long
+4 -3
View File
@@ -405,9 +405,10 @@ class ENU:
: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))
L0 = float(berechnungen.L(X0, Y0))
mittelwerte = XYZ.mean(axis=0)
X0, Y0, Z0 = mittelwerte[0], mittelwerte[1], mittelwerte[2]
B0 = float(np.asarray(berechnungen.B(X0, Y0, Z0)).item())
L0 = float(np.asarray(berechnungen.L(X0, Y0)).item())
return B0, L0
+112
View File
@@ -2,6 +2,7 @@ import csv
from datetime import datetime
import numpy as np
import os
import pandas as pd
import sympy as sp
import webbrowser
@@ -78,6 +79,19 @@ class Export:
:return: None
:rtype: None
"""
for key in ergebnisse:
wert = ergebnisse[key]
if isinstance(wert, tuple):
if len(wert) > 0 and isinstance(wert[0], pd.DataFrame):
ergebnisse[key] = wert[0]
else:
ergebnisse[key] = pd.DataFrame(list(wert))
elif isinstance(wert, dict):
ergebnisse[key] = pd.DataFrame([wert])
# Pfad für den Ordner erstellen
ordner = "Protokolle"
if not os.path.exists(ordner):
@@ -97,6 +111,19 @@ class Export:
h1 {{ color: #2c3e50; border-bottom: 2px solid #2c3e50; }}
h3 {{ color: #2980b9; margin-top: 30px; }}
.metadata {{ background: #f9f9f9; padding: 15px; border-radius: 5px; border-left: 5px solid #2980b9; }}
/* Styling für das Inhaltsverzeichnis */
.toc {{ background: #fff; border: 1px solid #ddd; padding: 15px; border-radius: 5px; display: inline-block; min-width: 300px; }}
.toc ul {{ list-style: none; padding-left: 0; }}
.toc li {{ margin: 5px 0; }}
.toc a {{ text-decoration: none; color: #2980b9; font-weight: bold; }}
.toc a:hover {{ text-decoration: underline; }}
/* Styling für Bilder */
.plot-container {{ margin-top: 20px; text-align: center; background: #fff; padding: 10px; border: 1px solid #ddd; }}
.plot-img {{ width: 100%; max-width: 1000px; height: auto; border: 1px solid #eee; }}
.plot-caption {{ font-style: italic; color: #666; margin-top: 5px; }}
table {{ border-collapse: collapse; width: 100%; margin-top: 10px; }}
th, td {{ text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }}
tr:nth-child(even) {{ background-color: #f2f2f2; }}
@@ -112,13 +139,95 @@ class Export:
<p><strong>Bearbeiter:</strong> {metadaten['bearbeiter']}</p>
<p><strong>Datum:</strong> {metadaten['datum']}</p>
<p><strong>Ausgleichungsmodus:</strong> Methode der kleinsten Quadrate (L2-Norm)</p>
<p><strong>Koordinatenreferenzsystem:</strong> {metadaten['koordinatenreferenzsystem']}</p>
<p><strong>Datumsfestlegung:</strong> {metadaten['datumsfestlegung']}</p>
<p><strong>Dimension:</strong> 3D</p>
</div>
<div class="toc">
<strong>Inhaltsverzeichnis</strong>
<ul>
<li><a href="#globaltest">1. Globaltest</a></li>
<li><a href="#redundanz">2. Redundanzanteile</a></li>
<li><a href="#lokaltest">3. Lokaltest</a></li>
<li><a href="#vks">4. Varianzkomponentenschätzung</a></li>
<li><a href="#aeussere_zuver">5. Äussere Zuverlässigkeit</a></li>
<li><a href="#Helmertscher_Punktfehler">6. Standardabweichungen und Helmert'scher Punktfehler</a></li>
<li><a href="#standardellipsen">7. Standardellipsen</a></li>
<li><a href="#konfidenzellipsen">8. Konfidenzellipsen</a></li>
<li><a href="#Konfidenzellipse_ENU">9. Konfidenzellipsen im ENU-System</a></li>
<li><a href="#netzplot_gesamt">10. Netzplot im ENU-System mit Konfidenzellipsen - Gesamtes Netz</a></li>
<li><a href="#netzplot_zoom">11. Netzplot im ENU-System mit Konfidenzellipsen - Ausschnitt</a></li>
<li><a href="#koordinaten_xyz">12. Koordinaten Geozentrisch</a></li>
<li><a href="#koordinaten_utm">13. Koordinaten UTM</a></li>
</ul>
</div>
<h3 id="globaltest">1. Globaltest</h3>
{ergebnisse['df_globaltest'].to_html(index=False)}
<h3 id="redundanz">2. Redundanzanteile</h3>
{ergebnisse['df_redundanz'].to_html(index=False)}
<h3 id="lokaltest">3. Lokaltest</h3>
{ergebnisse['df_lokaltest'].to_html(index=False)}
<h3 id="vks">4. Varianzkomponentenschätzung</h3>
{ergebnisse['df_vks'].to_html(index=False)}
<h3 id="aeussere_zuver">5. Äussere Zuverlässigkeit</h3>
{ergebnisse['df_aeussere_zuver'].to_html(index=False)}
<h3 id="Helmertscher_Punktfehler">6. Standardabweichungen und Helmert'scher Punktfehler</h3>
{ergebnisse['df_punktfehler'].to_html(index=False)}
<h3 id="standardellipsen">7. Standardellipsen</h3>
{ergebnisse['df_ellipsen'].to_html(index=False)}
<h3 id="konfidenzellipsen">8. Konfidenzellipsen</h3>
{ergebnisse['df_konfidenzellipsen'].to_html(index=False)}
<h3 id="Konfidenzellipse_ENU">9. Konfidenzellipsen im ENU-System</h3>
{ergebnisse['df_konfidenzellipsen_enu'].to_html(index=False)}
<h3 id="netzplot_gesamt">10. Plots: Konfidenzellipsen im ENU-System (Gesamtes Netz)</h3>
<div class="plot-container">
<h4>Gesamtnetz</h4>
<img src="../Netzqualitaet/netzplot_ellipsen_volle_ausdehnung.png" class="plot-img" alt="Gesamtes Netz">
<p class="plot-caption">Netzplot im ENU-System mit Konfidenzellipsen - Gesamtes Netz</p>
</div>
<h3 id="netzplot_zoom">11. Plots: Konfidenzellipsen im ENU-System (Auschnitt) </h3>
<div class="plot-container">
<h4>Detailansicht (Zoom)</h4>
<img src="../Netzqualitaet/netzplot_ellipsen_zoom_ansicht.png" class="plot-img" alt="2Netzplot im ENU-System mit Konfidenzellipsen - Gesamtes Netz">
<p class="plot-caption">Netzplot im ENU-System mit Konfidenzellipsen - Ausschnitt</p>
</div>
<h3 id="koordinaten_xyz">12. Koordinaten Geozentrisch Kartesisch</h3>
{ergebnisse['df_koordinaten_geozentrisch_kartesisch'].to_html(index=True)}
<h3 id="koordinaten_utm">13. Koordinaten UTM</h3>
{ergebnisse['df_koordinaten_utm'].to_html(index=True)}
<h3>1. Globaltest</h3>
{ergebnisse['df_globaltest'].to_html(index=False)}
<h3>2. Redundanzanteile</h3>
{ergebnisse['df_redundanz'].to_html(index=False)}
<h3>2. Lokaltest (data snooping)</h3>
{ergebnisse['df_lokaltest'].to_html(index=False)}
<h3>2. Varianzkomponentenschätzung</h3>
{ergebnisse['df_vks'].to_html(index=False)}
<h3>2. Äussere Zuverlässigkeit</h3>
{ergebnisse['df_aeussere_zuver'].to_html(index=False)}
<h3>2. Standardabweichungen und Helmert'scher Punktfehler</h3>
{ergebnisse['df_punktfehler'].to_html(index=False)}
<h3>3. Standardellipsen</h3>
{ergebnisse['df_ellipsen'].to_html(index=False)}
@@ -126,6 +235,9 @@ class Export:
<h3>3. Konfidenzellipsen</h3>
{ergebnisse['df_konfidenzellipsen'].to_html(index=False)}
<h3>3. Konfidenzellipsen im ENU-System</h3>
{ergebnisse['df_konfidenzellipsen_enu'].to_html(index=False)}
<h3>3. Koordinaten Geozentrisch Kartesisch</h3>
{ergebnisse['df_koordinaten_geozentrisch_kartesisch'].to_html(index=True)}
+22 -22
View File
@@ -103,7 +103,7 @@ class Import:
# Abbruch des Imports und Ausgabe einer Fehlermeldung, wenn ein Punkt doppelt in der Importdatei vorhanden ist.
if row[0] in liste_punktnummern_vorher:
Import_abbrechen = True
print(f"Der Import wurde abgebrochen, weil in der Datei {pfad_datei} Punktnummern doppelt vorhanden sind. Bitte in der Datei ändern und Import wiederholen.")
print(f"❌ Der Import wurde abgebrochen, weil in der Datei {pfad_datei} Punktnummern doppelt vorhanden sind. Bitte in der Datei ändern und Import wiederholen.")
break
liste_punktnummern_vorher.append(row[0])
@@ -111,7 +111,7 @@ class Import:
# Abbruch des Imports und Ausgabe einer Fehlermeldung, wenn mindestens eine Punktnummer aus der Importdatei bereits in der Tabelle Netzpunkte vorhanden ist.
if row[0] in liste_punktnummern_db:
Import_abbrechen = True
print(f"Der Import wurde abgebrochen, weil mindestens ein Teil der Punktnummern aus der Datei {pfad_datei} bereits in der Datenbank vorhanden ist. Bitte in der Datei ändern und Import wiederholen.")
print(f"❌ Der Import wurde abgebrochen, weil mindestens ein Teil der Punktnummern aus der Datei {pfad_datei} bereits in der Datenbank vorhanden ist. Bitte in der Datei ändern und Import wiederholen.")
break
liste_punktnummern_vorher_db.append(row[0])
@@ -130,7 +130,7 @@ class Import:
con.commit()
cursor.close()
con.close()
print("Der Import der Näherungskoordinaten wurde erfolgreich abgeschlossen")
print("✅ Der Import der Näherungskoordinaten wurde erfolgreich abgeschlossen")
def ist_rundung_von_jxl(self, wert_csv: str, wert_jxl: str) -> bool:
"""Prüft, ob ein CSV-Wert eine Rundung eines JXL-Wertes (mit mehr Nachkommastellen) ist.
@@ -431,7 +431,7 @@ class Import:
if zaehler >= len(liste_records):
Import_fortsetzen = False
print(
f"Der Vorgang wurde abgebrochen: Standpunkt {standpunkt} kommt in der CSV öfter vor als in der JXL.")
f"❌ Der Vorgang wurde abgebrochen: Standpunkt {standpunkt} kommt in der CSV öfter vor als in der JXL.")
break
station_id, ih = liste_records[zaehler]
@@ -545,7 +545,7 @@ class Import:
writer.writerow(row)
if Import_fortsetzen:
print(f"Korrektur erfolgreich abgeschlossen. Ausgabe: {pfad_datei_csv_out}")
print(f"✅ Korrektur erfolgreich abgeschlossen. Ausgabe: {pfad_datei_csv_out}")
print(f"Ersetzungen in der CSV-Datei (Rundung -> JXL volle Nachkommastellen): {dict_ersetzungen}")
# Ausgabe der Zeilennummern in der JXL-Datei ohne Instrumentenhöhe
@@ -566,7 +566,7 @@ class Import:
print(f"Anzahl: {len(liste_zeilen_standpunkt_nicht_in_jxl)}")
print(liste_zeilen_standpunkt_nicht_in_jxl)
else:
print("Die Korrektur der CSV-Datei wurde abgebrochen.")
print("❌ Die Korrektur der CSV-Datei wurde abgebrochen.")
return {
"Import_fortsetzen": Import_fortsetzen,
@@ -716,7 +716,7 @@ class Import:
if liste_fehlerhafte_zeile != []:
fehler_zeilen = ", ".join(map(str, liste_fehlerhafte_zeile))
print(
f"Das Einlesen der Datei {pfad_datei} wurde abgebrochen.\n"
f"❌ Das Einlesen der Datei {pfad_datei} wurde abgebrochen.\n"
f"Bitte bearbeiten Sie die Zeilen rund um: {fehler_zeilen} in der csv-Datei "
f"und wiederholen Sie den Import."
)
@@ -724,7 +724,7 @@ class Import:
else:
print(
f"Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
f"❌ Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
if Import_fortsetzen:
liste_beobachtungen_import = []
@@ -756,13 +756,13 @@ class Import:
prismenhoehe = liste_aktueller_zielpunkt[8]
else:
Import_fortsetzen = False
print(f"Der Import wurde abgebrochen, weil für zwei Halbsätze vom Standpunkt {liste_aktueller_zielpunkt[3]} zum Zielpunkt {aktueller_zielpunkt} unterschiedliche Prismenhöhen vorliegen. Bitte in der Datei {pfad_datei} korrigieren und Import neustarten.")
print(f"❌ Der Import wurde abgebrochen, weil für zwei Halbsätze vom Standpunkt {liste_aktueller_zielpunkt[3]} zum Zielpunkt {aktueller_zielpunkt} unterschiedliche Prismenhöhen vorliegen. Bitte in der Datei {pfad_datei} korrigieren und Import neustarten.")
if liste_aktueller_zielpunkt[9] == liste[9]:
instrumentenhoehe_import = liste_aktueller_zielpunkt[9]
else:
Import_fortsetzen = False
print(f"Der Import wurde abgebrochen, weil für zwei Halbsätze vom Standpunkt {liste_aktueller_zielpunkt[3]} zum Zielpunkt {aktueller_zielpunkt} unterschiedliche Instrumentenhöhen vorliegen. Bitte in der Datei {pfad_datei} korrigieren und Import neustarten.")
print(f"❌ Der Import wurde abgebrochen, weil für zwei Halbsätze vom Standpunkt {liste_aktueller_zielpunkt[3]} zum Zielpunkt {aktueller_zielpunkt} unterschiedliche Instrumentenhöhen vorliegen. Bitte in der Datei {pfad_datei} korrigieren und Import neustarten.")
# Umrechnen der Zenitwinkel und Schrägdistanzen auf den Boden unter Verwendung der Instrumenten- und Prismenhöhen
schraegdistanz_bodenbezogen, zenitwinkel_bodenbezogen = self.berechnungen.berechne_zenitwinkel_distanz_bodenbezogen(
@@ -779,7 +779,7 @@ class Import:
if instrumentenID not in liste_instrumentenid:
Import_fortsetzen = False
print(
"Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
"❌ Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
# Berechnete bodenbezogene Beobachtungen, welche jeweils auf den Vollsatz reduziert sind, in die Tabelle Beobachtungen importieren.
if Import_fortsetzen:
@@ -794,7 +794,7 @@ class Import:
con.commit()
cursor.close()
con.close()
print(f"Der Import der Datei {pfad_datei} wurde erfolgreich abgeschlossen.")
print(f"✅ Der Import der Datei {pfad_datei} wurde erfolgreich abgeschlossen.")
def vorbereitung_import_beobachtungen_nivellement_naeherung_punkthoehen(self, pfad_datei: str,
instrumentenID: int) -> None | tuple[None, None] | tuple[dict[Any, Any], list[Any]]:
@@ -835,14 +835,14 @@ class Import:
# Abbruch des Imports, wenn bereits Daten aus der Datei importiert wurden.
if pfad_datei in liste_dateinamen_in_db:
Import_fortsetzen = False
print(f"Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
print(f"❌ Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
return None, None
# Abbruch, wenn das Instrument noch nicht vom Benutzer angelegt wurde.
if instrumentenID not in liste_instrumentenid:
Import_fortsetzen = False
print(
"Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
"❌ Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
return None, None
if Import_fortsetzen:
@@ -917,7 +917,7 @@ class Import:
if dict_punkt_mittelwert_punkthoehen == None or liste_punktnummern_in_db == None or liste_punktnummern_hinzufuegen == None:
Import_fortsetzen = False
print("Der Import der Nivellementbeobachtungen wurde abgebrochen.")
print("❌ Der Import der Nivellementbeobachtungen wurde abgebrochen.")
return None
con = sqlite3.connect(self.pfad_datenbank)
@@ -993,13 +993,13 @@ class Import:
# Import abbrechen, wenn bereits Daten aus der selben Datei importiert wurden
if pfad_datei in liste_dateinamen_in_db:
Import_fortsetzen = False
print(f"Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
print(f"❌ Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
# Import abbrechen, wenn das Instrument noch nicht vom Benutzer angelegt wurde.
if instrumentenID not in liste_instrumentenid:
Import_fortsetzen = False
print(
"Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
"❌ Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
if Import_fortsetzen:
# rvvr = Rück, Vor, Vor, Rück
@@ -1171,10 +1171,10 @@ class Import:
con.commit()
cursor.close()
con.close()
return f"Die Beobachtungen aus der Datei {pfad_datei} wurden erfolgreich importiert."
return f"✅ Die Beobachtungen aus der Datei {pfad_datei} wurden erfolgreich importiert."
else:
print(f"Anzahl RVVR durch 4 teilbar. Bitte die Datei {pfad_datei} überprüfen! Der Import wurde abgebrochen.")
print(f"❌ Anzahl RVVR nicht durch 4 teilbar. Bitte die Datei {pfad_datei} überprüfen! Der Import wurde abgebrochen.")
Import_fortsetzen = False
def import_koordinaten_gnss(self, pfad_datei: str, liste_sapos_stationen_genauigkeiten: list) -> str:
@@ -1265,7 +1265,7 @@ class Import:
if instrumentenID not in liste_instrumentenid:
Import_fortsetzen = False
print(
"Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
"❌ Der Import wurde abgebrochen. Bitte eine gültige InstrumentenID eingeben. Bei Bedarf ist das Instrument neu anzulegen.")
if Import_fortsetzen:
liste_basilinien = []
@@ -1285,7 +1285,7 @@ class Import:
else:
print(
f"Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
f"❌ Der Import wurde abgebrochen, weil die Beobachtungen aus der Datei {pfad_datei} bereits in der Datenbank vorhanden sind.")
if Import_fortsetzen:
con = sqlite3.connect(self.pfad_datenbank)
@@ -1297,4 +1297,4 @@ class Import:
con.commit()
cursor.close()
con.close()
print(f"Der Import der Datei {pfad_datei} wurde erfolgreich abgeschlossen.")
print(f"✅ Der Import der Datei {pfad_datei} wurde erfolgreich abgeschlossen.")
+23 -7
View File
@@ -23,7 +23,7 @@ class Genauigkeitsmaße:
@staticmethod
def berechne_s0apost(v: np.ndarray, P: np.ndarray, r: int) -> float:
def berechne_s0apost(v: np.ndarray, P: np.ndarray, r: int, print_ausgabe = True) -> float:
"""
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit s₀.
@@ -44,7 +44,8 @@ class Genauigkeitsmaße:
vTPv_matrix = v.T @ P @ v
vTPv = vTPv_matrix.item()
s0apost = np.sqrt(vTPv / r)
print(f"s0 a posteriori beträgt: {s0apost:.4f}")
if print_ausgabe:
print(f"s0 a posteriori beträgt: {s0apost:.4f}")
return s0apost
@@ -109,7 +110,7 @@ class Genauigkeitsmaße:
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σx", "σy", "σz", f"σP_{dim}D"])
display(HTML(helmert_punktfehler.to_html(index=False)))
helmert_punktfehler.to_excel(r"Zwischenergebnisse\Standardabweichungen_Helmertscher_Punktfehler.xlsx",index=False)
helmert_punktfehler.to_excel(r"Netzqualitaet\Standardabweichungen_Helmertscher_Punktfehler.xlsx",index=False)
return helmert_punktfehler
@@ -204,7 +205,7 @@ class Genauigkeitsmaße:
standardellipse["Kleine Halbachse [m]"] = standardellipse["Kleine Halbachse [m]"].astype(float).round(4)
standardellipse["θ [gon]"] = standardellipse["θ [gon]"].astype(float).round(3)
display(HTML(standardellipse.to_html(index=False)))
standardellipse.to_excel(r"Zwischenergebnisse\Standardellipse.xlsx", index=False)
standardellipse.to_excel(r"Netzqualitaet\Standardellipse.xlsx", index=False)
return standardellipse
@@ -313,7 +314,7 @@ class Genauigkeitsmaße:
konfidenzellipse["θ [gon]"] = konfidenzellipse["θ [gon]"].round(3)
if ausgabe_erfolgt == False:
display(HTML(konfidenzellipse.to_html(index=False)))
konfidenzellipse.to_excel(r"Zwischenergebnisse\Konfidenzellipse.xlsx", index=False)
konfidenzellipse.to_excel(r"Netzqualitaet\Konfidenzellipse.xlsx", index=False)
return konfidenzellipse, alpha
@@ -388,7 +389,7 @@ class Genauigkeitsmaße:
display(HTML(Konfidenzellipse_ENU.to_html(index=False)))
# 5) Export
Konfidenzellipse_ENU.to_excel(r"Zwischenergebnisse\Konfidenzellipse_ENU.xlsx", index=False)
Konfidenzellipse_ENU.to_excel(r"Netzqualitaet\Konfidenzellipse_ENU.xlsx", index=False)
return Konfidenzellipse_ENU, R0
@@ -560,5 +561,20 @@ class Plot:
align='left', showarrow=False, xref='paper', yref='paper', x=0.02, y=0.05,
bgcolor="white", bordercolor="black", borderwidth=1
)
fig.write_image(r"Netzqualitaet\netzplot_ellipsen_volle_ausdehnung.png")
return fig
fig.show(config={'scrollZoom': True})
def plot_speichere_aktuelle_ansicht(plot, dateiname=r"Netzqualitaet\netzplot_ellipsen_zoom_ansicht.png"):
aktuelles_layout = plot.layout
export_plot = go.Figure(plot.data, layout=aktuelles_layout)
export_plot.write_image(dateiname, scale=2)
print(f"✅ Aktuelle Ansicht wurde erfolgreich gespeichert: {dateiname}")
x_bereich = aktuelles_layout.xaxis.range
y_bereich = aktuelles_layout.yaxis.range
if x_bereich and y_bereich:
print(
f"Ausschnitt: E[{x_bereich[0]:.2f} bis {x_bereich[1]:.2f}], N[{y_bereich[0]:.2f} bis {y_bereich[1]:.2f}]")
else:
print("Hinweis: Es wurde die Standardansicht (kein Zoom) gespeichert.")
+8 -5
View File
@@ -124,7 +124,7 @@ class Zuverlaessigkeit:
klassen = [Zuverlaessigkeit.klassifiziere_ri(r) for r in ri]
Redundanzanteile = pd.DataFrame({"Beobachtung": labels, "r_i": ri, "EV_i [%]": EVi, "Klassifikation": klassen, })
display(HTML(Redundanzanteile.to_html(index=False)))
Redundanzanteile.to_excel(r"Zwischenergebnisse\Redundanzanteile.xlsx", index=False)
Redundanzanteile.to_excel(r"Netzqualitaet\Redundanzanteile.xlsx", index=False)
return R, ri, EVi, Redundanzanteile
@@ -211,11 +211,11 @@ class Zuverlaessigkeit:
und der Grenzwert als NaN gesetzt.
:param v: Residuenvektor der Beobachtungen.
:type v: array_like
:type v: np.asarray
:param Q_vv: Kofaktor-Matrix der Residuen.
:type Q_vv: array_like
:type Q_vv: np.asarray
:param ri: Redundanzanteile der Beobachtungen.
:type ri: array_like
:type ri: np.asarray
:param labels: Liste der Beobachtungen zur Zuordnung in der Ergebnistabelle.
:type labels: list
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
@@ -340,7 +340,7 @@ class Zuverlaessigkeit:
gui.ausgabe_erstellen()
gui.zeige_tabelle()
Lokaltest.to_excel(r"Zwischenergebnisse\Lokaltest_innere_Zuverlaessugkeit.xlsx", index=False)
Lokaltest.to_excel(r"Netzqualitaet\Lokaltest_innere_Zuverlaessugkeit.xlsx", index=False)
return gui.ausschalten_dict, beta
@@ -563,8 +563,11 @@ class Zuverlaessigkeit:
"SP_3D [mm]": SP_m * 1000.0,
"EF*SP_3D [mm]": EF_SP_m * 1000.0,
})
display(HTML(aeussere_zuverlaessigkeit.to_html(index=False)))
aeussere_zuverlaessigkeit.to_excel(r"Netzqualitaet\Aeussere_Zuverlaessigkeit.xlsx", index=False)
return aeussere_zuverlaessigkeit
class LokaltestInnereZuverlaessigkeitGUI:
"""Interaktive Auswahloberfläche für den Lokaltest (innere Zuverlässigkeit).
+11 -11
View File
@@ -8,11 +8,11 @@ def atpv_probe(A, P, v, tol=1e-7):
Die Prüfung erfolgt unter Verwendung einer vorgegebenen Toleranz.
:param A: Jacobi-Matrix (A-Matrix).
:type A: array_like
:type A: np.asarray
:param P: Gewichtsmatrix der Beobachtungen.
:type P: array_like
:type P: np.asarray
:param v: Residuenvektor der Beobachtungen.
:type v: array_like
:type v: np.asarray
:param tol: Absolute Toleranz für den Vergleich mit Null.
:type tol: float
:return: None
@@ -25,9 +25,9 @@ def atpv_probe(A, P, v, tol=1e-7):
ATPV = A.T @ P @ v
if np.allclose(ATPV, 0, atol=tol):
print("ATPv-Probe erfolgreich")
print("✅ ATPv-Probe erfolgreich")
else:
print("ATPv-Probe nicht erfolgreich. Fehler bei der Lösung des Normalgleichungssystems")
print("❌ ATPv-Probe nicht erfolgreich. Fehler bei der Lösung des Normalgleichungssystems")
def hauptprobe(A, x, l, v, tol=1e-7):
@@ -40,13 +40,13 @@ def hauptprobe(A, x, l, v, tol=1e-7):
innerhalb der Toleranz überein, gilt die Ausgleichung als konsistent.
:param A: Jacobi-Matrix (A-Matrix).
:type A: array_like
:type A: np.asarray
:param x: Lösungsvektor der Unbekannten.
:type x: array_like
:type x: np.asarray
:param l: Beobachtungsvektor.
:type l: array_like
:type l: np.asarray
:param v: Residuenvektor aus der Ausgleichung.
:type v: array_like
:type v: np.asarray
:param tol: Absolute Toleranz für den Vergleich der Residuen.
:type tol: float
:return: None
@@ -60,7 +60,7 @@ def hauptprobe(A, x, l, v, tol=1e-7):
v_test = A @ x - l
if np.allclose(v, v_test, atol=tol):
print("Hauptprobe erfolgreich")
print("✅ Hauptprobe erfolgreich")
else:
diff = v - v_test
print("Hauptprobe nicht erfolgreich. Abweichung zu v: ", diff)
print("❌ Hauptprobe nicht erfolgreich. Abweichung zu v: ", diff)
+32 -27
View File
@@ -41,7 +41,7 @@ class VKS:
self.db_zugriff = Datenbank.Datenbankzugriff(self.pfad_datenbank)
def varianzkomponten_berechnen(self, Jacobimatrix_symbolisch_liste_beobachtungsvektor: list, res: dict, R: np.ndarray) -> None:
def varianzkomponten_berechnen(self, Jacobimatrix_symbolisch_liste_beobachtungsvektor: list, res: dict, R: np.ndarray) -> pd.DataFrame:
"""Berechnet a-posteriori Varianzen und a-posteriori Standardabweichungen je Beobachtungsgruppe.
Teilt die Residuen v, die Gewichtsmatrix P sowie die Redundanzmatrix R gemäß der in
@@ -57,10 +57,12 @@ class VKS:
:type res: dict
:param R: Redundanzmatrix (z. B. aus R = Q_vv @ P oder äquivalent), passend zu v/P dimensioniert.
:type R: np.ndarray
:return: None
:rtype: None
:return: DataFrame mit den Spalten 'Beobachtungsgruppe', 'Standardabweichung', 'Varianz'
:rtype: pd.DataFrame
"""
liste_ergebnisse = []
# Zeilen- und Spaltennummern der jeweiligen Beobachtungsgruppe, z.B. SD für Schrägdistanz ermitteln
dict_indizes_beobachtungsgruppen = Datumsfestlegung.Datumsfestlegung.indizes_beobachtungsvektor_nach_beobachtungsgruppe(
Jacobimatrix_symbolisch_liste_beobachtungsvektor)
@@ -76,10 +78,10 @@ class VKS:
aufgeteilt_P_SD = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_SD = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_SD = sum(np.diag(aufgeteilt_R_SD))
s0_aposteriori_SD = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_SD, aufgeteilt_P_SD, ri_SD)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_SD:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_SD ** 2:.4f}")
s0_aposteriori_SD = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_SD, aufgeteilt_P_SD, ri_SD, False)
liste_ergebnisse.append(
{"Beobachtungsgruppe": beobachtungsgruppe, "Standardabweichung a posteriori": s0_aposteriori_SD,
"Varianz a posteriori": s0_aposteriori_SD ** 2})
# R = Tachymeter Richtungsbeobachtungen
if beobachtungsgruppe == "R":
@@ -87,10 +89,10 @@ class VKS:
aufgeteilt_P_R = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_R = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_R = sum(np.diag(aufgeteilt_R_R))
s0_aposteriori_R = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_R, aufgeteilt_P_R, ri_R)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_R:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_R ** 2:.4f}")
s0_aposteriori_R = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_R, aufgeteilt_P_R, ri_R, False)
liste_ergebnisse.append(
{"Beobachtungsgruppe": beobachtungsgruppe, "Standardabweichung a posteriori": s0_aposteriori_R,
"Varianz a posteriori": s0_aposteriori_R ** 2})
# ZW = Tachymeter Zenitwinkelbeobachtung
if beobachtungsgruppe == "ZW":
@@ -98,10 +100,10 @@ class VKS:
aufgeteilt_P_ZW = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_ZW = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_ZW = sum(np.diag(aufgeteilt_R_ZW))
s0_aposteriori_ZW = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_ZW, aufgeteilt_P_ZW, ri_ZW)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_ZW:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_ZW ** 2:.4f}")
s0_aposteriori_ZW = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_ZW, aufgeteilt_P_ZW, ri_ZW, False)
liste_ergebnisse.append(
{"Beobachtungsgruppe": beobachtungsgruppe, "Standardabweichung a posteriori": s0_aposteriori_ZW,
"Varianz a posteriori": s0_aposteriori_ZW ** 2})
# GNSS = GNSS-Basisilinien
if beobachtungsgruppe == "gnss":
@@ -109,10 +111,10 @@ class VKS:
aufgeteilt_P_gnss = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_gnss = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_gnss = sum(np.diag(aufgeteilt_R_gnss))
s0_aposteriori_gnss = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_gnss, aufgeteilt_P_gnss, ri_gnss)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_gnss:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_gnss ** 2:.4f}")
s0_aposteriori_gnss = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_gnss, aufgeteilt_P_gnss, ri_gnss, False)
liste_ergebnisse.append(
{"Beobachtungsgruppe": beobachtungsgruppe, "Standardabweichung a posteriori": s0_aposteriori_gnss,
"Varianz a posteriori": s0_aposteriori_gnss ** 2})
# niv = geometrisches Nivellement
if beobachtungsgruppe == "niv":
@@ -120,10 +122,10 @@ class VKS:
aufgeteilt_P_niv = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_niv = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_niv = sum(np.diag(aufgeteilt_R_niv))
s0_aposteriori_niv = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_niv, aufgeteilt_P_niv, ri_niv)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_niv:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_niv ** 2:.4f}")
s0_aposteriori_niv = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_niv, aufgeteilt_P_niv, ri_niv, False)
liste_ergebnisse.append(
{"Beobachtungsgruppe": beobachtungsgruppe, "Standardabweichung a posteriori": s0_aposteriori_niv,
"Varianz a posteriori": s0_aposteriori_niv ** 2})
# lA = Anschlusspunkte für die weiche Lagerung
if beobachtungsgruppe == "lA":
@@ -131,10 +133,13 @@ class VKS:
aufgeteilt_P_lA = res["P"][z_start: z_ende + 1, s_start: s_ende + 1]
aufgeteilt_R_lA = R[z_start: z_ende + 1, s_start: s_ende + 1]
ri_lA = sum(np.diag(aufgeteilt_R_lA))
s0_aposteriori_lA = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_lA, aufgeteilt_P_lA, ri_lA)
print(f"s0 aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_lA:.4f}")
print(
f"Varianz aposteriori der Beobachtungsgruppe {beobachtungsgruppe} beträgt: {s0_aposteriori_lA ** 2:.4f}")
s0_aposteriori_lA = Genauigkeitsmaße.berechne_s0apost(aufgeteilt_v_lA, aufgeteilt_P_lA, ri_lA, False)
liste_ergebnisse.append(
{"Beobachtungsgruppe": beobachtungsgruppe, "Standardabweichung a posteriori": s0_aposteriori_lA,
"Varianz a posteriori": s0_aposteriori_lA ** 2})
df_varianzkomponenten = pd.DataFrame(liste_ergebnisse)
return df_varianzkomponenten
def vks_ausfuehren(self) -> None:
"""Initialisiert die interaktive VKS-Eingabetabelle.