zusammenfügen 02.2.

This commit is contained in:
2026-02-02 20:01:37 +01:00
parent 774acc3854
commit 4e7c55500b
11 changed files with 62593 additions and 2121 deletions

465
Import.py
View File

@@ -1,37 +1,95 @@
import csv
import sqlite3
from decimal import Decimal
from typing import Any
import re
import xml.etree.ElementTree as ET
from decimal import Decimal, getcontext, ROUND_HALF_UP
import sqlite3
from typing import Any
import xml.etree.ElementTree as ET
from Berechnungen import Berechnungen
import Berechnungen
class Import:
def __init__(self, pfad_datenbank: str) -> None:
"""Importfunktionen für Messdaten und Näherungswerte in die SQLite-Datenbank.
Die Klasse stellt Methoden zur Verfügung für:
- Import von Näherungskoordinaten (LH-Tachymeter, GNSS/ECEF) in die Tabelle Netzpunkte,
- Import und Vorverarbeitung von Tachymeterbeobachtungen (CSV-Datei) inkl. optionaler Korrektur durch nicht gerundete Leica-JXL,
- Import von GNSS-Basislinien inkl. Kovarianzanteilen in die Tabelle Beobachtungen,
- Import von Nivellementdaten (Normalhöhen als Näherungen sowie RVVR-Züge als dh-Beobachtungen),
- einfache Plausibilitätsprüfungen (Duplikate, InstrumentenID, Dateiname bereits importiert).
"""
def __init__(self, pfad_datenbank: str, a : float, b : float) -> None:
"""Initialisiert die Importklasse.
Speichert den Pfad zur SQLite-Datenbank und initialisiert die Hilfsklasse Berechnungen.
:param a: Große Halbachse a des Referenzellipsoids in Meter.
:type a: float
:param b: Kleine Halbachse b des Referenzellipsoids in Meter.
:type b: float
:param pfad_datenbank: Pfad zur SQLite-Datenbank.
:type pfad_datenbank: str
:return: None
:rtype: None
"""
self.a = a
self.b = b
self.pfad_datenbank = pfad_datenbank
pass
self.berechnungen = Berechnungen.Berechnungen(self.a, self.b)
def string_to_float(self, zahl: str) -> float:
"""Konvertiert einen Zahlenstring in float.
Ersetzt das Dezimaltrennzeichen "," durch "." und führt anschließend float() aus.
:param zahl: Zahlenstring (z. B. "12,345" oder "12.345").
:type zahl: str
:return: Zahlenwert als float.
:rtype: float
"""
zahl = zahl.replace(',', '.')
return float(zahl)
def string_to_decimal(self, zahl: str) -> Decimal:
"""Konvertiert einen Zahlenstring in Decimal.
Ersetzt das Dezimaltrennzeichen "," durch "." und erzeugt anschließend ein Decimal.
:param zahl: Zahlenstring (z. B. "12,345" oder "12.345").
:type zahl: str
:return: Konvertierter Decimal-Wert.
:rtype: Decimal
"""
zahl = zahl.replace(',', '.')
return Decimal(zahl)
def import_koordinaten_lh_tachymeter(self, pfad_datei: str) -> None:
"""Importiert Näherungskoordinaten im lokalen Horizontsystem des Tachymeters in die Tabelle Netzpunkte.
Die Datei wird semikolon-separiert erwartet. Pro Zeile werden Punktnummer sowie X/Y/Z-Näherung
ausgelesen und in Netzpunkte (naeherungx_lh, naeherungy_lh, naeherungz_lh) geschrieben.
Vor dem Import werden zwei zentrale Prüfungen durchgeführt:
- Punktnummern dürfen in der Importdatei nicht doppelt vorkommen,
- Punktnummern aus der Importdatei dürfen noch nicht in der Tabelle Netzpunkte vorhanden sein.
:param pfad_datei: Pfad zur CSV-Datei mit Punktnummer und Koordinaten.
:type pfad_datei: str
:return: None
:rtype: None
"""
liste_punktnummern = []
liste_punktnummern_vorher = []
liste_punktnummern_vorher_db = []
# Import_abbrechen wird True, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_abbrechen = False
with open (pfad_datei, newline='', encoding='utf-8') as csvfile:
# Abfragen aller in der Tabelle Netzpunkte enthaltenen Punktnummern
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
liste_punktnummern_db = [r[0] for r in cursor.execute("SELECT DISTINCT punktnummer FROM Netzpunkte").fetchall()]
@@ -41,6 +99,7 @@ class Import:
r = csv.reader(csvfile, delimiter=';')
for row in r:
liste_punktnummern.append(row[0])
# 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.")
@@ -48,12 +107,14 @@ class Import:
liste_punktnummern_vorher.append(row[0])
# 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.")
break
liste_punktnummern_vorher_db.append(row[0])
# Import durchführen, wenn keine Fehler festgestellt wurden
if Import_abbrechen == False:
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
@@ -70,15 +131,30 @@ class Import:
con.close()
print("Der Import der Näherungskoordinaten wurde erfolgreich abgeschlossen")
def ist_rundung_von_jxl(self, wert_csv: str, wert_jxl_voll: str) -> bool:
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.
Es wird geprüft, ob:
- beide Werte echte Zahlen sind,
- der CSV-Wert weniger Nachkommastellen als der JXL-Wert besitzt,
- der JXL-Wert auf die Nachkommastellenanzahl des CSV-Wertes gerundet exakt dem CSV-Wert entspricht.
:param wert_csv: Wert aus der CSV-Datei.
:type wert_csv: str
:param wert_jxl: Wert aus der JXL-Datei.
:type wert_jxl: str
:return: True, wenn wert_csv eine Rundung von wert_jxl auf weniger Nachkommastellen darstellt, sonst False.
:rtype: bool
"""
wert_csv = str(wert_csv).strip()
wert_jxl_voll = str(wert_jxl_voll).strip()
wert_jxl = str(wert_jxl).strip()
if ":ZH:" in wert_csv:
wert_csv = wert_csv.split(":ZH:", 1)[0].strip()
if ":ZH:" in wert_jxl_voll:
wert_jxl_voll = wert_jxl_voll.split(":ZH:", 1)[0].strip()
if ":ZH:" in wert_jxl:
wert_jxl = wert_jxl.split(":ZH:", 1)[0].strip()
def ist_zahl(text: str) -> bool:
text = str(text).strip()
@@ -115,9 +191,10 @@ class Import:
if ist_zahl(wert_csv) == False:
return False
if ist_zahl(wert_jxl_voll) == False:
if ist_zahl(wert_jxl) == False:
return False
# Ermittlung der Anzahl Nachkommastellen in CSV-Datei und JXL-Datei
anzahl_nachkommastellen_csv = 0
if "," in wert_csv:
anzahl_nachkommastellen_csv = len(wert_csv.split(",", 1)[1])
@@ -125,16 +202,16 @@ class Import:
anzahl_nachkommastellen_csv = len(wert_csv.split(".", 1)[1])
anzahl_nachkommastellen_jxl = 0
if "," in wert_jxl_voll:
anzahl_nachkommastellen_jxl = len(wert_jxl_voll.split(",", 1)[1])
elif "." in wert_jxl_voll:
anzahl_nachkommastellen_jxl = len(wert_jxl_voll.split(".", 1)[1])
if "," in wert_jxl:
anzahl_nachkommastellen_jxl = len(wert_jxl.split(",", 1)[1])
elif "." in wert_jxl:
anzahl_nachkommastellen_jxl = len(wert_jxl.split(".", 1)[1])
if anzahl_nachkommastellen_csv >= anzahl_nachkommastellen_jxl:
return False
wert_csv_decimal = self.string_to_decimal(wert_csv.replace(".", ","))
wert_jxl_decimal = self.string_to_decimal(wert_jxl_voll.replace(".", ","))
wert_jxl_decimal = self.string_to_decimal(wert_jxl.replace(".", ","))
q = Decimal("1") if anzahl_nachkommastellen_csv == 0 else Decimal("1." + ("0" * anzahl_nachkommastellen_csv))
wert_jxl_gerundet = wert_jxl_decimal.quantize(q, rounding=ROUND_HALF_UP)
@@ -143,6 +220,13 @@ class Import:
return wert_jxl_gerundet == wert_csv_gerundet
def ist_zahl_csv(self, text: str) -> bool:
"""Prüft, ob ein String in der CSV als Zahl interpretiert werden kann.
:param text: Zu prüfender Text.
:type text: str
:return: True, wenn der Text eine Zahl ist, sonst False.
:rtype: bool
"""
text = str(text).strip()
if text == "":
return False
@@ -172,58 +256,92 @@ class Import:
pfad_datei_csv: str,
pfad_datei_jxl: str,
pfad_datei_csv_out: str) -> dict:
Import_fortsetzen = True
getcontext().prec = 70
"""Korrigiert Tachymeterbeobachtungen in einer CSV-Datei über eine JXL-Datei (Leica XML).
Die JXL-Datei wird eingelesen und je StationID eine Sequenz an Beobachtungen (Zielpunktname,
Horizontal-/Vertikalkreisablesung, Schrägdistanz sowie Prismenhöhe) aufgebaut. Die Winkel werden
von Grad nach gon umgerechnet und in der Nachkommastellenauflösung der JXL gerundet.
Anschließend wird die CSV zeilenweise verarbeitet:
- Standpunktzeilen werden der zugehörigen StationID/IH aus der JXL zugeordnet,
- Beobachtungszeilen werden falls der CSV-Wert eine Rundung des JXL-Werts ist durch den JXL-Wert mit voller Nachkommastellenzahl ersetzt,
- Prismenhöhen (ZH) werden aus der JXL übernommen und in der letzten Spalte als ":ZH:" angehängt.
Zusätzlich werden Fehler-Listen erstellt (fehlende IH, fehlende ZH, Standpunkte in CSV aber nicht in JXL). Diese werden dem Benutzer übergeben.
:param pfad_datei_csv: Pfad zur Eingabe-CSV (Tachymeterbeobachtungen).
:type pfad_datei_csv: str
:param pfad_datei_jxl: Pfad zur JXL-Datei.
:type pfad_datei_jxl: str
:param pfad_datei_csv_out: Pfad zur Ausgabe-CSV (korrigierte Datei).
:type pfad_datei_csv_out: str
:return: Ergebnisdictionary mit Status und Diagnosen, u. a.:
- "Import_fortsetzen" (bool),
- "dict_ersetzungen" (dict mit Zählungen für "Hz", "Z", "SD"),
- "liste_zeilen_ohne_IH" (list),
- "liste_zeilen_ohne_ZH" (list),
- "liste_zeilen_standpunkt_nicht_in_jxl" (list),
- "pfad_datei_csv_out" (str).
:rtype: dict
"""
# Import_fortsetzen wird False, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_fortsetzen = True
getcontext().prec = 70
dict_ersetzungen = {"Hz": 0, "Z": 0, "SD": 0}
# IH = Instrumentenhöhe | ZH = Zielhöhe, bzw. Prismenhöhe
liste_zeilen_ohne_IH = []
liste_zeilen_ohne_ZH = []
liste_zeilen_standpunkt_nicht_in_jxl = []
liste_stationrecords = []
liste_tachymeterstandpunkte = []
dict_stationname_stationrecords = {}
dict_stationname_zaehler = {}
dict_stationname_tachymeterstandpunkte = {}
dict_standpunkte_anzahl = {}
dict_targetID_zu_ZH = {}
dict_stationID_zu_seq = {}
dict_stationnamen = {}
# Vorbereitung jxl-Datei lesen
tree = ET.parse(pfad_datei_jxl)
root = tree.getroot()
# JXL-Datei auslesen
if Import_fortsetzen:
# StationRecords einlesen (Standpunkt, StationID, Instrumentenhöhe)
# Standpunkt, StationID, Instrumentenhöhe aus der JXL-Datei auslesen
for sr in root.iter("StationRecord"):
stationname = (sr.findtext("StationName") or "").strip()
station_id = (sr.attrib.get("ID") or "").strip()
ih = (sr.findtext("TheodoliteHeight") or "").strip()
if stationname != "" and station_id != "":
liste_stationrecords.append((stationname, station_id, ih))
liste_tachymeterstandpunkte.append((stationname, station_id, ih))
dict_stationnamen[stationname] = 1
if stationname not in dict_stationname_stationrecords:
dict_stationname_stationrecords[stationname] = []
dict_stationname_stationrecords[stationname].append((station_id, ih))
if stationname not in dict_stationname_tachymeterstandpunkte:
dict_stationname_tachymeterstandpunkte[stationname] = []
dict_stationname_tachymeterstandpunkte[stationname].append((station_id, ih))
for stationname in dict_stationname_stationrecords.keys():
dict_stationname_zaehler[stationname] = 0
for stationname in dict_stationname_tachymeterstandpunkte.keys():
dict_standpunkte_anzahl[stationname] = 0
# Prismenhöhe auslesen und in Dict speichern
for tr in root.iter("TargetRecord"):
target_id = (tr.attrib.get("ID") or "").strip()
zh = (tr.findtext("TargetHeight") or "").strip()
if target_id != "":
dict_targetID_zu_ZH[target_id] = zh
for tupel in liste_stationrecords:
for tupel in liste_tachymeterstandpunkte:
station_id = tupel[1]
if station_id not in dict_stationID_zu_seq:
dict_stationID_zu_seq[station_id] = []
# Horizontal- und Vertikalkreisablesungen, sowie Schrägdistanzablesungen aus JXL-Datei auslesen
for pr in root.iter("PointRecord"):
station_id = (pr.findtext("StationID") or "").strip()
if station_id == "" or station_id not in dict_stationID_zu_seq:
@@ -267,13 +385,14 @@ class Import:
z_gon_decimal = z_gon_decimal.quantize(q_z, rounding=ROUND_HALF_UP)
sd_decimal = Decimal(sd_m).quantize(q_sd, rounding=ROUND_HALF_UP)
# Ausgabe mit Komma
# Ausgabe mit Kommatrennung
hz_gon_text = format(hz_gon_decimal, "f").replace(".", ",")
z_gon_text = format(z_gon_decimal, "f").replace(".", ",")
sd_text = format(sd_decimal, "f").replace(".", ",")
zh = dict_targetID_zu_ZH.get(target_id, "")
# Dictionary mit den Abfragen für die Weiterverarbeitung füllen.
dict_stationID_zu_seq[station_id].append({
"target": zielpunkt_name,
"hz_gon": hz_gon_text,
@@ -283,7 +402,7 @@ class Import:
})
station_id_aktuell = None
index_seq_aktuell = 0
index_csv_jxl_aktuell = 0
standpunkt_aktuell = None
# CSV-Datei zeilenweise durchgehen und ggf. Werte ersetzen
@@ -304,9 +423,10 @@ class Import:
standpunkt = row[0].strip()
if standpunkt in dict_stationnamen:
zaehler = dict_stationname_zaehler.get(standpunkt, 0)
liste_records = dict_stationname_stationrecords[standpunkt]
zaehler = dict_standpunkte_anzahl.get(standpunkt, 0)
liste_records = dict_stationname_tachymeterstandpunkte[standpunkt]
# Überprüfung, ob in beiden Dateien die selben Tachymeterstandpunkte vorhanden sind
if zaehler >= len(liste_records):
Import_fortsetzen = False
print(
@@ -314,18 +434,20 @@ class Import:
break
station_id, ih = liste_records[zaehler]
dict_stationname_zaehler[standpunkt] = zaehler + 1
dict_standpunkte_anzahl[standpunkt] = zaehler + 1
station_id_aktuell = station_id
index_seq_aktuell = 0
index_csv_jxl_aktuell = 0
standpunkt_aktuell = standpunkt
# Erstellen einer Liste mit allen Zeilennummern aus der JXL, für die keine Instrumentenhöhe vorliegt, damit dies als Fehlermeldung mit Bearbeitungshinweisen ausgegeben werden kann.
if ih is None or str(ih).strip() == "":
liste_zeilen_ohne_IH.append((nummer_zeile, standpunkt))
writer.writerow([standpunkt, f"IH:{ih}", "", "", ""])
continue
# Erstellen einer Liste mit allen Zeilennummern aus der JXL, für die keine Prismenhöhe vorliegt, damit dies als Fehlermeldung mit Bearbeitungshinweisen ausgegeben werden kann.
if standpunkt.isdigit():
liste_zeilen_standpunkt_nicht_in_jxl.append((nummer_zeile, standpunkt))
@@ -338,8 +460,6 @@ class Import:
wert_z = row[2].split(":ZH:", 1)[0].strip()
wert_sd = row[3].split(":ZH:", 1)[0].strip()
if self.ist_zahl_csv(wert_hz) and self.ist_zahl_csv(wert_z) and self.ist_zahl_csv(wert_sd):
ist_beobachtung = True
@@ -355,21 +475,23 @@ class Import:
writer.writerow(row)
continue
if index_seq_aktuell >= len(liste_seq):
if index_csv_jxl_aktuell >= len(liste_seq):
writer.writerow(row)
continue
jxl_eintrag = liste_seq[index_seq_aktuell]
index_neu = index_seq_aktuell + 1
# Abfragen der selben Daten aus der JXL-Datei über den index
jxl_eintrag = liste_seq[index_csv_jxl_aktuell]
index_neu = index_csv_jxl_aktuell + 1
if jxl_eintrag["target"] != zielpunkt:
index_ende = min(len(liste_seq), index_seq_aktuell + 200)
index_ende = min(len(liste_seq), index_csv_jxl_aktuell + 200)
liste_kandidaten = []
for index_kandidat in range(index_seq_aktuell, index_ende):
for index_kandidat in range(index_csv_jxl_aktuell, index_ende):
if liste_seq[index_kandidat]["target"] == zielpunkt:
liste_kandidaten.append((index_kandidat, liste_seq[index_kandidat]))
# Überprüfung, ob die Ablesungen in der CSV-Datei wirklich Rundungen der selben Daten mit mehr Nachkommastellen aus der JXL-Datei sind und abspeichern der Prüfergebnisse.
if liste_kandidaten != []:
if len(liste_kandidaten) == 1:
index_kandidat, kandidat = liste_kandidaten[0]
@@ -392,9 +514,9 @@ class Import:
jxl_eintrag = kandidat_best
index_neu = index_best + 1
index_seq_aktuell = index_neu
index_csv_jxl_aktuell = index_neu
# Nur ersetzen, wenn die CSV-Werte tatsächlich eine Rundung der JXL-Werte sind
# Nur in der CSV-Datei ersetzen, wenn die CSV-Werte tatsächlich eine Rundung der JXL-Werte sind
hz_out = hz_csv
z_out = z_csv
sd_out = sd_csv
@@ -423,24 +545,27 @@ class Import:
if Import_fortsetzen:
print(f"Korrektur erfolgreich abgeschlossen. Ausgabe: {pfad_datei_csv_out}")
print(f"Ersetzungen (Rundung -> JXL volle Nachkommastellen): {dict_ersetzungen}")
print(f"Ersetzungen in der CSV-Datei (Rundung -> JXL volle Nachkommastellen): {dict_ersetzungen}")
print("\n--- Fehlende IH ---")
print(f"Anzahl: {len(liste_zeilen_ohne_IH)}")
# Ausgabe der Zeilennummern in der JXL-Datei ohne Instrumentenhöhe
if len(liste_zeilen_ohne_IH) > 0:
print("\n--- Fehlende IH in JXL-Datei ---")
print(f"Anzahl: {len(liste_zeilen_ohne_IH)}")
print(liste_zeilen_ohne_IH)
print("\n--- Fehlende ZH ---")
print(f"Anzahl: {len(liste_zeilen_ohne_ZH)}")
# Ausgabe der Zeilennummern in der JXL-Datei ohne Prismenhöhe
if len(liste_zeilen_ohne_ZH) > 0:
print("\n--- Fehlende ZH ---")
print(f"Anzahl: {len(liste_zeilen_ohne_ZH)}")
print(liste_zeilen_ohne_ZH)
print("\n--- Standpunkt in CSV, aber kein StationRecord in JXL ---")
print(f"Anzahl: {len(liste_zeilen_standpunkt_nicht_in_jxl)}")
# Ausgabe der Zeilennummern in der JXL-Datei mit unterschiedlichen Tachymeterstandpunkten im Vergleich zur CSV-Datei
if len(liste_zeilen_standpunkt_nicht_in_jxl) > 0:
print("\n--- Standpunkt in CSV-Datei, aber nicht in JXL-Datei---")
print(f"Anzahl: {len(liste_zeilen_standpunkt_nicht_in_jxl)}")
print(liste_zeilen_standpunkt_nicht_in_jxl)
else:
print("Die Korrektur wurde abgebrochen.")
print("Die Korrektur der CSV-Datei wurde abgebrochen.")
return {
"Import_fortsetzen": Import_fortsetzen,
@@ -451,8 +576,32 @@ class Import:
"pfad_datei_csv_out": pfad_datei_csv_out
}
def import_beobachtungen_tachymeter(self, pfad_datei: str, instrumentenID: int, a: float, b: float) -> None:
berechnungen = Berechnungen.Berechnungen(a, b)
def import_beobachtungen_tachymeter(self, pfad_datei: str, instrumentenID: int) -> None:
"""Importiert Tachymeterbeobachtungen aus einer CSV-Datei in die Tabelle Beobachtungen.
Die Datei wird blockweise verarbeitet (Standpunktzeile + Beobachtungszeilen). Aus je zwei Halbsätzen
wird ein Vollsatz abgeleitet:
- Richtung: Mittel aus Hz(HS1) und Hz(HS2-200 gon), normiert in [0, 400),
- Zenitwinkel: (ZW1 - ZW2 + 400) / 2,
- Schrägdistanz: Mittel der beiden SD.
Zusätzlich werden aus Instrumenten- und Prismenhöhe bodenbezogene Werte berechnet
(schraegdistanz_bodenbezogen, zenitwinkel_bodenbezogen) über berechne_zenitwinkel_distanz_bodenbezogen().
Vorabprüfungen:
- Abbruch, wenn der Dateiname bereits in Beobachtungen vorkommt,
- Abbruch, wenn instrumentenID nicht in Tabelle Instrumente existiert,
- Plausibilitätsprüfung auf Vollsatz-Struktur (6 Zeilen pro Zielpunkt: 3 Vollsätze * 2 Halbsätze).
:param pfad_datei: Pfad zur CSV-Datei.
:type pfad_datei: str
:param instrumentenID: ID des verwendeten Instruments aus Tabelle Instrumente.
:type instrumentenID: int
:return: None
:rtype: None
"""
# Prüfen, ob Bereits Daten aus der Datei in der Datenbank vorhanden sind
con = sqlite3.connect(self.pfad_datenbank)
@@ -464,16 +613,19 @@ class Import:
FROM Beobachtungen""").fetchall()]
liste_instrumentenid = [r[0] for r in cursor.execute("SELECT instrumenteID FROM Instrumente").fetchall()]
cursor.close()
con.close()
cursor.close
# Import_fortsetzen wird False, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_fortsetzen = True
# Abbrechen des Imports, wenn bereits Daten aus der selben Datei importiert wurden.
if pfad_datei in liste_dateinamen_in_db:
Import_fortsetzen = False
if Import_fortsetzen:
nummer_zielpunkt = 0
# Abfragen der aktuell höschten Nummer im Attribut beobachtungsgruppeID der Tabelle Beobachtungen
try:
nummer_beobachtungsgruppeID = max(liste_beobachtungsgruppeID)
except:
@@ -487,20 +639,22 @@ class Import:
liste_beobachtungen_vorbereitung = []
for i, zeile in enumerate(f):
# Die ersten drei Zeilen der Importdatei müssen überprungen werden
if i < 3:
continue
zeile = zeile.strip().split(";")
if len(zeile) < 5:
zeile = zeile + [""] * (5 - len(zeile))
# Tachymeterstandpunkt speichern und beobachtungsgruppeID als ID für das einmalige Aufbauen eines Tachymeters auf einem Punkt festlegen
if zeile[2] == "" and zeile[3] == "" and zeile[4] == "":
nummer_beobachtungsgruppeID += 1
# print("Standpunkt: ",nummer_beobachtungsgruppeID ,zeile[0])
standpunkt = zeile[0]
instrumentenhoehe = zeile[1]
if instrumentenhoehe.startswith("IH:"):
instrumentenhoehe = instrumentenhoehe.split("IH:", 1)[1].strip()
# Überprüfung, ob für jeden Beobachteten Zielpunkt 6 Zeilen vorhanden sind (3 Vollszätze mit je 2 Halbsätzen)
if nummer_zielpunkt % 6 != 0:
liste_fehlerhafte_zeile.append(i)
@@ -509,6 +663,8 @@ class Import:
liste_zielpunkte_vs2 = []
liste_zielpunkte_vs3 = []
else:
# ZH = Prismenhöhe | VS = Vollsatz | HS = Halbsatz
# Erstellen einer Liste mit Standpunkt, Vollsatz und Halbsatzzuordnung für die Beobachtungen für die Weiterverarbeitung
nummer_zielpunkt += 1
if ":ZH:" in zeile[3]:
@@ -519,17 +675,14 @@ class Import:
if zeile[0] not in liste_zielpunkte_hs:
liste_zielpunkte_hs.append(zeile[0])
if zeile[0] in liste_zielpunkte_vs3:
# print(f"{nummer_zielpunkt} VS3 HS1 {zeile}")
liste_beobachtungen_vorbereitung.append(
[nummer_beobachtungsgruppeID, "VS3", "HS1", standpunkt, zeile[0], zeile[1],
zeile[2], zeile[3], zeile[4], instrumentenhoehe])
elif zeile[0] in liste_zielpunkte_vs2:
# print(f"{nummer_zielpunkt} VS2 HS1 {zeile}")
liste_beobachtungen_vorbereitung.append(
[nummer_beobachtungsgruppeID, "VS2", "HS1", standpunkt, zeile[0], zeile[1],
zeile[2], zeile[3], zeile[4], instrumentenhoehe])
else:
# print(f"{nummer_zielpunkt} VS1 HS1 {zeile}")
liste_beobachtungen_vorbereitung.append(
[nummer_beobachtungsgruppeID, "VS1", "HS1", standpunkt, zeile[0], zeile[1],
zeile[2],
@@ -538,7 +691,6 @@ class Import:
else:
liste_zielpunkte_hs.remove(zeile[0])
if zeile[0] in liste_zielpunkte_vs3:
# print(f"{nummer_zielpunkt} VS3 HS2 {zeile}")
liste_beobachtungen_vorbereitung.append(
[nummer_beobachtungsgruppeID, "VS3", "HS2", standpunkt, zeile[0], zeile[1],
zeile[2],
@@ -547,7 +699,6 @@ class Import:
elif zeile[0] in liste_zielpunkte_vs2:
if zeile[0] not in liste_zielpunkte_vs3:
liste_zielpunkte_vs3.append(zeile[0])
# print(f"{nummer_zielpunkt} VS2 HS2 {zeile}")
liste_beobachtungen_vorbereitung.append(
[nummer_beobachtungsgruppeID, "VS2", "HS2", standpunkt, zeile[0], zeile[1],
zeile[2],
@@ -555,18 +706,19 @@ class Import:
else:
if zeile[0] not in liste_zielpunkte_vs2:
liste_zielpunkte_vs2.append(zeile[0])
# print(f"{nummer_zielpunkt} VS1 HS2 {zeile}")
liste_beobachtungen_vorbereitung.append(
[nummer_beobachtungsgruppeID, "VS1", "HS2", standpunkt, zeile[0], zeile[1],
zeile[2],
zeile[3], zeile[4], instrumentenhoehe])
if liste_fehlerhafte_zeile == []:
# print(f"Einlesen der Datei {pfad_datei} erfolgreich beendet.")
pass
else:
# Ausgabe, welche Zeilen in der Importdatei bearbeitet werden müssen.
if liste_fehlerhafte_zeile != []:
fehler_zeilen = ", ".join(map(str, liste_fehlerhafte_zeile))
print(
f"Das Einlesen der Datei {pfad_datei} wurde abgebrochen.\nBitte bearbeiten Sie die Zeilen rund um: {", ".join(map(str, liste_fehlerhafte_zeile))} in der csv-Datei und wiederholen Sie den Import.")
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."
)
Import_fortsetzen = False
else:
@@ -579,13 +731,12 @@ class Import:
while len(liste_beobachtungen_vorbereitung) > 0:
liste_aktueller_zielpunkt = liste_beobachtungen_vorbereitung[0]
aktueller_zielpunkt = liste_aktueller_zielpunkt[4]
# print(liste_beobachtungen_vorbereitung[0])
for index in range(1, len(liste_beobachtungen_vorbereitung)):
liste = liste_beobachtungen_vorbereitung[index]
# Berechnen der zu importierenden Beobachtungen. (Jeweils reduziert auf den Vollsatz)
if liste[4] == aktueller_zielpunkt:
# print(liste)
richtung1 = self.string_to_decimal(liste_aktueller_zielpunkt[5])
richtung2 = self.string_to_decimal(liste[5]) - Decimal(200)
zenitwinkel_vollsatz_gon = (self.string_to_decimal(liste_aktueller_zielpunkt[6]) - self.string_to_decimal(
@@ -612,12 +763,8 @@ class Import:
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(richtung_vollsatz)
# print(zenitwinkel_vollsatz)
# print(distanz_vollsatz)
schraegdistanz_bodenbezogen, zenitwinkel_bodenbezogen = berechnungen.berechne_zenitwinkel_distanz_bodenbezogen(
# 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(
float(zenitwinkel_vollsatz_rad), float(distanz_vollsatz), float(instrumentenhoehe_import), float(prismenhoehe))
liste_beobachtungen_import.append(
@@ -627,12 +774,13 @@ class Import:
del liste_beobachtungen_vorbereitung[0]
break
# Überprüfung, ob das Instrument bereits 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.")
# Berechnete bodenbezogene Beobachtungen, welche jeweils auf den Vollsatz reduziert sind, in die Tabelle Beobachtungen importieren.
if Import_fortsetzen:
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
@@ -649,28 +797,47 @@ class Import:
def vorbereitung_import_beobachtungen_nivellement_naeherung_punkthoehen(self, pfad_datei: str,
instrumentenID: int) -> None | tuple[None, None] | tuple[dict[Any, Any], list[Any]]:
# Prüfen, ob Bereits Daten aus der Datei in der Datenbank vorhanden sind
"""Bereitet den Import von Nivellementdaten zur Ableitung von Näherungs-Normalhöhen vor.
Aus einer semikolon-separierten Datei werden Zeilen erkannt, die berechnete Zielweiten/Punkthöhen enthalten,
und daraus pro Punktnummer alle gefundenen Z-Werte gesammelt. Anschließend wird je Punktnummer
der Mittelwert berechnet (Rundung auf 6 Nachkommastellen).
Danach wird geprüft, welche dieser Punktnummern bereits in der Tabelle Netzpunkte existieren.
Abbruchbedingungen:
- Dateiname bereits in Beobachtungen vorhanden,
- instrumentenID nicht in Instrumente vorhanden.
:param pfad_datei: Pfad zur Importdatei.
:type pfad_datei: str
:param instrumentenID: ID des verwendeten Niv-Instruments aus der Tabelle Instrumente.
:type instrumentenID: int
:return: (dict_punkt_mittelwert_punkthoehen, liste_punktnummern_in_db) oder (None, None) bei Abbruch.
:rtype: None | tuple[None, None] | tuple[dict[Any, Any], list[Any]]
"""
# Prüfen, ob bereits Daten aus der Datei in der Datenbank vorhanden sind
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
liste_dateinamen_in_db = [r[0] for r in cursor.execute(
"SELECT DISTINCT dateiname FROM Beobachtungen"
).fetchall()]
liste_beobachtungsgruppeID = [r[0] for r in cursor.execute("""SELECT DISTINCT beobachtungsgruppeID
FROM Beobachtungen""").fetchall()]
liste_instrumentenid = [r[0] for r in cursor.execute("SELECT instrumenteID FROM Instrumente").fetchall()]
liste_netzpunkte = [r[0] for r in cursor.execute("SELECT punktnummer FROM Netzpunkte").fetchall()]
cursor.close()
con.close()
# Import_fortsetzen wird False, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_fortsetzen = True
# 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.")
return None, None
# Abbruch, wenn das Instrument noch nicht vom Benutzer angelegt wurde.
if instrumentenID not in liste_instrumentenid:
Import_fortsetzen = False
print(
@@ -678,7 +845,7 @@ class Import:
return None, None
if Import_fortsetzen:
# Berechnete Punkthöhe Importieren
# Messwerte aus der Importdatei abfragen
muster_berechnete_zielweiten = "| | |Z "
dict_punkt_alle_punkthoehen = {}
dict_punkt_mittelwert_punkthoehen = {}
@@ -702,7 +869,6 @@ class Import:
wert_z = self.string_to_float(teil.split()[0])
if punktnummer is not None and wert_z is not None:
#print(f"{punktnummer}, {float(wert_z)}")
if punktnummer not in dict_punkt_alle_punkthoehen:
dict_punkt_alle_punkthoehen[punktnummer] = []
@@ -711,6 +877,7 @@ class Import:
# Hier wird auf 6 Nachkommastellen gerundet!
dict_punkt_mittelwert_punkthoehen[punktnummer] = round(sum(liste_z) / len(liste_z),6)
# Erstellen einer Liste mit allen Punktnummern, die in der Datenbank vorliegen und für die Nivellementbeobachtungen vorliegen.
if Import_fortsetzen:
# Ausgabe, welche Niv-Punkte bereits in der Tabelle Netzpunkte enthalten sind
liste_punktnummern_nivellement = dict_punkt_mittelwert_punkthoehen.keys()
@@ -722,6 +889,7 @@ class Import:
else:
liste_punktnummern_nicht_in_db.append(punktnummer)
# Es werden nur Höhendifferenzen für Punkte berechnet, für die Näherungskoordinaten in der Datenbank vorliegen.
if Import_fortsetzen:
print(f"Für folgende Nivellementpunkte werden die Höhen in der Ausgleichung berechnet: {liste_punktnummern_in_db}\nFür folgende Punkte wird aktuell keine Höhe in der Ausgleichung berechnet: {liste_punktnummern_nicht_in_db}. Bei Bedarf im folgenden Schritt ändern!")
return dict_punkt_mittelwert_punkthoehen, liste_punktnummern_in_db
@@ -729,6 +897,21 @@ class Import:
def import_beobachtungen_nivellement_naeherung_punkthoehen(self, dict_punkt_mittelwert_punkthoehen: dict,
liste_punktnummern_in_db: list,
liste_punktnummern_hinzufuegen: list) -> str | None:
"""Importiert Näherungsnormalhöhen in die Tabelle Netzpunkte.
Es werden Listen geführt für neu hinzugefügte, bereits vorhandene und geänderte Punkte und
abschließend als Konsolen-Ausgabe ausgegeben.
:param dict_punkt_mittelwert_punkthoehen: Dictionary {punktnummer: normalhoehe} als Mittelwerte.
:type dict_punkt_mittelwert_punkthoehen: dict
:param liste_punktnummern_in_db: Punktnummern, die bereits in Netzpunkte existieren.
:type liste_punktnummern_in_db: list
:param liste_punktnummern_hinzufuegen: Zusätzliche Punktnummern, die ebenfalls übernommen werden sollen.
:type liste_punktnummern_hinzufuegen: list
:return: Status-String mit der Liste der Punkte, für die Normalhöhen in der Ausgleichung verfügbar sind, oder None bei Abbruch.
:rtype: str | None
"""
# Import_fortsetzen wird False, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_fortsetzen = True
if dict_punkt_mittelwert_punkthoehen == None or liste_punktnummern_in_db == None or liste_punktnummern_hinzufuegen == None:
@@ -744,6 +927,7 @@ class Import:
liste_punkte_geaendert = []
for punktnummer in liste_punktnummern_hinzufuegen:
# Neu anlegen oder aktualisieren der Normalhöhen in der Tabelle Netzpunkte
try:
cursor.execute(f"INSERT INTO Netzpunkte (punktnummer, normalhoehe_hfp) VALUES (?, ?)", (punktnummer, dict_punkt_mittelwert_punkthoehen[punktnummer]))
liste_punkte_neu_hinzugefuegt.append(punktnummer)
@@ -765,10 +949,31 @@ class Import:
print(f"Bereits vorhanden ({len(liste_punkte_bereits_vorhanden)}): {liste_punkte_bereits_vorhanden}")
print(f"Geändert ({len(liste_punkte_geaendert)}): {liste_punkte_geaendert}\n")
return f"Für folgende Punkte werden die Höhen Ausgeglichen: {liste_punktnummern_hinzufuegen + liste_punktnummern_in_db}"
return f"Für folgende Punkte werden die Höhen Ausgeglichen: {liste_punktnummern_in_db}"
def import_beobachtungen_nivellement_RVVR(self, pfad_datei: str, instrumentenID: int) -> str | None:
"""Importiert geometrische Nivellementbeobachtungen nach dem RVVR Prinzip die Tabelle Beobachtungen.
Es werden Zeilen mit Rück-/Vormessungen erkannt (rvvr: Rück, Vor, Vor, Rück). Pro Block werden
dh und Entfernung berechnet (Rundung jeweils auf 8 Nachkommastellen). Anschließend werden Züge reduziert, indem
Wechselpunkte, die nicht in Netzpunkte vorhanden sind, durch Summation herausgekürzt werden.
Damit werden nur Beobachtungen zwischen Punkten in Netzpunkte (bzw. reduzierten Start-/Zielpunkten)
in Beobachtungen gespeichert.
Abbruchbedingungen:
- Dateiname bereits in Beobachtungen vorhanden,
- instrumentenID nicht in Instrumente vorhanden,
- Anzahl RVVR-Zeilen nicht durch 4 teilbar.
:param pfad_datei: Pfad zur Textdatei.
:type pfad_datei: str
:param instrumentenID: ID des verwendeten Niv-Instruments aus der Tabelle Instrumente.
:type instrumentenID: int
:return: Status-String bei Erfolg oder None bei Abbruch.
:rtype: str | None
"""
# Prüfen, ob Bereits Daten aus der Datei in der Datenbank vorhanden sind
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
@@ -781,36 +986,36 @@ class Import:
cursor.close()
con.close()
# Import_fortsetzen wird False, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_fortsetzen = True
# 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.")
# 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.")
if Import_fortsetzen:
# rvvr = Rück, Vor, Vor, Rück
# Berechnen der Höhenunterschiede delta H und Schrägstrecken zwischen Zwei Punkten gemäß der Importdatei aus rvvr.
anzahl_zeilen_rvvr = 0
liste_zeilen_rvvr = []
liste_punktpaare = []
with open(pfad_datei, "r", encoding="utf-8") as f:
for i, zeile in enumerate(f):
if ("Lr" in zeile) or ("Lv" in zeile):
#print(zeile.rstrip())
liste_zeilen_rvvr.append(zeile)
anzahl_zeilen_rvvr += 1
if anzahl_zeilen_rvvr % 4 == 0:
index = 0
while index < len(liste_zeilen_rvvr):
block_4 = liste_zeilen_rvvr[index:index + 4]
liste_punktnummern_block = []
for zeile_block in block_4:
@@ -885,7 +1090,9 @@ class Import:
index += 4
# Berechnen der Höhendifferenzen und schrägstrecken zwischen Punkten in der Tabelle Netzpunkte.
# Somit werden alle Wechselpunkte nicht in der Ausgleichung berücksichtigt.
# Die Berechnung erfolgt durch addition.
liste_beobachtungen_reduziert = []
liste_beobachtungen_bearbeitung = []
zugnummer_vorher = liste_punktpaare[0][0]
@@ -893,15 +1100,12 @@ class Import:
zugnummer = einzelbeobachtung[0]
if zugnummer == zugnummer_vorher:
if einzelbeobachtung[1] in liste_netzpunkte and einzelbeobachtung[2] in liste_netzpunkte:
#print(einzelbeobachtung)
liste_beobachtungen_reduziert.append(einzelbeobachtung + (1,))
elif einzelbeobachtung[1] in liste_netzpunkte and einzelbeobachtung[2] not in liste_netzpunkte:
#print(f"Zielpunkt nicht enthalten {einzelbeobachtung}")
liste_beobachtungen_bearbeitung.append(einzelbeobachtung)
elif einzelbeobachtung[1] not in liste_netzpunkte and einzelbeobachtung[2] in liste_netzpunkte:
#print(f"Startpunkt nicht enthalten {einzelbeobachtung}")
liste_beobachtungen_bearbeitung.append(einzelbeobachtung)
startpunkt = None
zielpunkt = None
@@ -919,24 +1123,20 @@ class Import:
summe_dh += beobachtung_bearbeiten[3]
summe_entfernung += beobachtung_bearbeiten[4]
anzahl_standpunkte += 1
# Achtung:Hier Rundung auf 8 Nachkommastellen!
liste_beobachtungen_reduziert.append(
(zugnummer, startpunkt, zielpunkt, round(summe_dh, 8),
round(summe_entfernung, 8), anzahl_standpunkte))
liste_beobachtungen_bearbeitung = []
else:
#print(f"Startpunkt und Zielpunkt nicht enthalten {einzelbeobachtung}")
liste_beobachtungen_bearbeitung.append(einzelbeobachtung)
else:
#print(f"-----------------------------")
if einzelbeobachtung[1] in liste_netzpunkte and einzelbeobachtung[2] in liste_netzpunkte:
#print(einzelbeobachtung)
liste_beobachtungen_reduziert.append(einzelbeobachtung + (1,))
elif einzelbeobachtung[1] in liste_netzpunkte and einzelbeobachtung[2] not in liste_netzpunkte:
#print(f"Zielpunkt nicht enthalten {einzelbeobachtung}")
liste_beobachtungen_bearbeitung.append(einzelbeobachtung)
elif einzelbeobachtung[1] not in liste_netzpunkte and einzelbeobachtung[2] in liste_netzpunkte:
#print(f"Startpunkt nicht enthalten {einzelbeobachtung}")
liste_beobachtungen_bearbeitung.append(einzelbeobachtung)
startpunkt = None
zielpunkt = None
@@ -954,12 +1154,12 @@ class Import:
summe_dh += beobachtung_bearbeiten[3]
summe_entfernung += beobachtung_bearbeiten[4]
anzahl_standpunkte += 1
#Achtung:Hier Rundung auf 8 Nachkommastellen!
liste_beobachtungen_reduziert.append(
(zugnummer, startpunkt, zielpunkt, round(summe_dh,8), round(summe_entfernung,8), anzahl_standpunkte))
liste_beobachtungen_bearbeitung = []
else:
# print(f"Startpunkt und Zielpunkt nicht enthalten {einzelbeobachtung}")
liste_beobachtungen_bearbeitung.append(einzelbeobachtung)
zugnummer_vorher = zugnummer
@@ -970,22 +1170,28 @@ class Import:
con.commit()
cursor.close()
con.close()
return f"Die Beobachtungen aus der Datei {pfad_datei} wurden erfolgreich importiert."
else:
print(f"Anzahl nicht RVVR 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:
liste_zeilen = []
dict_koordinaten = {}
"""Importiert GNSS-Koordinaten (ECEF) in die Tabelle Netzpunkte.
Die Datei wird semikolon-separiert gelesen und zusätzlich aufgesplittet (Leerzeichen und Kommas).
Für Referenzstationen (Kennzeichnung "Referenz" und Standardabweichungen 0.0000/0.0000/0.0000)
werden die übergebenen Genauigkeiten (X/Y/Z) eingesetzt.
Die Koordinaten und Standardabweichungen werden in Netzpunkte geschrieben.
:param pfad_datei: Pfad zur Koordinatendatei.
:type pfad_datei: str
:param liste_sapos_stationen_genauigkeiten: Liste mit drei Werten [σX, σY, σZ] für Referenzstationen.
:type liste_sapos_stationen_genauigkeiten: list
:return: Statusmeldung zum erfolgreichen Import.
:rtype: str
"""
con = sqlite3.connect(self.pfad_datenbank)
cursor = con.cursor()
@@ -995,7 +1201,6 @@ class Import:
row_neu = []
for eintrag in row:
eintrag = str(eintrag).strip()
eintrag = eintrag.replace("'", "")
aufgeteilt = eintrag.split()
for teil in aufgeteilt:
@@ -1012,14 +1217,33 @@ class Import:
stabw_vorinfo_y = excluded.stabw_vorinfo_y,
stabw_vorinfo_z = excluded.stabw_vorinfo_z""", (row_neu[0], row_neu[4], row_neu[5], row_neu[6], row_neu[7], row_neu[8], row_neu[9])
)
#liste_zeilen.append(row_neu)
con.commit()
con.close()
return "Import der Koordinaten aus stationärem GNSS abgeschlossen."
def import_basislinien_gnss(self, pfad_datei: str, instrumentenID: int) -> None:
"""Importiert GNSS-Basislinien inkl. Kovarianzen in die Tabelle Beobachtungen.
Die Datei wird zeilenweise gelesen und Basislinien werden über Präfixe erkannt:
- @+ : Ziel-/Punktkennung (ID),
- @- : Gegenpunktkennung und Komponenten (bx/by/bz),
- @= : s0 und Kovarianzterme (cxx, cxy, cxz, cyy, cyz, czz).
Vorabprüfungen:
- Abbruch, wenn der Dateiname bereits in Beobachtungen vorkommt,
- Abbruch, wenn instrumentenID nicht in Instrumente existiert.
:param pfad_datei: Pfad zur Basisliniendatei (Text).
:type pfad_datei: str
:param instrumentenID: ID des verwendeten GNSS-Instruments (FK auf Instrumente).
:type instrumentenID: int
:return: None
:rtype: None
"""
# Import_fortsetzen wird False, sobald eine Fehler festgestellt wird. Als Folge wird der Import abgebrochen und eine Fehlermeldung mit Handlungshinweisen für den Benutzer ausgegeben.
Import_fortsetzen = True
# Prüfen, ob Bereits Daten aus der Datei in der Datenbank vorhanden sind
@@ -1033,18 +1257,16 @@ class Import:
if pfad_datei in liste_dateinamen_in_db:
Import_fortsetzen = False
# Import abbrechen, wenn das Instrument noch nicht vom Benutzer angelegt wurde.
liste_instrumentenid = [r[0] for r in cursor.execute("SELECT instrumenteID FROM Instrumente").fetchall()]
cursor.close()
con.close()
cursor.close
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.")
if Import_fortsetzen:
liste_basilinien = []
tupel_basislinie = ()
with (open(pfad_datei, "r", encoding="utf-8") as txt):
@@ -1052,17 +1274,13 @@ class Import:
zeile = str(zeile).rstrip("\n").rstrip("\r")
aufgeteilt = zeile.split()
if aufgeteilt[0][:2] == "@+":
#print(aufgeteilt[0][2:])
tupel_basislinie += (aufgeteilt[0][2:],)
if aufgeteilt[0][:2] == "@-":
#print(aufgeteilt[0][2:], aufgeteilt[1], aufgeteilt[2], aufgeteilt[3])
tupel_basislinie += (aufgeteilt[0][2:], aufgeteilt[1], aufgeteilt[2], aufgeteilt[3],)
if aufgeteilt[0][:2] == "@=":
#print(aufgeteilt[1], aufgeteilt[2], aufgeteilt[3], aufgeteilt[4], aufgeteilt[5], aufgeteilt[6], aufgeteilt[7])
tupel_basislinie += (aufgeteilt[1], aufgeteilt[2], aufgeteilt[3], aufgeteilt[4], aufgeteilt[5], aufgeteilt[6], aufgeteilt[7], )
liste_basilinien.append(tupel_basislinie)
tupel_basislinie = ()
#print(liste_basilinien)
else:
print(
@@ -1078,7 +1296,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.")