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

File diff suppressed because one or more lines are too long

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
Export.py
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)}

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.")

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.")

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).

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)

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.