1017 lines
54 KiB
Python
1017 lines
54 KiB
Python
from decimal import Decimal
|
|
import os
|
|
import pandas as pd
|
|
import sqlite3
|
|
import sympy as sp
|
|
from sympy import MutableDenseMatrix
|
|
from typing import Any
|
|
|
|
from Einheitenumrechnung import Einheitenumrechnung
|
|
|
|
class Datenbank_anlegen:
|
|
"""Legt die SQLite-Datenbank für die Ausgleichungsrechnung an.
|
|
|
|
Die Klasse erstellt die Datenbankdatei nur dann, wenn am angegebenen Pfad noch
|
|
keine Datenbank existiert. In diesem Fall werden die Tabellen und Constraints
|
|
per SQL-Skript angelegt.
|
|
|
|
Angelegte Tabellen:
|
|
- Netzpunkte,
|
|
- Beobachtungen,
|
|
- Instrumente,
|
|
- Genauigkeiten,
|
|
- Varianzkomponentenschaetzung.
|
|
|
|
:ivar pfad_datenbank: Pfad zur SQLite-Datenbankdatei.
|
|
:vartype pfad_datenbank: str
|
|
"""
|
|
def __init__(self, pfad_datenbank: str) -> None:
|
|
"""Initialisiert den Datenbankpfad und legt die Datenbank bei Bedarf an.
|
|
|
|
Beim Erstellen der Instanz wird db_anlegen() aufgerufen. Existiert die
|
|
Datenbankdatei unter dem übergebenen Pfad bereits, erfolgt keine Änderung.
|
|
|
|
:param pfad_datenbank: Pfad zur SQLite-Datenbankdatei.
|
|
:type pfad_datenbank: str
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
self.pfad_datenbank = pfad_datenbank
|
|
self.db_anlegen()
|
|
|
|
def db_anlegen(self) -> None:
|
|
"""Legt die SQLite-Datenbank an, sofern die Datei nicht existiert.
|
|
|
|
Prüft, ob die Datenbankdatei am Pfad vorhanden ist. Falls nicht, wird eine neue
|
|
SQLite-Datenbank erstellt.
|
|
Anschließend werden die Änderungen committet und die Verbindung geschlossen.
|
|
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
if not os.path.exists(self.pfad_datenbank):
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
cursor.executescript("""CREATE TABLE Netzpunkte (
|
|
punktnummer TEXT(10),
|
|
naeherungx_lh NUMERIC(9,3),
|
|
naeherungy_lh NUMERIC(7,3),
|
|
naeherungz_lh NUMERIC(8,3),
|
|
naeherungz_lh_niv NUMERIC(8,3),
|
|
naeherungx_us NUMERIC(9,3),
|
|
naeherungy_us NUMERIC(7,3),
|
|
naeherungz_us NUMERIC(8,3),
|
|
normalhoehe_hfp NUMERIC(5,3),
|
|
datumskoordinate_x INTEGER DEFAULT 0,
|
|
datumskoordinate_y INTEGER DEFAULT 0,
|
|
datumskoordinate_z INTEGER DEFAULT 0,
|
|
stabw_vorinfo_x NUMERIC(3, 8),
|
|
stabw_vorinfo_y NUMERIC(3, 8),
|
|
stabw_vorinfo_z NUMERIC(3, 8),
|
|
CONSTRAINT pk_Netzpunkte PRIMARY KEY (punktnummer)
|
|
);
|
|
""");
|
|
cursor.executescript("""CREATE TABLE Beobachtungen(
|
|
beobachtungenID INTEGER,
|
|
beobachtungsgruppeID INTEGER,
|
|
punktnummer_sp TEXT(10),
|
|
punktnummer_zp TEXT(10),
|
|
instrumenteID INTEGER,
|
|
tachymeter_richtung NUMERIC(8, 6),
|
|
tachymeter_richtung_ausschalten INTEGER DEFAULT 0,
|
|
tachymeter_zenitwinkel_roh NUMERIC(8, 6),
|
|
tachymeter_zenitwinkel NUMERIC(8, 6),
|
|
tachymeter_zenitwinkel_ausschalten INTEGER DEFAULT 0,
|
|
tachymeter_distanz_roh NUMERIC(8, 4),
|
|
tachymeter_distanz NUMERIC(8, 4),
|
|
tachymeter_distanz_auschalten INTEGER DEFAULT 0,
|
|
tachymeter_instrumentenhoehe NUMERIC(3, 8),
|
|
tachymeter_prismenhoehe NUMERIC(3, 8),
|
|
gnss_bx NUMERIC(7, 4),
|
|
gnss_bx_ausschalten INTEGER DEFAULT 0,
|
|
gnss_by NUMERIC(7, 4),
|
|
gnss_by_ausschalten INTEGER DEFAULT 0,
|
|
gnss_bz NUMERIC(7, 4),
|
|
gnss_bz_ausschalten INTEGER DEFAULT 0,
|
|
gnss_s0 NUMERIC(1, 8),
|
|
gnss_cxx NUMERIC(1, 8),
|
|
gnss_cxy NUMERIC(1, 8),
|
|
gnss_cxz NUMERIC(1, 8),
|
|
gnss_cyy NUMERIC(1, 8),
|
|
gnss_cyz NUMERIC(1, 8),
|
|
gnss_czz NUMERIC(1, 8),
|
|
niv_dh NUMERIC(8, 6),
|
|
niv_strecke NUMERIC(8, 6),
|
|
niv_anz_standpkte INTEGER,
|
|
niv_ausschalten INTEGER DEFAULT 0,
|
|
dateiname TEXT(200),
|
|
CONSTRAINT pk_Beobachtungen PRIMARY KEY (beobachtungenID),
|
|
CONSTRAINT fk_Beobachtungen_Netzpunktesp FOREIGN KEY (punktnummer_sp) REFERENCES Netzpunkte(punktnummer),
|
|
CONSTRAINT fk_Beobachtungen_Netzpunktezp FOREIGN KEY (punktnummer_zp) REFERENCES Netzpunkte(punktnummer),
|
|
CONSTRAINT fk_Beobachtungen_Instrumente FOREIGN KEY (instrumenteID) REFERENCES Instrumente(instrumenteID)
|
|
);
|
|
""");
|
|
cursor.executescript("""CREATE TABLE Instrumente(
|
|
instrumenteID INTEGER,
|
|
typ TEXT(200),
|
|
name TEXT(200),
|
|
CONSTRAINT pk_Instrumente PRIMARY KEY (instrumenteID)
|
|
);
|
|
""");
|
|
cursor.executescript("""CREATE TABLE Genauigkeiten(
|
|
genauigkeitenID INTEGER,
|
|
instrumenteID INTEGER,
|
|
beobachtungsart TEXT(25),
|
|
stabw_apriori_konstant NUMERIC(3, 8),
|
|
stabw_apriori_streckenprop NUMERIC(3, 8),
|
|
CONSTRAINT pk_Genauigkeiten PRIMARY KEY (genauigkeitenID),
|
|
CONSTRAINT fk_Genauigkeiten_Instrumente FOREIGN KEY (instrumenteID) REFERENCES Instrumente(instrumenteID)
|
|
);
|
|
""");
|
|
cursor.executescript("""CREATE TABLE Varianzkomponentenschaetzung(
|
|
varianzkomponenteID INTEGER,
|
|
instrumenteID INTEGER,
|
|
beobachtungsgruppe TEXT(50),
|
|
varianz_varianzkomponentenschaetzung NUMERIC(3, 16) DEFAULT 1,
|
|
CONSTRAINT pk_Varianzkomponentenschaetzung PRIMARY KEY (varianzkomponenteID),
|
|
CONSTRAINT fk_Varianzkomponentenschaetzung_Instrumente FOREIGN KEY (instrumenteID) REFERENCES Instrumente(instrumenteID)
|
|
);
|
|
""")
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
class Datenbankzugriff:
|
|
"""Zugriff auf die SQLite-Datenbank des Ausgleichungsprogramms.
|
|
|
|
Die Klasse stellt Methoden zur Verfügung für:
|
|
|
|
- Schreiben in die Datenbank durch alle set_* Methoden
|
|
- Lesen aus der Datenbank durch alle get_* Methoden
|
|
- Darstellen der aus der Datenbenak gelesenen Daten in tabellarischer Form durch alle tabelle_* Methoden
|
|
|
|
:ivar pfad_datenbank: Pfad zur SQLite-Datenbankdatei.
|
|
:vartype pfad_datenbank: str
|
|
"""
|
|
def __init__(self, pfad_datenbank: str) -> None:
|
|
"""Initialisiert den Datenbankzugriff.
|
|
|
|
:param pfad_datenbank: Pfad zur SQLite-Datenbankdatei.
|
|
:type pfad_datenbank: str
|
|
"""
|
|
self.pfad_datenbank = pfad_datenbank
|
|
|
|
def set_koordinaten(self, dict_koordinaten: dict, koordinatenart: str) -> None:
|
|
"""Schreibt Koordinaten in die Tabelle Netzpunkte.
|
|
|
|
Die Koordinaten werden aus `dict_koordinaten` gelesen und abhängig von der koordinatenart
|
|
in die entsprechenden Felder geschrieben. Es werden nur Einträge aktualisiert, deren
|
|
Zielspalten aktuell ``NULL`` sind.
|
|
|
|
:param dict_koordinaten: Dictionary mit Punktnummer → (X, Y, Z).
|
|
:type dict_koordinaten: dict
|
|
:param koordinatenart: Art der Koordinaten ("naeherung_lh" für die Koordinaten im lokalen Horizontsystem aus der Tachymetermessung oder "naeherung_us" für die Näherungskoordinaten der Netzpunkte im geozentrisch-kartesischen-system).
|
|
:type koordinatenart: str
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
|
|
daten = []
|
|
|
|
for punktnummer, wert in dict_koordinaten.items():
|
|
daten.append((
|
|
float(wert[0]),
|
|
float(wert[1]),
|
|
float(wert[2]),
|
|
str(punktnummer)
|
|
))
|
|
# Der Import für die Koordinatenart "naeherung_lh" ist im Zuge möglicher Erweiterungen zu implementieren.
|
|
if koordinatenart == "naeherung_lh":
|
|
pass
|
|
elif koordinatenart == "naeherung_us":
|
|
cursor.executemany(f"""UPDATE Netzpunkte SET naeherungx_us = ?, naeherungy_us = ?, naeherungz_us = ? WHERE punktnummer = ? AND naeherungx_us IS NULL AND naeherungy_us IS NULL AND naeherungz_us IS NULL""", daten)
|
|
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def set_instrument(self, typ: str, name: str, liste_beobachtungsarten: list) -> None:
|
|
"""Fügt ein Instrument hinzu und initialisiert Varianzkomponenten.
|
|
|
|
Ist das Instrument (typ, name) noch nicht in der Datenbank vorhanden, wird es in die Tabelle Instrumente eingefügt.
|
|
Zusätzlich werden Einträge in Varianzkomponentenschaetzung für die angegebenen
|
|
Beobachtungsarten erzeugt. Falls die Varianzkomponentenschätzung noch leer ist, wird
|
|
ein zusätzlicher Eintrag für die Beobachtungsgruppe "Anschlusspunkte" angelegt.
|
|
|
|
:param typ: Instrumenttyp.
|
|
:type typ: str
|
|
:param name: Instrumentname.
|
|
:type name: str
|
|
:param liste_beobachtungsarten: Liste der Beobachtungsgruppen zur Initialisierung.
|
|
:type liste_beobachtungsarten: list
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_instrumente = cursor.execute("SELECT * FROM Instrumente WHERE typ = ? AND name =?", (typ, name)).fetchall()
|
|
if liste_instrumente == []:
|
|
cursor.execute(
|
|
"INSERT INTO Instrumente (typ, name) VALUES (?, ?)", (typ, name)
|
|
)
|
|
id_instrument = cursor.lastrowid
|
|
print(f"Das Instrument {name} wurde erfolgreich hinzugefügt.")
|
|
|
|
if self.get_varianzkomponentenschaetzung() == []:
|
|
cursor.execute(
|
|
"INSERT INTO Instrumente (typ, name) VALUES (?, ?)", ("Anschlusspunkte", "lA")
|
|
)
|
|
id_instrument_anschlusspunkte = cursor.lastrowid
|
|
|
|
cursor.execute(
|
|
"INSERT INTO Varianzkomponentenschaetzung (instrumenteID, beobachtungsgruppe) VALUES (?, ?)",
|
|
(id_instrument_anschlusspunkte, "Anschlusspunkte")
|
|
)
|
|
|
|
for beobachtungsart in liste_beobachtungsarten:
|
|
cursor.execute(
|
|
"INSERT INTO Varianzkomponentenschaetzung (instrumenteID, beobachtungsgruppe) VALUES (?, ?)",
|
|
(id_instrument, beobachtungsart)
|
|
)
|
|
else:
|
|
id_instrument = cursor.execute(
|
|
"SELECT instrumenteID FROM Instrumente WHERE typ = ? AND name =?", (typ, name))
|
|
print(f"Das Instrument {name} ist bereits in der Datenbank vorhanden.")
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def set_genauigkeiten(self, instrumenteID: int, beobachtungsart: str, stabw_apriori_konstant: float = None,
|
|
stabw_apriori_streckenprop: float = None) -> None:
|
|
"""Speichert a-priori Genauigkeiten für die Beobachtungsgruppen pro Instrument.
|
|
|
|
Prüft, ob instrumenteID existiert und ob mindestens eine Genauigkeitsangabe übergeben wurde.
|
|
Je nach Beobachtungsart werden Einheitenumrechnungen durchgeführt (z. B. mgon → rad bzw. mm → m).
|
|
Der Eintrag wird neu hinzugefügt, wenn in Genauigkeiten kein identischer Datensatz vorhanden ist.
|
|
Ansonsten wird der bestehende Datensatz in der Datenbank aktualisiert.
|
|
|
|
:param instrumenteID: ID des Instruments in der Tabelle Instrumente.
|
|
:type instrumenteID: int
|
|
:param beobachtungsart: Bezeichnung der Beobachtungsart.
|
|
:type beobachtungsart: str
|
|
:param stabw_apriori_konstant: Konstanter Anteil der Standardabweichung (optional).
|
|
:type stabw_apriori_konstant: float | None
|
|
:param stabw_apriori_streckenprop: Streckenproportionaler Anteil der Standardabweichung (optional).
|
|
:type stabw_apriori_streckenprop: float | None
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
|
|
# Überprüfung auf vorhandensein der Instrumentes in der Tabelle Instrumente
|
|
instrumentenname = cursor.execute("SELECT name FROM Instrumente WHERE instrumenteID = ?",
|
|
(instrumenteID, )).fetchone()
|
|
if instrumentenname is None:
|
|
print(
|
|
f"Die InstumentenID {instrumenteID} ist in der Datenbank nicht vorhanden. Bitte zuerst das Instrument hinzufügen.")
|
|
cursor.close()
|
|
con.close()
|
|
return
|
|
instrumentenname = instrumentenname[0]
|
|
|
|
# Überprüfung, ob Genauigkeitsinformationen vom Benutzer übergeben wurden.
|
|
if stabw_apriori_konstant is None and stabw_apriori_streckenprop is None:
|
|
print(
|
|
"Es wurden keine Genauigkeiten importiert. Bitte stabw_apriori_konstant und / oder stabw_apriori_streckenprop angeben.")
|
|
cursor.close()
|
|
con.close()
|
|
return
|
|
|
|
# Umrechnen der Einheiten in Radiant und Meter
|
|
if beobachtungsart == "Tachymeter_Richtung" or beobachtungsart == "Tachymeter_Zenitwinkel" :
|
|
stabw_apriori_konstant = Einheitenumrechnung.mgon_to_rad_Decimal(stabw_apriori_konstant)
|
|
|
|
if beobachtungsart == "Tachymeter_Strecke" or beobachtungsart == "Geometrisches_Nivellement":
|
|
stabw_apriori_konstant = Einheitenumrechnung.mm_to_m(stabw_apriori_konstant)
|
|
|
|
if isinstance(stabw_apriori_konstant, Decimal):
|
|
stabw_apriori_konstant = float(stabw_apriori_konstant)
|
|
|
|
if isinstance(stabw_apriori_streckenprop, Decimal):
|
|
stabw_apriori_streckenprop = float(stabw_apriori_streckenprop)
|
|
|
|
# Prüfen, ob für dieses Instrument und diese Art bereits ein Eintrag existiert
|
|
vorhanden = cursor.execute("SELECT 1 FROM Genauigkeiten WHERE instrumenteID = ? AND beobachtungsart = ?",
|
|
(instrumenteID, beobachtungsart)).fetchone()
|
|
|
|
if vorhanden:
|
|
# Bestehenden Datensatz aktualisieren
|
|
cursor.execute(
|
|
"UPDATE Genauigkeiten SET stabw_apriori_konstant = ?, stabw_apriori_streckenprop = ? WHERE instrumenteID = ? AND beobachtungsart = ?",
|
|
(stabw_apriori_konstant, stabw_apriori_streckenprop, instrumenteID, beobachtungsart)
|
|
)
|
|
print(f"Die Genauigkeitsangabe für {beobachtungsart} (Instrument: {instrumentenname}) wurde aktualisiert.")
|
|
else:
|
|
# Neuen Datensatz anlegen
|
|
if stabw_apriori_konstant is not None and stabw_apriori_streckenprop is not None:
|
|
cursor.execute(
|
|
"INSERT INTO Genauigkeiten (instrumenteID, beobachtungsart, stabw_apriori_konstant, stabw_apriori_streckenprop) VALUES (?, ?, ?, ?)",
|
|
(instrumenteID, beobachtungsart, stabw_apriori_konstant, stabw_apriori_streckenprop)
|
|
)
|
|
elif stabw_apriori_konstant is None:
|
|
cursor.execute(
|
|
"INSERT INTO Genauigkeiten (instrumenteID, beobachtungsart, stabw_apriori_streckenprop) VALUES (?, ?, ?)",
|
|
(instrumenteID, beobachtungsart, stabw_apriori_streckenprop)
|
|
)
|
|
else:
|
|
cursor.execute(
|
|
"INSERT INTO Genauigkeiten (instrumenteID, beobachtungsart, stabw_apriori_konstant) VALUES (?, ?, ?)",
|
|
(instrumenteID, beobachtungsart, stabw_apriori_konstant)
|
|
)
|
|
print(
|
|
f"Die Genauigkeitsangabe für {beobachtungsart} (Instrument: {instrumentenname}) wurde erfolgreich hinzugefügt.")
|
|
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def set_datumskoordinaten(self, liste_datumskoordinaten_x: list, liste_datumskoordinaten_y: list,
|
|
liste_datumskoordinaten_z: list,
|
|
liste_datumskoordinaten_x_y_z: list) -> None:
|
|
"""Setzt Datumskoordinaten für Netzpunkte unter Berücksichtigung von Vorinformationen.
|
|
|
|
Für die übergebenen Punktlisten werden die Felder datumskoordinate_x, datumskoordinate_y
|
|
und / oder datumskoordinate_z auf 1 gesetzt. Ein Setzen erfolgt nur, wenn zu der jeweiligen Koordinate
|
|
eine Vorinformation zur Standardabweichung (stabw_vorinfo_*) vorhanden ist. Eine 1 bedeutet,
|
|
dass dieser Punkt für die Datumdefinition verwendet wird.
|
|
|
|
:param liste_datumskoordinaten_x: Liste der Punktnummern mit Datumsdefinition in X.
|
|
:type liste_datumskoordinaten_x: list
|
|
:param liste_datumskoordinaten_y: Liste der Punktnummern mit Datumsdefinition in Y.
|
|
:type liste_datumskoordinaten_y: list
|
|
:param liste_datumskoordinaten_z: Liste der Punktnummern mit Datumsdefinition in Z.
|
|
:type liste_datumskoordinaten_z: list
|
|
:param liste_datumskoordinaten_x_y_z: Liste der Punktnummern mit Datumsdefinition in X, Y und Z.
|
|
:type liste_datumskoordinaten_x_y_z: list
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
|
|
# Überprüfen, ob Genauigkeitsinformationen zu den Punkten in der Datenbank gespeichert sind. Ist dies der Fall, wird eine 1 in das entsprechende Tupel geschrieben.
|
|
liste_stabw_vorinfo_x = [str(row[0]).strip() for row in cursor.execute(
|
|
"SELECT punktnummer FROM Netzpunkte WHERE stabw_vorinfo_x IS NOT NULL").fetchall()]
|
|
liste_stabw_vorinfo_y = [str(row[0]).strip() for row in cursor.execute(
|
|
"SELECT punktnummer FROM Netzpunkte WHERE stabw_vorinfo_y IS NOT NULL").fetchall()]
|
|
liste_stabw_vorinfo_z = [str(row[0]).strip() for row in cursor.execute(
|
|
"SELECT punktnummer FROM Netzpunkte WHERE stabw_vorinfo_z IS NOT NULL").fetchall()]
|
|
liste_stabw_vorinfo_x_y_z = [str(row[0]).strip() for row in cursor.execute(
|
|
"SELECT punktnummer FROM Netzpunkte WHERE stabw_vorinfo_x IS NOT NULL AND stabw_vorinfo_y IS NOT NULL AND stabw_vorinfo_z IS NOT NULL").fetchall()]
|
|
|
|
if liste_datumskoordinaten_x != []:
|
|
for punktnummer in liste_datumskoordinaten_x:
|
|
punktnummer = str(punktnummer).strip()
|
|
if punktnummer in liste_stabw_vorinfo_x:
|
|
cursor.execute(f"UPDATE Netzpunkte SET datumskoordinate_x = 1 WHERE punktnummer = ? AND stabw_vorinfo_x IS NOT NULL", (str(punktnummer),))
|
|
else:
|
|
print(f"Die X-Koordinate des Punktes {punktnummer} wurde nicht in eine Datumskoordinate geändert, weil keine Vorinformationen zur Standardabweichung der X-Koordinate des Punktes vorliegen. Diese bitte zuerst erfassen und Datumsdefinition wiederholen.")
|
|
|
|
if liste_datumskoordinaten_y != []:
|
|
for punktnummer in liste_datumskoordinaten_y:
|
|
punktnummer = str(punktnummer).strip()
|
|
if punktnummer in liste_stabw_vorinfo_y:
|
|
cursor.execute(f"UPDATE Netzpunkte SET datumskoordinate_y = 1 WHERE punktnummer = ? AND stabw_vorinfo_y IS NOT NULL", (str(punktnummer),))
|
|
else:
|
|
print(f"Die Y-Koordinate des Punktes {punktnummer} wurde nicht in eine Datumskoordinate geändert, weil keine Vorinformationen zur Standardabweichung der Y-Koordinate des Punktes vorliegen. Diese bitte zuerst erfassen und Datumsdefinition wiederholen.")
|
|
|
|
if liste_datumskoordinaten_z != []:
|
|
for punktnummer in liste_datumskoordinaten_z:
|
|
punktnummer = str(punktnummer).strip()
|
|
if punktnummer in liste_stabw_vorinfo_z:
|
|
cursor.execute(f"UPDATE Netzpunkte SET datumskoordinate_z = 1 WHERE punktnummer = ? AND stabw_vorinfo_z IS NOT NULL", (str(punktnummer),))
|
|
else:
|
|
print(f"Die Z-Koordinate des Punktes {punktnummer} wurde nicht in eine Datumskoordinate geändert, weil keine Vorinformationen zur Standardabweichung der Z-Koordinate des Punktes vorliegen. Diese bitte zuerst erfassen und Datumsdefinition wiederholen.")
|
|
|
|
if liste_datumskoordinaten_x_y_z != []:
|
|
for punktnummer in liste_datumskoordinaten_x_y_z:
|
|
punktnummer = str(punktnummer).strip()
|
|
if punktnummer in liste_stabw_vorinfo_x_y_z:
|
|
cursor.execute(f"UPDATE Netzpunkte SET datumskoordinate_x = 1, datumskoordinate_y = 1, datumskoordinate_z = 1 WHERE punktnummer = ? AND stabw_vorinfo_x IS NOT NULL AND stabw_vorinfo_y IS NOT NULL AND stabw_vorinfo_z IS NOT NULL", (str(punktnummer),))
|
|
else:
|
|
print(f"Der Punkt {punktnummer} wurde nicht in einen Datumspunkt geändert, weil nicht alle Vorinformationen zur Standardabweichung der Koordinaten des Punktes vorliegen. Diese bitte zuerst erfassen und Datumsdefinition wiederholen.")
|
|
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def set_datumskoordinaten_to_neupunkte(self, liste_datumskoordinaten_x: list, liste_datumskoordinaten_y: list,
|
|
liste_datumskoordinaten_z: list,
|
|
liste_datumskoordinaten_x_y_z: list) -> None:
|
|
"""Setzt Datumskoordinaten für angegebene Punkte wieder zurück.
|
|
|
|
Für die übergebenen Punktlisten werden die Felder datumskoordinate_x, datumskoordinate_y
|
|
und / oder datumskoordinate_z auf 0 gesetzt. Dadurch werden diese in der Ausgleichung wieder
|
|
als Neupunkte behandelt und werden nicht für die Datumsdefinition verwendet.
|
|
|
|
:param liste_datumskoordinaten_x: Liste der Punktnummern, deren X-Datumsfestlegung zurückgesetzt wird.
|
|
:type liste_datumskoordinaten_x: list
|
|
:param liste_datumskoordinaten_y: Liste der Punktnummern, deren Y-Datumsfestlegung zurückgesetzt wird.
|
|
:type liste_datumskoordinaten_y: list
|
|
:param liste_datumskoordinaten_z: Liste der Punktnummern, deren Z-Datumsfestlegung zurückgesetzt wird.
|
|
:type liste_datumskoordinaten_z: list
|
|
:param liste_datumskoordinaten_x_y_z: Liste der Punktnummern, deren X-, Y- und Z-Datumsfestlegung zurückgesetzt werden.
|
|
:type liste_datumskoordinaten_x_y_z: list
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
|
|
# Überprüfung, ob eine Benutzereingabe in der entsprechenden Liste vorgenommen wurde. Wenn ja, wird ein UPDATE in der Datenbank durchgeführt.
|
|
if liste_datumskoordinaten_x != []:
|
|
for punktnummer in liste_datumskoordinaten_x:
|
|
punktnummer = str(punktnummer).strip()
|
|
cursor.execute(
|
|
f"UPDATE Netzpunkte SET datumskoordinate_x = 0 WHERE punktnummer = ?",
|
|
(str(punktnummer),))
|
|
|
|
if liste_datumskoordinaten_y != []:
|
|
for punktnummer in liste_datumskoordinaten_y:
|
|
punktnummer = str(punktnummer).strip()
|
|
cursor.execute(
|
|
f"UPDATE Netzpunkte SET datumskoordinate_y = 0 WHERE punktnummer = ?",
|
|
(str(punktnummer),))
|
|
|
|
if liste_datumskoordinaten_z != []:
|
|
for punktnummer in liste_datumskoordinaten_z:
|
|
punktnummer = str(punktnummer).strip()
|
|
cursor.execute(
|
|
f"UPDATE Netzpunkte SET datumskoordinate_z = 0 WHERE punktnummer = ?",
|
|
(str(punktnummer),))
|
|
|
|
if liste_datumskoordinaten_x_y_z != []:
|
|
for punktnummer in liste_datumskoordinaten_x_y_z:
|
|
punktnummer = str(punktnummer).strip()
|
|
cursor.execute(
|
|
f"UPDATE Netzpunkte SET datumskoordinate_x = 0, datumskoordinate_y = 0, datumskoordinate_z = 0 WHERE punktnummer = ?",
|
|
(str(punktnummer),))
|
|
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def set_normalhoehe_hfp(self, liste_normalhoehe_hfp: list) -> LiteralString | str:
|
|
"""Speichert Normalhöhen von amtlichen Höhenfestpunkten (HFP) in Netzpunkte.
|
|
|
|
Existiert die Punktnummer bereits in der Tabelle Netzpunkte, wird das Attribut normalhoehe_hfp aktualisiert.
|
|
Andernfalls wird ein neuer Datensatz mit Punktnummer und Normalhöhe eingefügt.
|
|
|
|
:param liste_normalhoehe_hfp: Liste mit HFP-Informationen (u. a. Punktnummer und Normalhöhe).
|
|
:type liste_normalhoehe_hfp: list
|
|
:return: Zusammenfassung der durchgeführten Aktualisierungen bzw. Hinweis, falls keine Daten übergeben wurden.
|
|
:rtype: str
|
|
"""
|
|
liste_hfp_in_db = self.get_normalhoehe_hfp()
|
|
if liste_normalhoehe_hfp != []:
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_punktnummern_in_db = [str(r[0]) for r in cursor.execute(
|
|
"SELECT punktnummer FROM Netzpunkte"
|
|
).fetchall()]
|
|
ausgaben = []
|
|
for hfp in liste_normalhoehe_hfp:
|
|
if str(hfp[0]) in liste_punktnummern_in_db:
|
|
cursor.execute("UPDATE Netzpunkte SET normalhoehe_hfp = ? WHERE punktnummer = ?",
|
|
(hfp[3], hfp[0])
|
|
)
|
|
ausgaben.append(f"Der HFP {hfp[0]} wurde aktualisiert.")
|
|
else:
|
|
cursor.execute(
|
|
"INSERT INTO Netzpunkte (punktnummer, normalhoehe_hfp) VALUES (?, ?)",
|
|
(hfp[0], hfp[1])
|
|
)
|
|
ausgaben.append(f"Der HFP {hfp[0]} wurde neu hinzugefügt.")
|
|
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
return "\n".join(ausgaben)
|
|
else:
|
|
return f"Es wurden keine neuen Normalhöhen übergeben. Folgende Normalhöhen sind in der Datenbank enthalten: {liste_hfp_in_db}"
|
|
|
|
def set_beobachtung_ausschalten(self, dict_beobachtung_ausschalten: dict) -> None:
|
|
"""Schaltet ausgewählte Beobachtungen für die Ausgleichung aus.
|
|
|
|
Die zu deaktivierenden Beobachtungen werden über dict_beobachtung_ausschalten übergeben.
|
|
Der Schlüssel wird ausgewertet und das zugehörige *_ausschalten-Tupel in der Datenbank
|
|
auf 1 gesetzt (z. B. Richtungen, Zenitwinkel, Strecken, GNSS-Komponenten, Geometrisches Nivellement).
|
|
Dadurch wird die jeweilige Beobachtung in allen folgenden Iterationen nicht mehr berücksichtigt.
|
|
|
|
:param dict_beobachtung_ausschalten: Dictionary zur Steuerung, welche Beobachtungen deaktiviert werden, in der Form: {Beobachtung: "beobachtung_ausschalten"} zum ausschalten und {Beobachtung: ""} fürs beibehalten.
|
|
:type dict_beobachtung_ausschalten: dict
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
|
|
for beobachtung, ausschalten in dict_beobachtung_ausschalten.items():
|
|
# Nur in die Schleife gehen, wenn im Value des Dicts "beobachtung_ausschalten" enthalten ist.
|
|
if ausschalten == "beobachtung_ausschalten":
|
|
beobachtung_gesplittet = beobachtung.split("_")
|
|
|
|
# Distanz
|
|
if beobachtung_gesplittet[1] == "SD":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET tachymeter_distanz_auschalten = 1
|
|
WHERE beobachtungenID = ? AND beobachtungsgruppeID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3], beobachtung_gesplittet[4]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
# Richtungen
|
|
if beobachtung_gesplittet[1] == "R":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET tachymeter_richtung_ausschalten = 1
|
|
WHERE beobachtungenID = ? AND beobachtungsgruppeID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3], beobachtung_gesplittet[4]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
|
|
# Zenitwinkel
|
|
if beobachtung_gesplittet[1] == "ZW":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET tachymeter_zenitwinkel_ausschalten = 1
|
|
WHERE beobachtungenID = ? AND beobachtungsgruppeID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3], beobachtung_gesplittet[4]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
|
|
if beobachtung_gesplittet[1] == "gnssbx":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET gnss_bx_ausschalten = 1
|
|
WHERE beobachtungenID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
|
|
#GNSS-Basislinien
|
|
if beobachtung_gesplittet[1] == "gnssby":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET gnss_by_ausschalten = 1
|
|
WHERE beobachtungenID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
|
|
if beobachtung_gesplittet[1] == "gnssbz":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET gnss_bz_ausschalten = 1
|
|
WHERE beobachtungenID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
|
|
# Geometrisches Nivellement
|
|
if beobachtung_gesplittet[1] == "niv":
|
|
try:
|
|
cursor.execute(f"""UPDATE Beobachtungen SET niv_ausschalten = 1
|
|
WHERE beobachtungenID = ? AND punktnummer_sp = ? AND punktnummer_zp = ?""",
|
|
(beobachtung_gesplittet[0], beobachtung_gesplittet[2], beobachtung_gesplittet[3]))
|
|
except:
|
|
print(f"Die Beobachtung {beobachtung} konnte aufgrund eines Fehlers nicht ausgeschaltet werden.")
|
|
print("Die ausgewählten Beobachtungen werden für die folgenden Iterationen ausgeschaltet.")
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def set_varianzkomponente(self, liste_varianzkomponten_anpassen: list) -> None:
|
|
"""Passt Varianzkomponenten für die nächste Iteration an.
|
|
|
|
Für jede angegebene Varianzkomponente wird der aktuelle Datenbankwert mit einem vom Benutzer übergebenen
|
|
Faktor multipliziert und zurückgeschrieben.
|
|
|
|
:param liste_varianzkomponten_anpassen: Liste mit Einträgen (instrumenteID, beobachtungsgruppe, faktor).
|
|
:type liste_varianzkomponten_anpassen: list
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
if liste_varianzkomponten_anpassen != []:
|
|
for varianzkomponente in liste_varianzkomponten_anpassen:
|
|
# Faktor für die Varianzkomponentenschätzung der aktuellen Iteration aus der Datenbank abfragen
|
|
varianz_db = cursor.execute(f"SELECT varianz_varianzkomponentenschaetzung FROM Varianzkomponentenschaetzung WHERE instrumenteID = ? AND beobachtungsgruppe = ?",
|
|
(varianzkomponente[0], varianzkomponente[1])).fetchone()[0]
|
|
|
|
# Faktor für die Varianzkompontenschätzung aus der Datenbank mit der Benutzereingabe multiplizieren und das Produkt in der Datenbank für die nächste Iteration speichern.
|
|
cursor.execute(
|
|
f"UPDATE Varianzkomponentenschaetzung SET varianz_varianzkomponentenschaetzung = ? WHERE instrumenteID = ? AND beobachtungsgruppe = ?",
|
|
(varianz_db * varianzkomponente[2], varianzkomponente[0], varianzkomponente[1]))
|
|
print(f"Folgende Varianzkomponente wurde für die nächste Iteration gespeichert: {liste_varianzkomponten_anpassen}.")
|
|
con.commit()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
def get_koordinaten(self, koordinatenart: str, ausgabeart: str = "Dict") -> dict[Any, MutableDenseMatrix] | None:
|
|
"""Liest Koordinaten aus der Tabelle Netzpunkte.
|
|
|
|
Abhängig von der koordinatenart werden die entsprechenden Koordinatenspalten gelesen.
|
|
Es werden nur Datensätze berücksichtigt, bei denen X, Y und Z nicht NULL sind.
|
|
Bei ausgabeart="Dict" wird ein Dictionary in der Form {Punktnummer : sympy.Matrix([X, Y, Z])} zurückgegeben.
|
|
|
|
:param koordinatenart: Art der Koordinaten ("naeherung_lh" für Koordinaten im lokalen Horizontsystem aus dem Tachymeterimport oder "naeherung_us" für Näherungskoordinaten im geozentrisch-kartesischen System).
|
|
:type koordinatenart: str
|
|
:param ausgabeart: Ausgabeformat (Standard: "Dict").
|
|
:type ausgabeart: str
|
|
:return: Dictionary mit Punktnummer → Koordinatenmatrix oder None (abhängig von ausgabeart).
|
|
:rtype: dict | None
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
|
|
# Festlegen der Attribute, welche je nach Koordinatenart aus der Datenbank abgefragt werden sollen
|
|
if koordinatenart == "naeherung_lh":
|
|
values = "punktnummer, naeherungx_lh, naeherungy_lh, naeherungz_lh"
|
|
elif koordinatenart == "naeherung_us":
|
|
values = "punktnummer, naeherungx_us, naeherungy_us, naeherungz_us"
|
|
|
|
# SQL-Abfrage
|
|
liste_koordinaten = cursor.execute(f"""
|
|
SELECT {values} FROM Netzpunkte;
|
|
""").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
|
|
# Nur ausgeben, wenn für einen Punkt X, Y und Z Koordinaten vorhanden sind
|
|
liste_koordinaten = [
|
|
koordinate for koordinate in liste_koordinaten
|
|
if koordinate[1] is not None and koordinate[2] is not None and koordinate[3] is not None
|
|
]
|
|
|
|
# Aktuell ist nur die Ausgabeart "Dict" implementiert. Weitere Ausgabearten sind im Zuge möglicher erweiterungen zu implementieren.
|
|
if ausgabeart == "Dict":
|
|
return {
|
|
koordinate[0]: sp.Matrix([
|
|
sp.Float(str(koordinate[1])),
|
|
sp.Float(str(koordinate[2])),
|
|
sp.Float(str(koordinate[3]))
|
|
])
|
|
for koordinate in liste_koordinaten
|
|
}
|
|
|
|
def get_normalhoehe_hfp(self) -> list[Any]:
|
|
"""Liest alle Normalhöhen von amtlichen Höhenfestpunkten (HFP) aus der Tabelle Netzpunkte.
|
|
|
|
:return: Liste mit Tupeln (punktnummer, normalhoehe_hfp) für alle Punkte mit gesetzter Normalhöhe.
|
|
:rtype: list
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_hfp = cursor.execute("SELECT punktnummer, normalhoehe_hfp FROM Netzpunkte WHERE normalhoehe_hfp IS NOT NULL").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_hfp
|
|
|
|
|
|
def get_instrument_liste(self, typ: str) -> list:
|
|
"""Liest Instrumente eines gegebenen Typs aus der Tabelle Instrumente.
|
|
|
|
Gibt eine Liste der gefundenen Instrumente zurück. Falls keine Instrumente vorhanden sind,
|
|
wird eine Textausgabe mit verfügbaren Typen zurückgegeben.
|
|
|
|
:param typ: Instrumenttyp.
|
|
:type typ: str
|
|
:return: Liste der Instrumente oder Hinweistext, falls keine Instrumente gefunden wurden.
|
|
:rtype: list | str
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_instrumente = cursor.execute("SELECT * FROM Instrumente WHERE typ = ?", (typ,)).fetchall()
|
|
liste_typen = cursor.execute("SELECT DISTINCT typ FROM Instrumente").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
if liste_instrumente == []:
|
|
liste_instrumente = f"Kein Instrument vom Typ {typ} gefunden. Folgende Typen stehen aktuell zur Auswahl: {liste_typen}"
|
|
return liste_instrumente
|
|
|
|
def get_alle_instrumente_liste(self: str) -> list:
|
|
"""Liest alle Instrumente aus der Tabelle Instrumente auf.
|
|
|
|
Gibt eine Liste der gefundenen Instrumente zurück. Falls keine Instrumente vorhanden sind,
|
|
wird eine Textausgabe mit verfügbaren Typen zurückgegeben.
|
|
|
|
:return: Liste der Instrumente oder Hinweistext, falls keine Instrumente gefunden wurden.
|
|
:rtype: list | str
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_instrumente = cursor.execute("SELECT * FROM Instrumente").fetchall()
|
|
liste_typen = cursor.execute("SELECT DISTINCT typ FROM Instrumente").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
if liste_instrumente == []:
|
|
liste_instrumente = f"Kein Instrumente gefunden. Bitte in der Folgenden Zelle anlegen."
|
|
return liste_instrumente
|
|
|
|
def get_genauigkeiten_dict(self) -> dict[Any, Any]:
|
|
"""Liest alle Genauigkeiten aus der Tabelle Genauigkeiten und gibt diese als Dictionary zurück.
|
|
|
|
:return: Dictionary {genauigkeitenID : restliche Tabellenwerte}.
|
|
:rtype: dict
|
|
"""
|
|
dict = {}
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_genauigkeiten = cursor.execute("SELECT * FROM Genauigkeiten").fetchall()
|
|
for genauigkeit in liste_genauigkeiten:
|
|
dict[genauigkeit[0]] = genauigkeit[1:]
|
|
cursor.close()
|
|
con.close()
|
|
return dict
|
|
|
|
def get_instrumenteID_beobachtungenID_dict(self) -> dict[Any, Any]:
|
|
"""Liest die Zuordnung BeobachtungenID → InstrumenteID aus der Tabelle Beobachtungen.
|
|
|
|
:return: Dictionary {beobachtungenID : instrumenteID}.
|
|
:rtype: dict
|
|
"""
|
|
dict = {}
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_beobachtungen_instrumente = cursor.execute("SELECT beobachtungenID, instrumenteID FROM Beobachtungen").fetchall()
|
|
for i in liste_beobachtungen_instrumente:
|
|
dict[i[0]] = i[1]
|
|
cursor.close()
|
|
con.close()
|
|
return dict
|
|
|
|
def get_puntknummern_beobachtungen_tachymeter(self, beobachtungsart: str) -> list[Any]:
|
|
"""Liest Beobachtungen (ID, Gruppe, Standpunkt, Zielpunkt) für Tachymeterbeobachtungen.
|
|
|
|
Es werden nur Beobachtungen berücksichtigt, bei denen die angegebene Beobachtungsart
|
|
nicht NULL ist. Zudem werden zusätzlich werden nur Beobachtungen übergeben, die nicht
|
|
ausgeschaltet werden.
|
|
|
|
:param beobachtungsart: Name der Beobachtungsspalte.
|
|
:type beobachtungsart: str
|
|
:return: Liste von Tupeln (beobachtungenID, beobachtungsgruppeID, punktnummer_sp, punktnummer_zp).
|
|
:rtype: list
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
sql_ausdruck = f"SELECT beobachtungenID, beobachtungsgruppeID, punktnummer_sp, punktnummer_zp FROM Beobachtungen WHERE {beobachtungsart} IS NOT NULL"
|
|
if beobachtungsart == "tachymeter_distanz":
|
|
sql_ausdruck += " AND tachymeter_distanz_auschalten = 0"
|
|
elif beobachtungsart == "tachymeter_richtung":
|
|
sql_ausdruck += " AND tachymeter_richtung_ausschalten = 0"
|
|
elif beobachtungsart == "tachymeter_zenitwinkel":
|
|
sql_ausdruck += " AND tachymeter_zenitwinkel_ausschalten = 0"
|
|
liste_beobachtungen = cursor.execute(sql_ausdruck).fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_beobachtungen
|
|
|
|
def get_beobachtungen_from_beobachtungenid(self) -> list[Any]:
|
|
"""Liest Tachymeterbeobachtungen aus der Tabelle ``Beobachtungen``.
|
|
|
|
Es werden nur Datensätze mit gesetzter Tachymeter-Richtung berücksichtigt.
|
|
|
|
:return: Liste von Tupeln (punktnummer_sp, punktnummer_zp, beobachtungenID, beobachtungsgruppeID, tachymeter_richtung, tachymeter_zenitwinkel, tachymeter_distanz).
|
|
:rtype: list
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_beobachtungen = cursor.execute(f"SELECT punktnummer_sp, punktnummer_zp, beobachtungenID, beobachtungsgruppeID, tachymeter_richtung, tachymeter_zenitwinkel, tachymeter_distanz FROM Beobachtungen WHERE tachymeter_richtung IS NOT NULL").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_beobachtungen
|
|
|
|
def get_beobachtungen_gnssbasislinien(self) -> list[Any]:
|
|
"""Liest GNSS-Basislinienbeobachtungen inklusive Kovarianzangaben.
|
|
|
|
Es werden nur Datensätze zurückgegeben, bei denen alle benötigten GNSS-Felder (bx, by, bz, s0
|
|
und Kovarianzelemente) nicht NULL sind.
|
|
|
|
:return: Liste von Tupeln mit GNSS-Basisliniendaten und Kovarianzelementen.
|
|
:rtype: list
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_beobachtungen = cursor.execute(f"SELECT beobachtungenID, punktnummer_sp, punktnummer_zp, gnss_bx, gnss_by, gnss_bz, gnss_s0, gnss_cxx, gnss_cxy, gnss_cxz, gnss_cyy, gnss_cyz, gnss_czz FROM Beobachtungen WHERE gnss_bx IS NOT NULL AND gnss_by IS NOT NULL AND gnss_bz IS NOT NULL AND gnss_s0 IS NOT NULL AND gnss_cxx IS NOT NULL AND gnss_cxy IS NOT NULL AND gnss_cxz IS NOT NULL AND gnss_cyy IS NOT NULL AND gnss_cyz IS NOT NULL AND gnss_czz IS NOT NULL").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_beobachtungen
|
|
|
|
def get_beobachtungen_nivellement(self) -> list[Any]:
|
|
"""Liest Nivellementbeobachtungen aus der Tabelle Beobachtungen.
|
|
|
|
Es werden nur Datensätze zurückgegeben, bei denen alle Nivellementfelder Daten enthalten
|
|
und niv_ausschalten = 0 ist, also diese Beobachtung in der Ausgleichung verwendet wird.
|
|
|
|
:return: Liste von Tupeln (beobachtungenID, punktnummer_sp, punktnummer_zp, niv_dh, niv_strecke, niv_anz_standpkte).
|
|
:rtype: list
|
|
"""
|
|
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_beobachtungen = cursor.execute(f"SELECT beobachtungenID, punktnummer_sp, punktnummer_zp, niv_dh, niv_strecke, niv_anz_standpkte FROM Beobachtungen WHERE niv_dh IS NOT NULL AND niv_strecke IS NOT NULL AND niv_anz_standpkte IS NOT NULL AND niv_ausschalten = 0").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_beobachtungen
|
|
|
|
def get_datumskoordinate(self) -> list[Any]:
|
|
"""Liest die aktuell gesetzten Datumskoordinaten aus der Tabelle Netzpunkte.
|
|
|
|
Die Rückgabe erfolgt als Liste von Symbolnamen der Form "X<punktnummer>", "Y<punktnummer>"
|
|
und "Z<punktnummer>".
|
|
|
|
:return: Liste der Datumskoordinatenbezeichner.
|
|
:rtype: list
|
|
"""
|
|
# Abragen der Koordinaten mit einer 1 im Attribut datumskoordinate_*, da diese für die Lagerung verwendet werden sollen.
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_datumskoordinate_x = cursor.execute(
|
|
f"SELECT punktnummer FROM Netzpunkte WHERE datumskoordinate_x = 1").fetchall()
|
|
liste_datumskoordinate_y = cursor.execute(
|
|
f"SELECT punktnummer FROM Netzpunkte WHERE datumskoordinate_y = 1").fetchall()
|
|
liste_datumskoordinate_z = cursor.execute(
|
|
f"SELECT punktnummer FROM Netzpunkte WHERE datumskoordinate_z = 1").fetchall()
|
|
|
|
cursor.close()
|
|
con.close()
|
|
|
|
# Hinzufügen der jeweiligen Punktnummer als Symbol mit X, Y oder Z-Präfix zur Rückgabeliste
|
|
liste_datumskoordinaten = []
|
|
if liste_datumskoordinate_x != []:
|
|
for datumskoordinate in liste_datumskoordinate_x:
|
|
datumskoordinate = str(datumskoordinate[0]).strip()
|
|
liste_datumskoordinaten.append(f"X{datumskoordinate}")
|
|
if liste_datumskoordinate_y != []:
|
|
for datumskoordinate in liste_datumskoordinate_y:
|
|
datumskoordinate = str(datumskoordinate[0]).strip()
|
|
liste_datumskoordinaten.append(f"Y{datumskoordinate}")
|
|
if liste_datumskoordinate_z != []:
|
|
for datumskoordinate in liste_datumskoordinate_z:
|
|
datumskoordinate = str(datumskoordinate[0]).strip()
|
|
liste_datumskoordinaten.append(f"Z{datumskoordinate}")
|
|
|
|
return liste_datumskoordinaten
|
|
|
|
def get_stabw_AA_Netzpunkte(self) -> dict[Any, Any]:
|
|
"""Liest Vorinformationen zur Standardabweichung der Netzpunkte aus der Tabelle Netzpunkte.
|
|
|
|
Die Rückgabe erfolgt als Dictionary mit Schlüsseln der Form "StabwAA_X<punktnummer>",
|
|
"StabwAA_Y<punktnummer>" und "StabwAA_Z<punktnummer>".
|
|
|
|
:return: Dictionary der Vorinformationen zur Standardabweichung je Koordinate.
|
|
:rtype: dict
|
|
"""
|
|
# Abfragen aller Punktnummern und s0 apriori Vorinformationen aus der Datenbank, wenn die Vorinformationen vorliegen.
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_stabwAA_x = cursor.execute(f"SELECT punktnummer, stabw_vorinfo_x FROM Netzpunkte WHERE stabw_vorinfo_x IS NOT NULL").fetchall()
|
|
liste_stabwAA_y = cursor.execute(
|
|
f"SELECT punktnummer, stabw_vorinfo_y FROM Netzpunkte WHERE stabw_vorinfo_y IS NOT NULL").fetchall()
|
|
liste_stabwAA_z = cursor.execute(
|
|
f"SELECT punktnummer, stabw_vorinfo_z FROM Netzpunkte WHERE stabw_vorinfo_z IS NOT NULL").fetchall()
|
|
|
|
cursor.close()
|
|
con.close()
|
|
|
|
# Erstellen des Rückgabedictionaries.
|
|
dict_stabwAA = {}
|
|
for stabwAA_x in liste_stabwAA_x:
|
|
punktnummer = str(stabwAA_x[0]).strip()
|
|
wert = stabwAA_x[1]
|
|
dict_stabwAA[f"StabwAA_X{punktnummer}"]= wert
|
|
|
|
for stabwAA_y in liste_stabwAA_y:
|
|
punktnummer = str(stabwAA_y[0]).strip()
|
|
wert = stabwAA_y[1]
|
|
dict_stabwAA[f"StabwAA_Y{punktnummer}"]= wert
|
|
|
|
for stabwAA_z in liste_stabwAA_z:
|
|
punktnummer = str(stabwAA_z[0]).strip()
|
|
wert = stabwAA_z[1]
|
|
dict_stabwAA[f"StabwAA_Z{punktnummer}"]= wert
|
|
|
|
return dict_stabwAA
|
|
|
|
def get_gnss_beobachtungen_punktnummern(self, gnss_komponente: str) -> list[Any]:
|
|
"""Liest GNSS-Beobachtungen (ID, Standpunkt, Zielpunkt) für eine GNSS-Komponente.
|
|
|
|
Es werden nur Datensätze berücksichtigt, bei denen die geforderte Komponente sowie alle
|
|
zugehörigen GNSS-Genauigkeitsangaben (s0 und Kovarianzelemente) vorhanden sind.
|
|
Zusätzlich wird das jeweilige Ausschalt-Attribut berücksichtigt.
|
|
|
|
:param gnss_komponente: Name der GNSS-Basislinienkomponente (z. B. "gnss_bx", "gnss_by", "gnss_bz").
|
|
:type gnss_komponente: str
|
|
:return: Liste von Tupeln (beobachtungenID, punktnummer_sp, punktnummer_zp).
|
|
:rtype: list
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
sql = f"""SELECT beobachtungenID, punktnummer_sp, punktnummer_zp
|
|
FROM Beobachtungen
|
|
WHERE {gnss_komponente} IS NOT NULL
|
|
AND gnss_s0 IS NOT NULL
|
|
AND gnss_cxx IS NOT NULL AND gnss_cxy IS NOT NULL AND gnss_cxz IS NOT NULL
|
|
AND gnss_cyy IS NOT NULL AND gnss_cyz IS NOT NULL AND gnss_czz IS NOT NULL"""
|
|
|
|
if gnss_komponente == "gnss_bx":
|
|
sql += " AND gnss_bx_ausschalten = 0"
|
|
elif gnss_komponente == "gnss_by":
|
|
sql += " AND gnss_by_ausschalten = 0"
|
|
elif gnss_komponente == "gnss_bz":
|
|
sql += " AND gnss_bz_ausschalten = 0"
|
|
|
|
liste_gnss_beobachtungen = cursor.execute(sql).fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_gnss_beobachtungen
|
|
|
|
def get_nivellement_beobachtungen_punktnummern(self) -> list[Any]:
|
|
"""Liest Beobachtungen vom geometrischen Nivellement (ID, Standpunkt, Zielpunkt) aus der Tabelle Beobachtungen.
|
|
|
|
Es werden nur Datensätze berücksichtigt, bei denen alle Attribute gesetzt sind
|
|
und niv_ausschalten = 0 ist.
|
|
|
|
:return: Liste von Tupeln (beobachtungenID, punktnummer_sp, punktnummer_zp).
|
|
:rtype: list
|
|
"""
|
|
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_nivellement_beobachtungen = cursor.execute(f"SELECT beobachtungenID, punktnummer_sp, punktnummer_zp FROM Beobachtungen WHERE niv_dh IS NOT NULL AND niv_strecke IS NOT NULL AND niv_anz_standpkte IS NOT NULL AND niv_ausschalten = 0").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_nivellement_beobachtungen
|
|
|
|
def get_varianzkomponentenschaetzung(self) -> list[Any]:
|
|
"""Liest alle Einträge der Varianzkomponentenschätzung aus der Datenbank.
|
|
|
|
:return: Liste von Tupeln (varianzkomponenteID, instrumenteID, beobachtungsgruppe, varianz_varianzkomponentenschaetzung).
|
|
:rtype: list
|
|
"""
|
|
con = sqlite3.connect(self.pfad_datenbank)
|
|
cursor = con.cursor()
|
|
liste_varianzkomponenten = cursor.execute(f"SELECT varianzkomponenteID, instrumenteID, beobachtungsgruppe, varianz_varianzkomponentenschaetzung FROM Varianzkomponentenschaetzung").fetchall()
|
|
cursor.close()
|
|
con.close()
|
|
return liste_varianzkomponenten
|
|
|
|
def tabelle_instrumente_aus_db(self) -> None:
|
|
"""Stellt die in der Datenbank gespeicherten Instrumente tabellarisch dar.
|
|
|
|
Die Methode liest alle Datensätze aus der Tabelle Instrumente über die
|
|
zugehörige Datenbankzugriffsmethode und erzeugt daraus einen pandas-DataFrame
|
|
zur Anzeige im Notebook. Sind keine Instrumente vorhanden, wird ein Hinweistext
|
|
ausgegeben, dass die Instrumente zuerst anzulegen sind.
|
|
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
liste_instrumente_in_db = self.get_alle_instrumente_liste()
|
|
|
|
# Prüfen, ob Datensätze in der Tabelle Instrumente enthalten sind
|
|
if isinstance(liste_instrumente_in_db, list) and len(liste_instrumente_in_db) > 0:
|
|
df_instrumente = pd.DataFrame(liste_instrumente_in_db, columns=['InstrumenteID', 'Typ', 'Bezeichnung'])
|
|
display(df_instrumente.style.hide(axis='index'))
|
|
|
|
else:
|
|
print(
|
|
"Es wurden noch keine Instrumente angelegt. Bitte in der folgenden Zelle nachholen und diese Zelle erneut ausführen!")
|
|
|
|
def tabelle_genauigkeiten_aus_db(self) -> None:
|
|
"""Stellt die a-priori Genauigkeiten der Beobachtungsgruppen tabellarisch dar.
|
|
|
|
Die Methode liest alle Einträge aus der Tabelle Genauigkeiten über die
|
|
zugehörige Datenbankzugriffsmethode und erstellt eine
|
|
übersichtliche Anzeige im Notebook. Liegen keine Genauigkeitsangaben vor,
|
|
wird ein Hinweistext ausgegeben, dass die a-priori Genauigkeiten zunächst zu
|
|
erfassen sind.
|
|
|
|
:return: None
|
|
:rtype: None
|
|
"""
|
|
genauigkeiten_dict = self.get_genauigkeiten_dict()
|
|
# Prüfen, ob Datensätze in der Tabelle Instrumente enthalten sind
|
|
if genauigkeiten_dict == {}:
|
|
print(
|
|
"Es wurden noch keine apriori Genauigkeiten zu den Beobachtungsgruppen erfasst. Bitte in der folgenden Zelle nachholen und diese Zelle erneut ausführen.")
|
|
else:
|
|
formatierte_daten = list(genauigkeiten_dict.values())
|
|
spalten = [
|
|
'instrumenteID',
|
|
'beobachtungsart',
|
|
'stabw_apriori_konstant',
|
|
'stabw_apriori_streckenprop'
|
|
]
|
|
df = pd.DataFrame(formatierte_daten, columns=spalten)
|
|
display(df.style.hide(axis='index'))
|