Messdatei (sinnvoll) einlesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

1. Umsetzung in meiner CAD-Software (Aktuell "entwickle" ich mit PyCharm)
So, habe vom Hersteller meiner CAD-Software folgende Antwort bekommen:
Generell verwendet GeoMapper IronPython, das ist eine python-Version für dotnet (GeoMapper ist ja eine dotnet-Anwendung)
siehe https://ironpython.net/
Man kann Bibliotheken einbinden, diese müssen aber auch unter dotnet lauffähig sein.
Manche libraries aber nur für CPython ausgelegt, leider auch recht beliebte bibliotheken wie zB numpy (siehe zB https://stackoverflow.com/questions/516 ... ironpython)

IronPython in GeoMapper basiert außerdem noch auf der älteren Python Version 2, die Bibliotheken müssen also auch dafür geeignet sein.
Sobald Ironpython Version 3 herauskommt wollen wir auf diese wechseln, derzeit ist das aber noch eine instabile beta-Version.
Was bedeutet das für meinen Code? Wie muss dieser umgeschrieben werden? Worauf muss ich zukünftig achten?
Wenn sie auf IronPython v.3.x umgestellt haben: wird dann alles "normal"?
Hier der aktuelle Stand:

Code: Alles auswählen

# XPAD to GeoMapper

import time
from pathlib import Path
from pprint import pprint
from tkinter import filedialog


# TODO

# CSV auslesen
# ( )   Objekte sinnvoll einlesen

# RAW auslesen
# (x)   Punkte einlesen und in Liste speichern
# (x)   RAW nach PNT und GIS durchsuchen
# ( )   Fields sinnvoll auf Liste aufteilen
# ( )       Punkt-Infos
# ( )       Punkt-GIS-Daten
# ( )       Linien

# Daten aus RAW mit CSV abgleichen und behandeln (siehe Konzept.pdf)

# Anpassungen, damit es auch in GeoMapper implementiert werden kann

# GUI basteln (siehe Konzept.pdf)




# MESSCODEZUORDNUNGSDATEIPFAD = Path(filedialog.askopenfilename(
#     initialdir = 'C:/ProgramData/rmDATA/Shared/CodeGrafik',
#     title = 'GeoMapper Messcodezuordnung (CSV) auswählen',
#     filetypes = [('Messcodezuordnungsdatei', '*.csv')]
#     )
# )

MESSDATEIPFAD = Path(filedialog.askopenfilename(
    initialdir = 'C:/Firma/Projekte (aktuell)/2022-09-20_T_Messdatei',
    title = 'Geomax Messdatei (RAW) auswählen',
    filetypes = [('XPAD-Datei', '*.raw')]
    )
)

PNT = 'PNT'
GIS = 'GIS'
DPL = 'DPL'
DELIMITER = ','


def main():
    start_time = time.monotonic()

    with MESSDATEIPFAD.open('r', encoding='utf-8') as messdatei:
        punkte_raw = []
        linien_raw = []
        read_gis = False
        for line in messdatei:
            head, _, tail = line.rstrip().partition(DELIMITER)
            if head == PNT:
                punkte_raw.append(tail)
                read_gis = True
            elif read_gis and head == GIS:
                punkte_raw.append(tail)
                read_gis = False
            elif head == DPL:
                linien_raw.append(tail)
        print('Punkte:')
        pprint(punkte_raw)
        print('Linien:')
        pprint(linien_raw)

    print(time.monotonic() - start_time)


if __name__ == '__main__':
    main()
2. Aufsplitten eines Strings (der nächste Schritt)
Ein typischer String, der verarbeitet werden muss sieht folgendermaßen aus:

Code: Alles auswählen

Für eine PNT-Zeile:
'NMFF220817008,CD6012,NO5664154.2246,ET686640.9372,EL151.1474,LT0.891836393413,LN0.203604921459,HT196.6247,TPGPS_POINT,NTNutzungsartengrenze,DT2022-08-17,HM09:54:45'
oder
Für eine GIS-Zeile
'FTLB,ATField1=Value1,ATField2=Value2'
Davon werden etliche eingelesen und sollen in einer Liste/Dictionary/... abgelegt werden.
Wie kann man das aufspalten (ich bin der Meinung, dass split() mit hier nur bedingt weiterhilft)?

Ein Umbenennen der Schlüssel (z.B. 'NM', oder 'CD') ist m.E. nicht nötig. Zumindest halte ich es nicht für nötig, da ich die Schlüssel im Allgemeinen kenne und sie so viel gezielter ansprechen kann.

3. Speicherung der Daten (die Idee: Dictionary)
Ich glaube, dass ein Dictionary hilfreich für mein Vorhaben sein kann. Meine bisherigen Tests waren aber bisher nicht ganz von Erfolg gekrönt, da ich augenscheinlich kein Dictionary in einem Dictionary speichern kann:

Code: Alles auswählen

from pprint import pprint

test_punkte = (
    {
        'NM': 'FF220817008',
        'CD': '6012',
        'NO': '5664154.2246',
        'ET': '686640.9372',
        'EL': '151.1474',
        'LT': '0.891836393413',
        'LN': '0.203604921459',
        'HT': '196.6247',
        'TP': 'GPS_POINT',
        'NT': 'Nutzungsartengrenze',
        'DT': '2022-08-17',
        'HM': '09:54:45',
        # 'GIS: {'Field1': 'Value1', 'Field2': 'Value2'}
    },
    {
        'NM': 'FF220817089',
        'CD': '6003',
        'NO': '5664232.7894',
        'ET': '686815.5678',
        'EL': '140.4580',
        'LT': '',
        'LN': '',
        'HT': '',
        'TP': 'REFERENCEPOINT',
        'NT': 'Polygon-Punkt',
        'DT': '2022-08-17',
        'HM': '12:23:12',
        # 'GIS: {'Vermarkungsart': 'RmK', 'Zustand': 'i.O.'}
    }
)

pprint(test_punkte)
Habt ihr andere Ideen?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann kannst du Module wie tkinter und pathlib schonmal vergessen.

Und natuerlich kann man ein Woerterbuch in einem Woerterbuch ablegen:

Code: Alles auswählen

a = { "foo": { "bar": "baz"}}
Warum glaubst du hilft dir split nicht? Das ist doch sprichwoertlich zum aufsplitten gemacht?
Benutzeravatar
__blackjack__
User
Beiträge: 13931
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: Der Code muss so geschrieben sein, dass er auf Python 2.7 läuft, und darf nur Module verwenden, die in Python geschrieben sind. Und es gehen, falls es das gibt, natürlich auch Module die speziell für IronPython geschrieben sind. Wahrscheinlich gibt es dann noch ein paar kleine Abweichungen von CPython, wie das auch bei Jython (Python-Implementierung für Java) der Fall ist.

Falls nicht ganz sicher ist, dass der Code nie unter Python 3 laufen muss, würde ich versuchen den möglichst so zu schreiben, dass er sowohl unter Python 2 als auch Python 3 lauffähig ist. Eventuell mit ein bisschen Hilfe beispielsweise mit dem `six`-Modul.

Ob durch die Umstellung auf Python 3 bei GeoMapper alles ”normal” wird, kommt auf die Definition von ”normal” an. 😜 Es dürften weiterhin Module tabu sein, die nicht in Python oder speziell für IronPython geschrieben wurden.

Die Dateidialoge ausserhalb der `main()`-Funktion sind keine gute Idee. Jetzt kann man das nicht mehr importieren, ohne das der Benutzer nach Dateien gefragt wird, die dann aber gar nicht verwendet werden.

Der Code kann ausserdem nicht damit umgehen falls der Benutzer keine Datei auswählt, sondern den Dialog abbricht.

Zusätzlich zum `split()` braucht man für die Schlüssel beim "PNT" noch slicing um die zwei Buchstaben am Anfang vom Rest zu trennen:

Code: Alles auswählen

#!/usr/bin/env python3
from pathlib import Path
from pprint import pprint
from tkinter import filedialog

# TODO

# CSV auslesen
# ( )   Objekte sinnvoll einlesen

# RAW auslesen
# (x)   Punkte einlesen und in Liste speichern
# (x)   RAW nach PNT und GIS durchsuchen
# ( )   Fields sinnvoll auf Liste aufteilen
# ( )       Punkt-Infos
# ( )       Punkt-GIS-Daten
# ( )       Linien

# Daten aus RAW mit CSV abgleichen und behandeln (siehe Konzept.pdf)

# Anpassungen, damit es auch in GeoMapper implementiert werden kann

# GUI basteln (siehe Konzept.pdf)

MESSDATEIORDNERPFAD = Path(
    "E:/Firma/Projekte (aktuell)/2022-09-20_T_Messdatei"
)
MESSDATEIORDNERPFAD = Path(".")
# MESSCODEZUORDNUNGSDATEIPORDNERFAD = Path(
#     "C:/ProgramData/rmDATA/Shared/CodeGrafik"
# )

DPL = "DPL"
GIS = "GIS"
PNT = "PNT"
DELIMITER = ","
POINT_KEYS = {
    "CD",
    "DT",
    "EL",
    "ET",
    "GIS",
    "HM",
    "HT",
    "LN",
    "LT",
    "NM",
    "NO",
    "NT",
    "TP",
}
GIS_KEYS = {"ATKrone", "ATStamm"}


def parse_point(line):
    result = {part[:2]: part[2:] for part in line.split(DELIMITER)}
    result[GIS] = None
    if result.keys() != POINT_KEYS:
        raise ValueError(
            f"parsed point keys {sorted(result.keys())} don't match"
            f" expected keys {sorted(POINT_KEYS)} in {line!r}"
        )
    return result


def parse_gis(line):
    result = {
        key: value
        for key, assignment, value in (
            part.partition("=") for part in line.split(DELIMITER)
        )
        if assignment
    }
    if result.keys() != GIS_KEYS:
        raise ValueError(
            f"parsed GIS keys {sorted(result.keys())} don't match"
            f" expected keys {sorted(GIS_KEYS)} in {line!r}"
        )

    return result


def load_measurements(file_path):
    with file_path.open("r", encoding="utf-8") as messdatei:
        punkte = []
        linien = []
        read_gis = False
        for line in messdatei:
            record_type, _, record_content = line.rstrip().partition(DELIMITER)
            if record_type == PNT:
                punkte.append(parse_point(record_content))
                read_gis = True
            elif read_gis and record_type == GIS:
                punkte[-1][GIS] = parse_gis(record_content)
                read_gis = False
            elif record_type == DPL:
                linien.append(record_content)  # TODO Parse content‽

    return punkte, linien


def main():
    messdateiname = filedialog.askopenfilename(
        initialdir=MESSDATEIORDNERPFAD,
        title="Geomax Messdatei (RAW) auswählen",
        filetypes=[("XPAD-Datei", "*.raw")],
    )
    if messdateiname:
        punkte, linien = load_measurements(Path(messdateiname))
        pprint(punkte)
        pprint(linien)


if __name__ == "__main__":
    main()
Mit den Daten vom Anfang (die anscheinend keine Linien enthalten) gibt das:

Code: Alles auswählen

[{'CD': '1004',
  'DT': '2022-08-15',
  'EL': '',
  'ET': '686724.1620',
  'GIS': None,
  'HM': '15:37:42',
  'HT': '',
  'LN': '',
  'LT': '',
  'NM': '10100',
  'NO': '5664853.3020',
  'NT': 'Trigonometrischer Punkt (TP)',
  'TP': 'REFERENCE'},
 {'CD': '1002',
  'DT': '2022-08-16',
  'EL': '130.2558',
  'ET': '687108.2964',
  'GIS': None,
  'HM': '11:22:44',
  'HT': '175.7256',
  'LN': '0.203722573488',
  'LT': '0.891856020118',
  'NM': 'PP07',
  'NO': '5664296.3700',
  'NT': 'Polygonpunkt (PP)',
  'TP': 'REFERENCE'},
 {'CD': '6012',
  'DT': '2022-08-17',
  'EL': '151.7266',
  'ET': '686639.0358',
  'GIS': None,
  'HM': '09:50:45',
  'HT': '197.2040',
  'LN': '0.203604389041',
  'LT': '0.891835378887',
  'NM': 'FF220817001',
  'NO': '5664147.6845',
  'NT': 'Nutzungsartengrenze',
  'TP': 'GPS_POINT'},
 {'CD': '',
  'DT': '2022-08-17',
  'EL': '151.7751',
  'ET': '686625.9103',
  'GIS': None,
  'HM': '09:50:45',
  'HT': '197.2530',
  'LN': '0.203600822850',
  'LT': '0.891830272600',
  'NM': '2521',
  'NO': '5664114.6384',
  'NT': '',
  'TP': 'GPS_BASE'},
 {'CD': '6012',
  'DT': '2022-08-17',
  'EL': '151.5120',
  'ET': '686637.6236',
  'GIS': None,
  'HM': '09:54:23',
  'HT': '196.9893',
  'LN': '0.203604096481',
  'LT': '0.891836413398',
  'NM': 'FF220817006',
  'NO': '5664154.2320',
  'NT': 'Nutzungsartengrenze',
  'TP': 'GPS_POINT'},
 {'CD': '6006',
  'DT': '2022-08-17',
  'EL': '145.1069',
  'ET': '686811.3461',
  'GIS': {'ATKrone': '9', 'ATStamm': '0.8'},
  'HM': '10:21:46',
  'HT': '190.5810',
  'LN': '0.203648038920',
  'LT': '0.891847364489',
  'NM': 'FF220817088',
  'NO': '5664230.3814',
  'NT': 'TOT',
  'TP': 'GPS_HIDDEN_DISTDIST'},
 {'CD': '6017',
  'DT': '2022-08-17',
  'EL': '131.8676',
  'ET': '687045.0910',
  'GIS': None,
  'HM': '11:31:52',
  'HT': '177.3375',
  'LN': '0.203707327215',
  'LT': '0.891864901365',
  'NM': 'FF220817264',
  'NO': '5664350.7239',
  'NT': 'Böschung deutlich oben',
  'TP': 'GPS_POINT'},
 {'CD': '6017',
  'DT': '2022-08-17',
  'EL': '141.6355',
  'ET': '686946.5415',
  'GIS': None,
  'HM': '13:47:18',
  'HT': '187.1074',
  'LN': '0.203682137599',
  'LT': '0.891854165067',
  'NM': 'FF220817583',
  'NO': '5664278.6641',
  'NT': 'Böschung deutlich oben',
  'TP': 'GPS_POINT'},
 {'CD': '5103',
  'DT': '2022-08-18',
  'EL': '154.3807',
  'ET': '686619.2512',
  'GIS': {'ATKrone': '5', 'ATStamm': '0.37'},
  'HM': '15:15:01',
  'HT': '199.8567',
  'LN': '0.203600661806',
  'LT': '0.891856326283',
  'NM': 'FF220818347',
  'NO': '5664280.5812',
  'NT': 'AT',
  'TP': 'TPS_POINT'},
 {'CD': '6004',
  'DT': '2022-08-22',
  'EL': '155.9097',
  'ET': '686622.5691',
  'GIS': {'ATKrone': '3', 'ATStamm': '0.12'},
  'HM': '12:04:06',
  'HT': '201.3878',
  'LN': '0.203599893071',
  'LT': '0.891828590566',
  'NM': 'FF220822376',
  'NO': '5664103.7885',
  'NT': 'Laubbaum',
  'TP': 'GPS_POINT'},
 {'CD': '6018',
  'DT': '2022-08-22',
  'EL': '159.7462',
  'ET': '686625.8204',
  'GIS': None,
  'HM': '12:19:34',
  'HT': '205.2248',
  'LN': '0.203600275874',
  'LT': '0.891821155827',
  'NM': 'FF220822393',
  'NO': '5664056.4836',
  'NT': 'Böschung undeutlich unten',
  'TP': 'GPS_POINT'},
 {'CD': '6018',
  'DT': '2022-08-22',
  'EL': '159.9720',
  'ET': '686626.0167',
  'GIS': None,
  'HM': '12:19:42',
  'HT': '205.4507',
  'LN': '0.203600294850',
  'LT': '0.891820635184',
  'NM': 'FF220822394',
  'NO': '5664053.1698',
  'NT': 'Böschung undeutlich unten',
  'TP': 'GPS_POINT'}]
[]
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Erst einmal Danke. Das Skript wirft aber bei mir Fehler (die Ursache dafür ist mutmaßlich 3. (s.u.)). Deshalb hier ein paar Fragen/Anmerkungen:
  1. Umsetzung zu IronPython 2
    Laut @__deets__
    Dann kannst du Module wie tkinter und pathlib schonmal vergessen.
    sind in IronPython path und tkinter nicht zulässig/erlaubt - sie funktionieren einfach nicht.
    Ohne die beiden müsste ich ja den Dateipfad und Dateiname direkt im Code eingeben. Dies ist zwar im aktuellen Stadium kein Problem, aber in einer zukünftigen Version 1 will ich ja ein wenig Komfort haben... Ideen dazu?
  2. Zweifache Initialisierung einer Konstanten
    Warum initialisierst du zwei mal MESSDATEIORDNERPFAD ?
  3. GIS
    1. GIS_KEYS
      diese sind definitiv keine Konstanten: sie können ganz unterschiedlich sein. Die Zuordnung muss also variabel bleiben
      Beispiel:

      Code: Alles auswählen

      'GIS,FTEinAusLauf,ATBezeichnung=A,ATDimension=400,ATMaterial=B'
      oder
      'GIS,FTDeckel,ATDurchmesser=0.7'
      oder
      'GIS,FTAblauf eckig,ATLaenge=0.3,ATBreite=0.5'
      oder
      'GIS,FTLB,ATKrone=4,ATStamm=0.17'
      oder eben auch 
      None (aber das hast du ja bereits erkannt)
      
    2. Die Aufteilung sollte nur für die Attribute und Attributswerte passieren. Das "AT" am Anfang interessiert mich nicht.
      Also aus der Zeile

      Code: Alles auswählen

      'GIS,FTEinAusLauf,ATBezeichnung=A,ATDimension=400,ATMaterial=B'
      soll

      Code: Alles auswählen

      'GIS': {'Bezeichnung': 'A', 'Dimension': '400', 'Material': 'B'},
      (Auszug) entstehen
    Gerade b. liegt an mir und den von mir zur verfügung gestellten Daten...daraus ging das bestimmt nicht hervor...sorry
  4. POINT_KEYS
    Die POINT_KEYS können von seitens des Erstellers der Messdatei theoretisch in zukünftigen Versionen mehr/andere werden. Wie gehe ich damit um, wenn sie von vorhinein "gesetzt" sind? Meine naive Grundidee war ja eh eine Andere: laufe durch den gesamten String durch und schau dir alles bis zum nächsten Komma an und splitte dann den String in ein Dictionary, mach dann bis zum Ende des Strings so weiter. Damit ist man doch viel flexiebler und ist für eventuelle Anpassungen gerüstet, oder irre ich mich?
  5. kommt, wenn ich deinen Code weiter durchdrungen habe
Benutzeravatar
__blackjack__
User
Beiträge: 13931
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: Ad 1. Von Python 2 zu Python 3 gab es einige Umordnungen/Umbenennungen in der Standardbibliothek. `tkinter` hiess vorher `Tkinter` mit einem grossen ”T” und einige Module die jetzt innerhalb des `tkinter`-Packages liegen, waren vorher Toplevel Module/Packages. `tkinter.filedialog` in Python 3 war in einem eigenen Modul `FileDialog` in Python 2. Mit dem Modul `six`, das man sowohl in Python 2 als auch in Python 3 installieren kann, ist ein ``from six.moves import tkinter_filedialog as filedialog`` in beiden Python-Versionen möglich.

Selbst wenn man `six` nicht verwenden möchte kann das Package hilfreich sein, zu schauen welche Veränderungen es zwischen Python 2 und 3 gab.

Für das `pathlib`-Modul kann man einen Backport für Python 2 mit ``pip`` installieren. Heisst `pathlib2`. Wenn das Programm unter beiden Versionen lauffähig sein soll, kann man das beispielsweise so lösen:

Code: Alles auswählen

try:
    from pathlib import Path
except ImportError:
    from pathlib2 import Path
Oder man muss den Code auf die Funktionen im `os.path`-Modul umschreiben.

Ad 2. Zum testen weil *ich* hier nicht einmal ein C:-Laufwerk habe, geschweige denn den Pfad. Bei mir liegt die Testdatei im Heimatverzeichnis. Hatte ich eigentlich vor dem Posten wieder rausnehmen wollen, sorry.

Ad 3.a. Ich habe halt versucht mit den Beispieldaten die ich kannte die Eingabe zu prüfen. Ob die zweibuchstabigen Schlüssel bei "PNT" immer gleich sind, wusste ich ja auch nicht. So einfache Sachen prüfe ich ganz gerne im Code, weil man dann mitbekommt wenn die Daten etwas enthalten womit man nicht gerechnet hat, und was man vielleicht irgendwie berücksichtigen möchte oder gar müsste. Wenn die Schlüssel für "GIS" variabel sind, einfach den Prüfcode rausnehmen.

Ad 3.b. Also die mit "AT" am Anfang rausfiltern und den Präfix entfernen.

Ad 4. Grundsätzlich ist das umwandeln in ein Wörterbuch doch so wie ich es gemacht habe am einfachsten. An Komma aufteilen und aus den Teilen dann Schlüssel/Wert-Paare machen.

Wenn die Schlüssel nicht fix über die Zeit sind, gilt auch hier wieder, dass der Test dann so nicht machbar ist. Könnte man also löschen. Falls Dich nur die Schlüssel interessieren, die Du sinnvoll verarbeiten kannst, könntest Du nach dem parsen in ein Wörterbuch nur die Schlüssel/Wert-Paare die Du brauchst in ein neues Wörterbuch übernehmen und das dann zurück geben.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
try:
    from pathlib import Path
except ImportError:
    from pathlib import Path

from pprint import pprint

from six.moves import tkinter_filedialog as filedialog

# TODO

# CSV auslesen
# ( )   Objekte sinnvoll einlesen

# RAW auslesen
# (x)   Punkte einlesen und in Liste speichern
# (x)   RAW nach PNT und GIS durchsuchen
# ( )   Fields sinnvoll auf Liste aufteilen
# ( )       Punkt-Infos
# ( )       Punkt-GIS-Daten
# ( )       Linien

# Daten aus RAW mit CSV abgleichen und behandeln (siehe Konzept.pdf)

# Anpassungen, damit es auch in GeoMapper implementiert werden kann

# GUI basteln (siehe Konzept.pdf)

MESSDATEIORDNERPFAD = Path(
    "E:/Firma/Projekte (aktuell)/2022-09-20_T_Messdatei"
)
# MESSCODEZUORDNUNGSDATEIPORDNERFAD = Path(
#     "C:/ProgramData/rmDATA/Shared/CodeGrafik"
# )

DPL = "DPL"
GIS = "GIS"
PNT = "PNT"
DELIMITER = ","
POINT_KEYS = {
    "CD",
    "DT",
    "EL",
    "ET",
    "GIS",
    "HM",
    "HT",
    "LN",
    "LT",
    "NM",
    "NO",
    "NT",
    "TP",
}
GIS_KEY_PREFIX = "AT"


def parse_point(line):
    result = {part[:2]: part[2:] for part in line.split(DELIMITER)}
    result[GIS] = None
    if result.keys() != POINT_KEYS:
        raise ValueError(
            f"parsed point keys {sorted(result.keys())} don't match"
            f" expected keys {sorted(POINT_KEYS)} in {line!r}"
        )
    return result


def parse_gis(line):
    return {
        key[len(GIS_KEY_PREFIX) :]: value
        for key, assignment, value in (
            part.partition("=") for part in line.split(DELIMITER)
        )
        if assignment and key.startswith(GIS_KEY_PREFIX)
    }


def load_measurements(file_path):
    with file_path.open("r", encoding="utf-8") as messdatei:
        punkte = []
        linien = []
        read_gis = False
        for line in messdatei:
            record_type, _, record_content = line.rstrip().partition(DELIMITER)
            if record_type == PNT:
                punkte.append(parse_point(record_content))
                read_gis = True
            elif read_gis and record_type == GIS:
                punkte[-1][GIS] = parse_gis(record_content)
                read_gis = False
            elif record_type == DPL:
                linien.append(record_content)  # TODO Parse content‽

    return punkte, linien


def main():
    messdateiname = filedialog.askopenfilename(
        initialdir=MESSDATEIORDNERPFAD,
        title="Geomax Messdatei (RAW) auswählen",
        filetypes=[("XPAD-Datei", "*.raw")],
    )
    if messdateiname:
        punkte, linien = load_measurements(Path(messdateiname))
        pprint(punkte)
        pprint(linien)


if __name__ == "__main__":
    main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@__blackjack__: das IronPython tkinter (oder Tkinter) hat, kann ich mir schwerlich vorstellen. Und was ich so finde suggeriert dem ist auch nicht so: https://forum.dynamobim.com/t/python-tk ... dule/33823
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Beim Versuch dein jüngstes Skript zu Starten bekomme ich folgende Meldung:
Traceback (most recent call last):
File "C:\Users\Fabsi\PycharmProjects\Geomax To GeoMapper\venv\Mit Hilfe.py", line 9, in <module>
from six.moves import tkinter_filedialog as filedialog
ModuleNotFoundError: No module named 'six'
Was soll mir das sagen? Muss ich zusätzlich noch etwas nachinstallieren?
Benutzeravatar
__blackjack__
User
Beiträge: 13931
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@__deets__: Stimmt. Ich vermute mal stark IronPython bietet die Möglichkeit .NET-Klassen zu verwenden ähnlich wie Jython Zugriff auf die JVM und Klassen dort zuzugreifen. Und .NET sollte einen Dateidialog haben.

@Feedback1000: Das sagt das `six` nicht installiert ist.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich würde auch auf dieses ganze 2to3/six verzichten. Die Umgebung ist wie sie ist. Und wer TE kämpft schon mit den Grundlagen genug.
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

__deets__ hat geschrieben: Donnerstag 3. November 2022, 08:05 Ich würde auch auf dieses ganze 2to3/six verzichten. Die Umgebung ist wie sie ist. Und wer TE kämpft schon mit den Grundlagen genug.
Was bedeutet das für meinen Code? An welcher Stelle konkret sollte ich schrauben?
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

__blackjack__ hat geschrieben: Mittwoch 2. November 2022, 23:58 @Feedback1000: Das sagt das `six` nicht installiert ist.
In PyCharm habe ich es mittlerweile installiert bekommen, allerdings habe ich das Bauchgefühl, dass das nicht global für meinen PC gilt. Diese naive Denkweise habe ich, da, wenn ich Python --Version in der Eingabeaufforderung eingebe das folgende angezeigt wird:
Python konnte nicht gefunden werden. Führen Sie die Verknüpfung ohne Argumente aus, um sie über den Microsoft Store zu installieren, oder deaktivieren Sie diese Verknüpfung unter
Ist das ein riesen Problem, oder "normal"?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Feedback1000 hat geschrieben: Donnerstag 3. November 2022, 16:25 Was bedeutet das für meinen Code? An welcher Stelle konkret sollte ich schrauben?
Fuer deinen Code garnix. Fuer den, den __blackjack__ fuer dich geschrieben hat: das Modul six nicht benutzen. Und weil tkinter auf deiner Plattform eh nicht verfuegbar ist, alles was damit zu tun hat.
nezzcarth
User
Beiträge: 1735
Registriert: Samstag 16. April 2011, 12:47

Feedback1000 hat geschrieben: Donnerstag 3. November 2022, 16:30 Ist das ein riesen Problem, oder "normal"?
Das hängt davon ab, was du genau vorhast. An sich muss Python in gar keiner Umgebung laufen – weder in Pycharm noch deiner Software. Ein einfaches Skript, das ein paar Infos aus einer Datei parsed und ausgibt oder in ein anderes Format konvertiert, könnte auch einfach nur ein Kommandozeilentool sein, dass du regulär über die Windows Shell ausführst. Dafür muss Python dann aber regulär im Betriebssystem installiert sein. Falls dein Python-Skript innerhalb der Software laufen muss/soll, ist nicht zwingend erforderlich, dass es regulär unter deinem Betriebssystem installiert ist; dieses IronPython ist ja genau dazu da, in andere Software eingebettet zu werden.
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

nezzcarth hat geschrieben: Donnerstag 3. November 2022, 18:46
Feedback1000 hat geschrieben: Donnerstag 3. November 2022, 16:30 Ist das ein riesen Problem, oder "normal"?
Das hängt davon ab, was du genau vorhast. An sich muss Python in gar keiner Umgebung laufen – weder in Pycharm noch deiner Software. Ein einfaches Skript, das ein paar Infos aus einer Datei parsed und ausgibt oder in ein anderes Format konvertiert, könnte auch einfach nur ein Kommandozeilentool sein, dass du regulär über die Windows Shell ausführst. Dafür muss Python dann aber regulär im Betriebssystem installiert sein. Falls dein Python-Skript innerhalb der Software laufen muss/soll, ist nicht zwingend erforderlich, dass es regulär unter deinem Betriebssystem installiert ist; dieses IronPython ist ja genau dazu da, in andere Software eingebettet zu werden.
Wenn ich also das Ganze korrekt verstanden habe, dann ist IronPython eine "angepasste/modifizierte/eingeschränkte Variante" des "normalen" Phython?
Hinzu kommt, dass meine CAD-Software noch eine veraltete Version von IronPython verwendet, die nochmals eingeschränkter ist....

Was könnte dann noch der Grund sein, dass der Code von __blackjack__ noch nicht in meiner CAD-Software läuft?

Als Fehlermeldung kommt
invalid syntax
Zeile 64, Spalte 14
nezzcarth
User
Beiträge: 1735
Registriert: Samstag 16. April 2011, 12:47

Feedback1000 hat geschrieben: Donnerstag 3. November 2022, 19:02 Wenn ich also das Ganze korrekt verstanden habe, dann ist IronPython eine "angepasste/modifizierte/eingeschränkte Variante" des "normalen" Phython?
Hinzu kommt, dass meine CAD-Software noch eine veraltete Version von IronPython verwendet, die nochmals eingeschränkter ist..
"Normales" Python funktioniertso, grob vereinfacht gesagt, dass du einen Python-Interpreter installierst und wenn du ein in Python geschriebenes Programm ausführen möchtest, wird das mit diesem Interpreter ausgeführt, als "selbständige" Software. IronPython ist eine Variante von Python, die nicht nativ direkt auf dem Betriebssystem läuft, sondern in der .Net Umgebung von Microsoft. Und in deinem Fall wird es so verwendet, dass deine CAD Software Python als eingebettete Sprache innerhalb der Anwendung benutzt, um Erweiterungen programmieren zu können (das geht mit "normalem" Python auch, aber halt nicht für .Net Anwendungen). Steuerst du aus deinem Skript denn überhaupt Features aus der CAD-Software an, bzw. ist dein Ziel überhaupt, Erweiterungen für die CAD-Anwendung zu schreiben? Denn falls nicht, muss es da dann überhaupt drin laufen?
Feedback1000 hat geschrieben: Donnerstag 3. November 2022, 19:02 Was könnte dann noch der Grund sein, dass der Code von __blackjack__ noch nicht in meiner CAD-Software läuft?
An der Stelle werden f-Strings verwendet, die es in Python 2 noch nicht gab. Das muss auf die dort verfügbaren Stringformatierungsmöglichkeiten angepasst werden.
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

nezzcarth hat geschrieben: Donnerstag 3. November 2022, 20:01 Steuerst du aus deinem Skript denn überhaupt Features aus der CAD-Software an, bzw. ist dein Ziel überhaupt, Erweiterungen für die CAD-Anwendung zu schreiben? Denn falls nicht, muss es da dann überhaupt drin laufen?
Z. Z. noch nicht, aber das wird kommen. Bis dahin wird aber noch einiges an Wasser den Rhein herunter fließen....
nezzcarth hat geschrieben: Donnerstag 3. November 2022, 20:01 An der Stelle werden f-Strings verwendet, die es in Python 2 noch nicht gab. Das muss auf die dort verfügbaren Stringformatierungsmöglichkeiten angepasst werden.
Heute Abend habe ich keine Möglichkeit mehr deinen Tipp zu testen, aber wenn ich dich richtig verstanden habe, dann muss ich "nur" die f-Strings umschreiben und dann sollte alles laufen?
Benutzeravatar
__blackjack__
User
Beiträge: 13931
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: Ich weiss nicht ob nezzcarth sich das genauer angeschaut hat, es kann auch sein, dass danach noch andere Änderungen vorgenommen werden müssen. Die meisten die hier antworten werden vorrangig in Python 3 ”denken” und auch nur noch eine aktuelle 3er-Version zum ausprobieren verwenden.

Syntaktisch wird das noch über das Nicht-ASCII-Zeichen in dem TODO-Kommentar stolpern und das "ä" in der einen Zeichenkette in der Hauptfunktion. Also muss man die Kodierung in einem Kodierungskommentar deklarieren.

Dann kommt das zwar am Compiler vorbei, allerdings verhält sich `dict.keys()` in Python 2 anders als in Python 3. Die Stelle muss man auch noch anpassen. Und `pathlib2` muss man installieren, oder eben die entsprechenden Stellen so umschreiben, dass sie die Funktionen in `os.path` verwenden.

Code: Alles auswählen

#!/usr/bin/env python2
# coding: utf-8
from pprint import pprint

from pathlib2 import Path

# TODO

# CSV auslesen
# ( )   Objekte sinnvoll einlesen

# RAW auslesen
# (x)   Punkte einlesen und in Liste speichern
# (x)   RAW nach PNT und GIS durchsuchen
# ( )   Fields sinnvoll auf Liste aufteilen
# ( )       Punkt-Infos
# ( )       Punkt-GIS-Daten
# ( )       Linien

# Daten aus RAW mit CSV abgleichen und behandeln (siehe Konzept.pdf)

# Anpassungen, damit es auch in GeoMapper implementiert werden kann

# GUI basteln (siehe Konzept.pdf)

MESSDATEIORDNERPFAD = Path(
    "E:/Firma/Projekte (aktuell)/2022-09-20_T_Messdatei"
)
# MESSCODEZUORDNUNGSDATEIPORDNERFAD = Path(
#     "C:/ProgramData/rmDATA/Shared/CodeGrafik"
# )

DPL = "DPL"
GIS = "GIS"
PNT = "PNT"
DELIMITER = ","
POINT_KEYS = {
    "CD",
    "DT",
    "EL",
    "ET",
    "GIS",
    "HM",
    "HT",
    "LN",
    "LT",
    "NM",
    "NO",
    "NT",
    "TP",
}
GIS_KEY_PREFIX = "AT"


def parse_point(line):
    result = {part[:2]: part[2:] for part in line.split(DELIMITER)}
    result[GIS] = None
    if set(result.keys()) != POINT_KEYS:
        raise ValueError(
            "parsed point keys {} don't match expected keys {} in {!r}".format(
                sorted(result.keys()), sorted(POINT_KEYS), line
            )
        )
    return result


def parse_gis(line):
    return {
        key[len(GIS_KEY_PREFIX) :]: value
        for key, assignment, value in (
            part.partition("=") for part in line.split(DELIMITER)
        )
        if assignment and key.startswith(GIS_KEY_PREFIX)
    }


def load_measurements(file_path):
    with file_path.open("r", encoding="utf-8") as messdatei:
        points = []
        lines = []
        read_gis = False
        for line in messdatei:
            record_type, _, record_content = line.rstrip().partition(DELIMITER)
            if record_type == PNT:
                points.append(parse_point(record_content))
                read_gis = True
            elif read_gis and record_type == GIS:
                points[-1][GIS] = parse_gis(record_content)
                read_gis = False
            elif record_type == DPL:
                lines.append(record_content)  # TODO Parse content‽

    return points, lines


def main():
    #
    # TODO File dialog in IronPython.
    #
    points, lines = load_measurements(MESSDATEIORDNERPFAD / "test.txt")
    pprint(points)
    pprint(lines)


if __name__ == "__main__":
    main()
Ausgabe mit den Testdaten:

Code: Alles auswählen

[{u'CD': u'1004',
  u'DT': u'2022-08-15',
  u'EL': u'',
  u'ET': u'686724.1620',
  'GIS': None,
  u'HM': u'15:37:42',
  u'HT': u'',
  u'LN': u'',
  u'LT': u'',
  u'NM': u'10100',
  u'NO': u'5664853.3020',
  u'NT': u'Trigonometrischer Punkt (TP)',
  u'TP': u'REFERENCE'},
 {u'CD': u'1002',
  u'DT': u'2022-08-16',
  u'EL': u'130.2558',
  u'ET': u'687108.2964',
  'GIS': None,
  u'HM': u'11:22:44',
  u'HT': u'175.7256',
  u'LN': u'0.203722573488',
  u'LT': u'0.891856020118',
  u'NM': u'PP07',
  u'NO': u'5664296.3700',
  u'NT': u'Polygonpunkt (PP)',
  u'TP': u'REFERENCE'},
 {u'CD': u'6012',
  u'DT': u'2022-08-17',
  u'EL': u'151.7266',
  u'ET': u'686639.0358',
  'GIS': None,
  u'HM': u'09:50:45',
  u'HT': u'197.2040',
  u'LN': u'0.203604389041',
  u'LT': u'0.891835378887',
  u'NM': u'FF220817001',
  u'NO': u'5664147.6845',
  u'NT': u'Nutzungsartengrenze',
  u'TP': u'GPS_POINT'},
 {u'CD': u'',
  u'DT': u'2022-08-17',
  u'EL': u'151.7751',
  u'ET': u'686625.9103',
  'GIS': None,
  u'HM': u'09:50:45',
  u'HT': u'197.2530',
  u'LN': u'0.203600822850',
  u'LT': u'0.891830272600',
  u'NM': u'2521',
  u'NO': u'5664114.6384',
  u'NT': u'',
  u'TP': u'GPS_BASE'},
 {u'CD': u'6012',
  u'DT': u'2022-08-17',
  u'EL': u'151.5120',
  u'ET': u'686637.6236',
  'GIS': None,
  u'HM': u'09:54:23',
  u'HT': u'196.9893',
  u'LN': u'0.203604096481',
  u'LT': u'0.891836413398',
  u'NM': u'FF220817006',
  u'NO': u'5664154.2320',
  u'NT': u'Nutzungsartengrenze',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6006',
  u'DT': u'2022-08-17',
  u'EL': u'145.1069',
  u'ET': u'686811.3461',
  'GIS': {u'Krone': u'9', u'Stamm': u'0.8'},
  u'HM': u'10:21:46',
  u'HT': u'190.5810',
  u'LN': u'0.203648038920',
  u'LT': u'0.891847364489',
  u'NM': u'FF220817088',
  u'NO': u'5664230.3814',
  u'NT': u'TOT',
  u'TP': u'GPS_HIDDEN_DISTDIST'},
 {u'CD': u'6017',
  u'DT': u'2022-08-17',
  u'EL': u'131.8676',
  u'ET': u'687045.0910',
  'GIS': None,
  u'HM': u'11:31:52',
  u'HT': u'177.3375',
  u'LN': u'0.203707327215',
  u'LT': u'0.891864901365',
  u'NM': u'FF220817264',
  u'NO': u'5664350.7239',
  u'NT': u'B\xf6schung deutlich oben',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6017',
  u'DT': u'2022-08-17',
  u'EL': u'141.6355',
  u'ET': u'686946.5415',
  'GIS': None,
  u'HM': u'13:47:18',
  u'HT': u'187.1074',
  u'LN': u'0.203682137599',
  u'LT': u'0.891854165067',
  u'NM': u'FF220817583',
  u'NO': u'5664278.6641',
  u'NT': u'B\xf6schung deutlich oben',
  u'TP': u'GPS_POINT'},
 {u'CD': u'5103',
  u'DT': u'2022-08-18',
  u'EL': u'154.3807',
  u'ET': u'686619.2512',
  'GIS': {u'Krone': u'5', u'Stamm': u'0.37'},
  u'HM': u'15:15:01',
  u'HT': u'199.8567',
  u'LN': u'0.203600661806',
  u'LT': u'0.891856326283',
  u'NM': u'FF220818347',
  u'NO': u'5664280.5812',
  u'NT': u'AT',
  u'TP': u'TPS_POINT'},
 {u'CD': u'6004',
  u'DT': u'2022-08-22',
  u'EL': u'155.9097',
  u'ET': u'686622.5691',
  'GIS': {u'Krone': u'3', u'Stamm': u'0.12'},
  u'HM': u'12:04:06',
  u'HT': u'201.3878',
  u'LN': u'0.203599893071',
  u'LT': u'0.891828590566',
  u'NM': u'FF220822376',
  u'NO': u'5664103.7885',
  u'NT': u'Laubbaum',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6018',
  u'DT': u'2022-08-22',
  u'EL': u'159.7462',
  u'ET': u'686625.8204',
  'GIS': None,
  u'HM': u'12:19:34',
  u'HT': u'205.2248',
  u'LN': u'0.203600275874',
  u'LT': u'0.891821155827',
  u'NM': u'FF220822393',
  u'NO': u'5664056.4836',
  u'NT': u'B\xf6schung undeutlich unten',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6018',
  u'DT': u'2022-08-22',
  u'EL': u'159.9720',
  u'ET': u'686626.0167',
  'GIS': None,
  u'HM': u'12:19:42',
  u'HT': u'205.4507',
  u'LN': u'0.203600294850',
  u'LT': u'0.891820635184',
  u'NM': u'FF220822394',
  u'NO': u'5664053.1698',
  u'NT': u'B\xf6schung undeutlich unten',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6017',
  u'DT': u'2022-08-17',
  u'EL': u'131.8676',
  u'ET': u'687045.0910',
  'GIS': {u'Bezeichnung': u'A', u'Dimension': u'400', u'Material': u'B'},
  u'HM': u'11:31:52',
  u'HT': u'177.3375',
  u'LN': u'0.203707327215',
  u'LT': u'0.891864901365',
  u'NM': u'FF220817264',
  u'NO': u'5664350.7239',
  u'NT': u'B\xf6schung deutlich oben',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6017',
  u'DT': u'2022-08-17',
  u'EL': u'131.8676',
  u'ET': u'687045.0910',
  'GIS': {u'Durchmesser': u'0.7'},
  u'HM': u'11:31:52',
  u'HT': u'177.3375',
  u'LN': u'0.203707327215',
  u'LT': u'0.891864901365',
  u'NM': u'FF220817264',
  u'NO': u'5664350.7239',
  u'NT': u'B\xf6schung deutlich oben',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6017',
  u'DT': u'2022-08-17',
  u'EL': u'131.8676',
  u'ET': u'687045.0910',
  'GIS': {u'Breite': u'0.5', u'Laenge': u'0.3'},
  u'HM': u'11:31:52',
  u'HT': u'177.3375',
  u'LN': u'0.203707327215',
  u'LT': u'0.891864901365',
  u'NM': u'FF220817264',
  u'NO': u'5664350.7239',
  u'NT': u'B\xf6schung deutlich oben',
  u'TP': u'GPS_POINT'},
 {u'CD': u'6017',
  u'DT': u'2022-08-17',
  u'EL': u'131.8676',
  u'ET': u'687045.0910',
  'GIS': {u'Krone': u'4', u'Stamm': u'0.17'},
  u'HM': u'11:31:52',
  u'HT': u'177.3375',
  u'LN': u'0.203707327215',
  u'LT': u'0.891864901365',
  u'NM': u'FF220817264',
  u'NO': u'5664350.7239',
  u'NT': u'B\xf6schung deutlich oben',
  u'TP': u'GPS_POINT'}]
[]
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

@__blackjack__
Es scheint, als sei ich mit deiner jüngsten Version des Codes einen kleinen Schritt weiter:
No module named pathlib2<string>
Zeile 5
<module> in <string>:5, System.Object Run2[CodeContext,FunctionCode,Object](IronPython.Runtime.CodeContext, IronPython.Runtime.FunctionCode)
(MESSDATEIORDNERPFAD und den Dateinamen habe ich vorher angepasst)

Hilft dir das Zitat?
Woher kommen die "u" in der Ausgabe?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Liest du auch, was hier geschrieben wird? __blackjack__ hat doch klar gesagt, das pathlib2 installiert werden muss. Oder das ganze umgeschrieben auf os.path
Und `pathlib2` muss man installieren, oder eben die entsprechenden Stellen so umschreiben, dass sie die Funktionen in `os.path` verwenden.
Bisher wirkt das ganze eher so, als ob du einfach nur durch posten der Ergebnisse und die Frage nach "wie geht's denn richtig" zum Ziel kommen willst. Eher nicht durch selbst machen. Das wird nicht auf Dauer funktionieren.
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Hallo.
Mittlerweile musste ich das Ganze noch einmal neu denken, da ich langfristig aus der Textdatei ein wenig mehr auslesen muss und bin gerade auf der Zielgeraden für Phase 1. Und plötzlich stoße ich an ein Problem, bei dem ich noch nicht so ganz weis, wie ich es lösen soll.

Ich bekomme die Zeilen aufgeteilt und kann sie auch in ein entsprechendes Dict schreiben. Dann folgen noch weitere Schritte bzw. sollen noch weitere Schritte folgen:
  • Prüfung, ob die Fields so, wie sie eingelesen wurden, überhaupt so vorgesehen sind (um auf Neuerungen reagieren zu können)
  • Prüfung, ob das aktuelle Field 'obligatory': True ist (um Fehler in der Datei bzw. in meinem Datenmodell zu erkennen)
  • Prüfung, ob das entsprechende Field 'expected_values' hat und on der value von aktuellen field da drinnen ist
  • Field_content entsprechend vom 'type' in raw_sections casten und überspeichern
Das Problem sind gelöschte Punkte ('DPN'). Diese haben einen zusätzliches Field ("DELETED").
Hat jemand einen Hinweis, wie ich parse_object_content umschreiben kann, sodass "DELETED" ignoriert wird? Am liebsten brauchen points keine zusätzliche Info "DELETED", denn diese Info steht dann in is_valid.

Hier der aktuelle Stand der Dinge:

Code: Alles auswählen

from pathlib2 import Path
from pprint import pprint

MESSDATEIORDNERPFAD = Path(
    r'C:\Firma\Projekte (aktuell)\2022-09-20_P_Messdatei'
    # r'C:\Users\Fabsi\PycharmProjects\Geomax-Import'
)

# TODO:
#   Objektorientiert arbeiten?
#   ----------------------------- Phase 1 -----------------------------
#   RAW
#   (x) Zeilenweise einlesen
#   ( ) Punkte
#       (x) Punkte (auch gelöschte) erkennen und in Punkte-Liste speichern
#       ( ) GIS erkennen und vorherigem Punkt anhängen
#   ( ) Linien - Linie erkennen und in Linien-Liste speichern
#   ( ) Splines - erkennen und in Linien-Liste speichern
#   ( ) Bögen - erkennen und in Linien-Liste speichern
#   ( ) Kombinationen - erkennen und in Linien-Liste speichern
#   CSV
#   (x) Objekte sinnvoll einlesen
#   ( ) Daten aus RAW mit CSV abgleichen und behandeln (siehe Konzept.pdf)
#   ( ) Anpassungen, damit es auch in GeoMapper implementiert werden kann
#   ----------------------------- Phase 2 -----------------------------
#   RAW
#   ( ) Messungen
#   ( )   TPS
#   ( )   GNSS
#   ( ) weitere Geomax-Objekte (wie z.B. 2- und 3-Punkt-Symbole) behandeln
#   ----------------------------- Phase 3 -----------------------------
#   ( ) Alles über den Haufen werfen, da Objektorientierung implementiert wird
#   ( ) GUI basteln (siehe Konzept.pdf)


raw_sections = {
    # TODO: Es fehlen:
    #  DPP (Spline ?)
    #  DPV (Spline ?)

    'Job data': {
        'section_key': 'JOB',
        'fields': [
            {'field_key': 'FV', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'DT', 'obligatory': False, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': False, 'type': 'h', 'expected_values': []},
            {'field_key': 'NM', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CR', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'Units': {
        'section_key': 'UNM',
        'fields': [
            {'field_key': 'AN', 'obligatory': False, 'type': 't', 'expected_values': ['GON', 'GRAD', 'DMS', 'RAD']},
            {'field_key': 'DS', 'obligatory': False, 'type': 't', 'expected_values': ['METER']},
            {'field_key': 'SL', 'obligatory': False, 'type': 't', 'expected_values': ['%', 'HB']},
            {'field_key': 'LL', 'obligatory': False, 'type': 't', 'expected_values': ['DMS']},
        ]
    },
    'Decimal digits': {
        'section_key': 'DEC',
        'fields': [
            {'field_key': 'AN', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'EL', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'DS', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'AR', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'SL', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'LL', 'obligatory': False, 'type': 'i', 'expected_values': []},
        ]
    },
    'Coordinate settings': {
        'section_key': 'CRD',
        'fields': [
            {'field_key': 'NO', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'ET', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'EL', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'OR', 'obligatory': False, 'type': 't', 'expected_values': ['EN', 'NE']},
        ]
    },
    'Software information': {
        'section_key': 'SWI',
        'fields': [
            {'field_key': 'PL', 'obligatory': True, 'type': 's', 'expected_values': ['WIN', 'ANDROID']},
            {'field_key': 'VR', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'TPS distances reduction': {
        'section_key': 'RED',
        'fields': [
            {'field_key': 'SL', 'obligatory': False, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'AE', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'CS', 'obligatory': False, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'SF', 'obligatory': False, 'type': 'f', 'expected_values': []},
        ]
    },
    'Localization': {
        'section_key': 'LOC',
        'fields': [
            {'field_key': 'HZ', 'obligatory': True, 'type': 't',
             'expected_values': ['NONE', 'SINGLE', 'MULTI', 'COORDSYS']},
            {'field_key': 'VT', 'obligatory': True, 'type': 't',
             'expected_values': ['WGS84', 'LOCAL', 'REFELLIPSOID', 'GEOID']},
        ]
    },
    'Localization one point': {
        'section_key': 'L1P',
        'fields': [
            {'field_key': 'GP', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'LT', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'LN', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'HT', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'LP', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'NO', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'ET', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'EL', 'obligatory': True, 'type': 'f', 'expected_values': []},
        ]
    },
    'Localization multi points': {
        'section_key': 'LMP',
        'fields': [
            {'field_key': 'NM', 'obligatory': True, 'type': 'i', 'expected_values': []},
            {'field_key': 'HZ', 'obligatory': True, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'VT', 'obligatory': True, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'GP', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'LT', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'LN', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'HT', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'LP', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'NO', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'ET', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'EL', 'obligatory': True, 'type': 'f', 'expected_values': []},
        ]
    },
    'Localization with cartographic coordinate system': {
        'section_key': 'LCS',
        'fields': [
            {'field_key': 'NM', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PJ', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'DM', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'EP', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'LT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'LN', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'FN', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'FE', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'SC', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'P1', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'P2', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'Datum for cartographic coordinate system': {
        'section_key': 'DAT',
        'fields': [
            {'field_key': 'NM', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'SX', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'SY', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'SZ', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'RX', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'RY', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'RZ', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'SC', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'DT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PX', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'PY', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'PZ', 'obligatory': True, 'type': 'f', 'expected_values': []},
        ]
    },
    'Ellipsoid for cartographic coordinate system': {
        'section_key': 'ELL',
        'fields': [
            {'field_key': 'NM', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'SA', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'IF', 'obligatory': True, 'type': 'f', 'expected_values': []},
        ]
    },
    'Geoide for vertical localization': {
        'section_key': 'GED',
        'fields': [
            {'field_key': 'NM', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Topographic point': {
        'section_key': ('PNT', 'DPN'),
        'fields': [
            {'field_key': 'NM', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'NO', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'ET', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'EL', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'LT', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'LN', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'HT', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'TP', 'obligatory': False, 'type': 't',
             'expected_values': ['GPS_POINT', 'GPS_BASE', 'GPS_OFFSET_DISTDIST', 'GPS_OFFSET_ALIGNOFF', 'GPS_STATIC',
                                 'GPS_STAKE', 'TPS_STATION', 'TPS_POINT', 'TPS_STAKE', 'COGO', 'REFERENCE', 'USER',
                                 'IMPORT', 'UNKNOWN']},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': False, 'type': 'h', 'expected_values': []},
        ]
    },
    'GIS Attributes': {
        'section_key': 'GIS',
        'fields': [
            {'field_key': 'FT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'AT', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Note': {
        'section_key': 'NTE',
        'fields': [
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': False, 'type': 'h', 'expected_values': []},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'GPS measure': {
        'section_key': 'GPS',
        'fields': [
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': True, 'type': 'h', 'expected_values': []},
            {'field_key': 'BS', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'PT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'LT', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'LN', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'HT', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'AH', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'BH', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'US', 'obligatory': False, 'type': 'd', 'expected_values': []},
            {'field_key': 'UE', 'obligatory': False, 'type': 'd', 'expected_values': []},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'GPS quality measure': {
        'section_key': 'QTY',
        'fields': [
            {'field_key': 'EP', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'GP', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'GS', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'BD', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'GA', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'HD', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'VD', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'PD', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'GD', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'PH', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'PV', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'FQ', 'obligatory': False, 'type': 't',
             'expected_values': ['RTK_FIXED', 'RTK_FLOAT', 'DGPS', 'AUTO', 'UNKNOWN']},
            {'field_key': 'ES', 'obligatory': False, 'type': 'i', 'expected_values': []},
        ]
    },
    'GPS covariance factors': {
        'section_key': 'COV',
        'fields': [
            {'field_key': 'XX', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'XY', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'XZ', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'YY', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'YZ', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'ZZ', 'obligatory': False, 'type': 'f', 'expected_values': []},
        ]
    },
    'GPS measure hidden point by distance-distance': {
        'section_key': 'GPD',
        'fields': [
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': True, 'type': 'h', 'expected_values': []},
            {'field_key': 'PT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'R1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'D1', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'V1', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'R2', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'D2', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'V2', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'RH', 'obligatory': True, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'GPS measure hidden point by distance-offset': {
        'section_key': 'GPO',
        'fields': [
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': True, 'type': 'h', 'expected_values': []},
            {'field_key': 'PT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'R1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'R2', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'RP', 'obligatory': True, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'DS', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'OF', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'HD', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'TPS StationSetup – Begin block': {
        'section_key': 'STB',
        'fields': [
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': True, 'type': 'h', 'expected_values': []},
            {'field_key': 'TP', 'obligatory': True, 'type': 't',
             'expected_values': ['FREE_STATION', 'BACKSIGHT1P', 'NOORIENTATION', 'BACKSIGHT1PAZ', 'BACKSIGHTMULTIP']},
            {'field_key': 'ST', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'IH', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'AZ', 'obligatory': True, 'type': 'f', 'expected_values': []},
        ]
    },
    'TPS StationSetup – End block': {
        'section_key': 'STE',
        'fields': [
            {'field_key': 'TP', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'ST', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'TPS measure': {
        'section_key': 'TPS',
        'fields': [
            {'field_key': 'DT', 'obligatory': True, 'type': 'd', 'expected_values': []},
            {'field_key': 'HM', 'obligatory': True, 'type': 'h', 'expected_values': []},
            {'field_key': 'IH', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'ST', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PT', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CD', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'HA', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'VA', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'SD', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'TH', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'RT', 'obligatory': False, 'type': 'i', 'expected_values': ['0', '1', '2']},
            {'field_key': 'NT', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'PK', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'PM', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'AM', 'obligatory': False, 'type': 'i', 'expected_values': ['0', '1', '2', '3']},
            {'field_key': 'VA', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'VO', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'OA', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'OD', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'OV', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'H1', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'V1', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'S1', 'obligatory': False, 'type': 'f', 'expected_values': []},
            {'field_key': 'H2', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'V2', 'obligatory': True, 'type': 'f', 'expected_values': []},
            {'field_key': 'S2', 'obligatory': False, 'type': 'f', 'expected_values': []},
        ]
    },
    'Polyline': {
        'section_key': 'DPL',
        'fields': [
            {'field_key': 'CD', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'CL', 'obligatory': True, 'type': 'b', 'expected_values': ['Y', 'N']},
            {'field_key': 'CT', 'obligatory': True, 'type': 'i', 'expected_values': []},
        ]
    },
    'Square by diagonal': {
        'section_key': 'DSD',
        'fields': [
            {'field_key': 'CD', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C2', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Square by center and side': {
        'section_key': 'DSC',
        'fields': [
            {'field_key': 'CD', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C2', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Rectangle by base and height': {
        'section_key': 'DRB',
        'fields': [
            {'field_key': 'CD', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C2', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C3', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Rectangle by center and sides or Circle by center and radius': {
        'section_key': 'DRC',
        'fields': [
            {'field_key': 'CD', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C2', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C3', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Circle by 3 points': {
        'section_key': 'DC3',
        'fields': [
            {'field_key': 'CD', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C1', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C2', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'C3', 'obligatory': True, 'type': 's', 'expected_values': []},
        ]
    },
    'Stakeout': {
        'section_key': 'STK',
        'fields': [
            {'field_key': 'ST', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PN', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PX', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PY', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'PZ', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'SN', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'SX', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'SY', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'SZ', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'DX', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'DY', 'obligatory': True, 'type': 's', 'expected_values': []},
            {'field_key': 'DZ', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'PP_Start': {
        'section_key': '[PP_RW5_START]',
        'fields': []
    },
    'PP_End': {
        'section_key': '[PP_RW5_END]',
        'fields': []
    },
    'PP_Time': {
        'section_key': '--PP Time',
        'fields': [
            {'field_key': 'StartWeek', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'StartSec', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'StopWeek', 'obligatory': False, 'type': 'i', 'expected_values': []},
            {'field_key': 'StopSec', 'obligatory': False, 'type': 'i', 'expected_values': []},
        ]
    },
    'PP_Antenna': {
        'section_key': '--Antenna',
        'fields': [
            {'field_key': 'Desc', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'True', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'Meas', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'ARP_V', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'ARP_H', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'NGS_ID', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'NGS_L1', 'obligatory': False, 'type': 's', 'expected_values': []},
            {'field_key': 'NGS_L2', 'obligatory': False, 'type': 's', 'expected_values': []},
        ]
    },
    'Antenna height': {
        'section_key': 'AH',
        'fields': [
            {'field_key': 'DC', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'MA', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'ME', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'RA', 'obligatory': False, 'type': False, 'expected_values': []},
        ]
    },
    'EP': {  # Name noch unkreativ
        'section_key': 'EP',
        'fields': [
            {'field_key': 'TM', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'LA', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'LN', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'HT', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'RH', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'RV', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'DH', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'DV', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'GM', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'CL', 'obligatory': False, 'type': False, 'expected_values': []},
        ]
    },
    'GS': {  # Name noch unkreativ
        'section_key': 'GS',
        'fields': [
            {'field_key': 'PN', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'N ', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'E ', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': 'EL', 'obligatory': False, 'type': False, 'expected_values': []},
            {'field_key': '--', 'obligatory': False, 'type': False, 'expected_values': []},
        ]
    }
}
# pprint(raw_sections, sort_dicts=False)

RAW_SECTION_DELIMITERS = [',', ':']
RAW_OBJECT_DELIMITER = ','
assert RAW_OBJECT_DELIMITER in RAW_SECTION_DELIMITERS
RAW_PP_DELIMITER = '='

JOB = raw_sections['Job data']['section_key']
PNT = raw_sections['Topographic point']['section_key'][0]
DPN = raw_sections['Topographic point']['section_key'][1]
GIS = raw_sections['GIS Attributes']['section_key']
DPL = raw_sections['Polyline']['section_key']
PP_START = raw_sections['PP_Start']['section_key']
PP_END = raw_sections['PP_End']['section_key']
PP_KEYS = [raw_sections['PP_Time']['section_key'], raw_sections['PP_Antenna']['section_key']]
# print(JOB, PNT, DPN, GIS, DPL, PP_START, PP_END, PP_KEYS)

# Liste aller Sektions
section_list = [item for section in raw_sections.values() for item in
                (section['section_key'] if isinstance(section['section_key'], tuple) else [section['section_key']])]
# print(section_list)
# print(f'{len(section_list)} Sektions')

# Liste aller Feldnamen innerhalb einer Section
keys = [[fieldname['field_key'] for fieldname in section['fields']] for section in raw_sections.values()]
# pprint(keys, sort_dicts=False)


print('---------------------------------------------------------------------------------------------------------------')


def find_field_keys(needed_key):
    field_keys = []
    for section_name, section_data in raw_sections.items():
        if isinstance(section_data['section_key'], tuple):
            section_keys = section_data['section_key']
        else:
            section_keys = [section_data['section_key']]

        if needed_key in section_keys:
            for field_info in section_data['fields']:
                field_keys.append(field_info['field_key'])

    return field_keys


def parse_pp_content(content, delimiter, line_number):
    pass


def parse_gis(content):
    return None


def parse_object_content(type, content, line_number):
    result = {}
    for part in content.split(RAW_OBJECT_DELIMITER):
        key, value = part[:2], part[2:]
        result[key] = value

    field_keys = find_field_keys(type)

    unexpected_fields = set(result.keys()) - set(field_keys)
    if unexpected_fields:
        parsed_keys = sorted(result.keys())
        expected_keys = sorted(field_keys)
        raise ValueError(
            f"Parsed fields {parsed_keys} don't match expected keys {expected_keys} in line {line_number}"
        )

    # TODO: Prüfung, ob field == obligatirisch

    return result


def find_first_occurrence_index(input_string):
    occurrences = (input_string.find(delimiter) for delimiter in RAW_SECTION_DELIMITERS)
    min_index = min((index for index in occurrences if index != -1), default=-1)
    return min_index


def custom_partition(line, line_number):
    index = find_first_occurrence_index(line)

    type = line[:index]
    content = line[index + 1:].strip()
    line = line.strip()

    # unbekannte Keys abfangen
    if type not in section_list:
        raise ValueError(
            f'Unbekannter Mess-Typ in Zeile {line_number} gefunden: {type}'
            f' \n(erwartet: {section_list})'
        )

    if index != -1:
        return type, content
    else:
        return line, None


def load_measurements(file_path):
    with file_path.open('r', encoding='utf-8') as messdatei:
        not_yet_needed = []
        points = []
        lines = []
        read_gis = False
        line_number = 1

        for line in messdatei:
            record_type, record_content = custom_partition(line, line_number)

            if record_type == PP_START:
                pass  # TODO: Parse content
            elif record_type == PP_END:
                pass  # TODO: Parse content
            elif record_type in PP_KEYS:
                pass  # TODO: Parse content

            else:
                parsed_content = parse_object_content(record_type, record_content, line_number)
                print(parsed_content)
                if record_type == PNT or record_type == DPN:
                    points.append(parsed_content)
                    read_gis = True
                    points[-1][GIS] = None

                    if record_type == PNT:
                        is_valid = True
                    else:
                        is_valid = False
                    points[-1]['is_valid'] = is_valid

                elif read_gis and record_type == GIS:
                    points[-1][GIS] = parse_gis(record_content)  # TODO: Parse content and expand points[-1]
                    read_gis = False
                elif record_type == DPL:
                    lines.append(record_content)  # TODO: Parse content
                else:
                    not_yet_needed.append(parsed_content)

            line_number += 1

    return points, lines, not_yet_needed


def main():
    points, lines, not_yet_needed = load_measurements(MESSDATEIORDNERPFAD / 'Testdatei_2.raw')
    # pprint(points, sort_dicts=False)
    print(len(points), 'Punkte')
    # pprint(lines, sort_dicts=False)
    # pprint(not_yet_needed, sort_dicts=False)


if __name__ == "__main__":
    main()
Hier ein praxisnaher Auszug aus der Messdatei:

Code: Alles auswählen

JOB,FV1.0,DT2022-08-26,HM13:05:45,NMBestand_2022-8-16.gfd4,CR,NT
UNM,ANGON,DSMETER,SL%,LLDMS
DEC,AN5,CD4,EL4,DS4,AR4,SL4,LL7
CRD,NON,ETE,ELZ,OREN
SWI,PLANDROID,VR4.7.60
LOC,HZCOORDSYS,VTGEOID
LCS,NMETRS89-NHN 32,PJTM,DMETRS89,EPGRS80,LT0.000000000000,LN0.157079632679,FN500000.0000,FE0.0000,SC0.999600000000,P10.000000000000,P20.000000000000
DAT,NMETRS89,SX0.000000,SY0.000000,SZ0.000000,RX0.000000000,RY0.000000000,RZ0.000000000,SC0.000000,DTMOL,PX0.000000,PY0.000000,PZ0.000000
ELL,NMGRS80,SA6378137.000000000,IF298.257222101000
GED,NMGCG2016
RED,SLN,AE0.000,CSY,SF1.000
PNT,NM10100,CD1004,NO5664853.3020,ET686724.1620,EL,LT,LN,HT,TPREFERENCE,NTTrigonometrischer Punkt (TP),DT2022-08-15,HM15:37:42
PNT,NM5402,CD1004,NO5664583.7600,ET686446.5820,EL,LT,LN,HT,TPREFERENCE,NTTrigonometrischer Punkt (TP),DT2022-08-15,HM15:37:42
PNT,NM7110,CD1004,NO5663899.9030,ET686640.8010,EL,LT,LN,HT,TPREFERENCE,NTTrigonometrischer Punkt (TP),DT2022-08-15,HM15:37:42
PNT,NM903160,CD1005,NO5664598.0000,ET686559.0000,EL141.5510,LT,LN,HT,TPREFERENCE,NTHöhenfestpunkt (HFP),DT2022-08-15,HM15:37:42
PNT,NM902011,CD1005,NO5664621.0000,ET686931.0000,EL122.6680,LT,LN,HT,TPREFERENCE,NTHöhenfestpunkt (HFP),DT2022-08-15,HM15:37:42
PNT,NM902021,CD1005,NO5664681.0000,ET686838.0000,EL125.7120,LT,LN,HT,TPREFERENCE,NTHöhenfestpunkt (HFP),DT2022-08-15,HM15:37:42
PNT,NMPP01,CD1002,NO5664501.0669,ET686681.1803,EL142.8648,LT0.891890541320,LN0.203618071573,HT188.3374,TPREFERENCE,NTPolygonpunkt (PP),DT2022-08-16,HM10:14:22
PNT,NMPP02,CD1002,NO5664535.9983,ET686777.6521,EL136.1512,LT0.891895469384,LN0.203642408886,HT181.6222,TPREFERENCE,NTPolygonpunkt (PP),DT2022-08-16,HM10:22:28
PNT,NMPP03,CD1002,NO5664586.1861,ET686902.6953,EL129.8737,LT0.891902626437,LN0.203673998835,HT175.3425,TPREFERENCE,NTPolygonpunkt (PP),DT2022-08-16,HM10:35:16
PNT,NMFF220817001,CD6012,NO5664147.6845,ET686639.0358,EL151.7266,LT0.891835378887,LN0.203604389041,HT197.2040,TPGPS_POINT,NTNutzungsartengrenze,DT2022-08-17,HM09:50:45
PNT,NM2521,CD,NO5664114.6384,ET686625.9103,EL151.7751,LT0.891830272600,LN0.203600822850,HT197.2530,TPGPS_BASE,NT,DT2022-08-17,HM09:50:45
PNT,NMFF220817002,CD6017,NO5664148.8880,ET686638.0076,EL151.5627,LT0.891835573406,LN0.203604143893,HT197.0401,TPGPS_POINT,NTBöschung deutlich oben,DT2022-08-17,HM09:52:15
PNT,NMFF220817003,CD6015,NO5664149.7897,ET686637.5583,EL151.1061,LT0.891835717321,LN0.203604040145,HT196.5834,TPGPS_POINT,NTBöschung deutlich unten,DT2022-08-17,HM09:52:57
PNT,NMFF220817004,CD6015,NO5664150.3797,ET686637.3145,EL151.1203,LT0.891835811203,LN0.203603984783,HT196.5977,TPGPS_POINT,NTBöschung deutlich unten,DT2022-08-17,HM09:53:09
PNT,NMFF220817318,CD8701,NO5664463.2699,ET686975.2877,EL135.3905,LT0.891882943131,LN0.203690963793,HT180.8600,TPGPS_POINT,NTDeckel rund Sonstige Leitungen,DT2022-08-17,HM12:02:02
GIS,FTDeckel,ATDurchmesser=0
PNT,NMFF220817319,CD3022,NO5664463.9651,ET686974.7485,EL135.4384,LT0.891883055193,LN0.203690835813,HT180.9078,TPGPS_POINT,NTFundament,DT2022-08-17,HM12:03:05
PNT,NMFF220819224,CD8701,NO5664526.7203,ET686981.3457,EL124.9378,LT0.891892856108,LN0.203693045853,HT170.4064,TPTPS_POINT,NTDeckel rund Sonstige Leitungen,DT2022-08-19,HM13:07:48
GIS,FTDeckel,ATDurchmesser=0.7
PNT,NMFF220819307,CD5132,NO5664485.0096,ET686992.0669,EL125.3488,LT0.891886255871,LN0.203695338410,HT170.8177,TPTPS_POINT,NTPflasterkante,DT2022-08-19,HM14:05:05
PNT,NMFF220819311,CD8207,NO5664486.6089,ET686992.3080,EL124.9093,LT0.891886505233,LN0.203695412894,HT170.3783,TPTPS_POINT,NTAuslauf Wasserentsorgung,DT2022-08-19,HM14:06:35
GIS,FTEinAusLauf,ATBezeichnung=A,ATDimension=300,ATMaterial=Beton
PNT,NMFF220819312,CD8207,NO5664487.0748,ET686992.1963,EL124.8791,LT0.891886578918,LN0.203695389284,HT170.3481,TPTPS_POINT,NTFUER DIE RICHTUNG,DT2022-08-19,HM14:06:46
GIS,FTEinAusLauf,ATBezeichnung=A,ATDimension=0,ATMaterial=
PNT,NMFF220819322,CD8208,NO5664523.4842,ET686985.8548,EL124.8881,LT0.891892323108,LN0.203694139386,HT170.3567,TPTPS_POINT,NTStraßenablauf eckig,DT2022-08-19,HM14:12:26
GIS,FTAblauf eckig,ATLaenge=0.3,ATBreite=0.5
PNT,NMFF220819323,CD5115,NO5664542.1868,ET686979.1433,EL124.4422,LT0.891895293411,LN0.203692637265,HT169.9106,TPTPS_POINT,NTLeitplanke,DT2022-08-19,HM14:13:17
PNT,NMFF220819461,CD5103,NO5664028.2802,ET686632.8863,EL161.3747,LT0.891816694076,LN0.203601780737,HT206.8535,TPGPS_POINT,NTWeg unbefestigt,DT2022-08-22,HM10:42:11
DPN,NMFF220819462,CD6007,NO5664027.9133,ET686630.8637,EL161.3074,LT0.891816648046,LN0.203601273837,HT206.7863,TP,DELETED,NTStamm Laubbaum,DT2022-08-22,HM10:42:34
PNT,NMFF220822358,CD6001,NO5664275.3901,ET686621.4023,EL154.6354,LT0.891855500234,LN0.203601150546,HT200.1115,TPGPS_POINT,NTGeländepunkt,DT2022-08-22,HM11:47:54
DPN,NMFF220822359,CD6004,NO5664270.5349,ET686621.2629,EL154.9022,LT0.891854739845,LN0.203601072048,HT200.3784,TP,DELETED,NTLaubbaum,DT2022-08-22,HM11:48:28
GIS,FTLB,ATKrone=5,ATStamm=0.29
PNT,NMFF220822360,CD6004,NO5664274.1512,ET686611.5462,EL154.9591,LT0.891855361978,LN0.203598685263,HT200.4353,TPGPS_POINT,NTLaubbaum,DT2022-08-22,HM11:49:25
GIS,FTLB,ATKrone=7,ATStamm=0.22
PNT,NMFF220822374,CD6004,NO5664119.9122,ET686621.5293,EL155.0819,LT0.891831124287,LN0.203599779606,HT200.5599,TPGPS_POINT,NTLaubbaum,DT2022-08-22,HM12:03:12
GIS,FTLB,ATKrone=6,ATStamm=0.32
DPN,NMFF220822375,CD6004,NO5664111.7128,ET686621.9966,EL155.4699,LT0.891829836164,LN0.203599821990,HT200.9479,TP,DELETED,NTLaubbaum,DT2022-08-22,HM12:03:43
GIS,FTLB,ATKrone=5,ATStamm=0.37
PNT,NMFF220822376,CD6004,NO5664103.7885,ET686622.5691,EL155.9097,LT0.891828590566,LN0.203599893071,HT201.3878,TPGPS_POINT,NTLaubbaum,DT2022-08-22,HM12:04:06
GIS,FTLB,ATKrone=3,ATStamm=0.12
DPN,NMFF220822377,CD6004,NO5664095.7019,ET686622.8153,EL156.4403,LT0.891827321388,LN0.203599881427,HT201.9185,TP,DELETED,NTLaubbaum,DT2022-08-22,HM12:04:36
GIS,FTLB,ATKrone=8,ATStamm=0.33
PNT,NMFF220822378,CD6004,NO5664087.7210,ET686623.2236,EL157.1692,LT0.891826067860,LN0.203599911086,HT202.6475,TPGPS_POINT,NTLaubbaum,DT2022-08-22,HM12:08:03
GIS,FTLB,ATKrone=1.5,ATStamm=0.04
PNT,NMFF220825804,CD6001,NO5664183.5107,ET686560.6072,EL158.4758,LT0.891841441000,LN0.203585184331,HT203.9538,TPGPS_POINT,NTGeländepunkt,DT2022-08-25,HM10:13:08
PNT,NMFF220825810,CD1001,NO5663890.8940,ET685962.5488,EL192.9894,LT0.891798955762,LN0.203433642931,HT238.4787,TPTPS_STATION,NTFreier Standpunkt,DT2022-08-25,HM10:41:19
DPN,NMFF220825815,CD6001,NO5663911.6630,ET685759.3045,EL198.0171,LT0.891803361518,LN0.203383225790,HT243.5087,TP,DELETED,NTGeländepunkt,DT2022-08-25,HM10:42:33
PNT,NMFF220825816,CD6004,NO5663911.6051,ET685759.3292,EL198.0376,LT0.891803352294,LN0.203383231411,HT243.5291,TPGPS_POINT,NTLaubbaum,DT2022-08-25,HM10:43:20
GIS,FTLB,ATKrone=4,ATStamm=0.16
PNT,NMFF220825860,CD6006,NO5663990.0560,ET686109.0698,EL178.2724,LT0.891813672534,LN0.203471015391,HT223.7586,TPGPS_POINT,NT2X10 1X20,DT2022-08-25,HM11:53:16
GIS,FTLB,ATKrone=6,ATStamm=0.3
PNT,NMFF220825861,CD6001,NO5664254.3477,ET686636.6855,EL154.4318,LT0.891852114469,LN0.203604766118,HT199.9080,TPGPS_POINT,NTGeländepunkt,DT2022-08-25,HM12:19:54
PNT,NMFF220825862,CD6001,NO5664240.9038,ET686636.5308,EL154.6490,LT0.891850007672,LN0.203604606312,HT200.1253,TPGPS_POINT,NTGeländepunkt,DT2022-08-25,HM12:20:12
PNT,NMFF220825863,CD6001,NO5664227.2425,ET686636.2147,EL154.7165,LT0.891847867703,LN0.203604404369,HT200.1930,TPGPS_POINT,NTGeländepunkt,DT2022-08-25,HM12:20:28
PNT,NMT01,CD1009,NO5664375.3354,ET687058.8866,EL126.3673,LT0.891868681285,LN0.203710984847,HT171.8367,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:21:38
GIS,FTPP,ATVermarkungsart=FM temp
PNT,NMT02,CD1009,NO5664375.3398,ET687057.7455,EL125.8885,LT0.891868688482,LN0.203710700759,HT171.3579,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:22:25
GIS,FTPP,ATVermarkungsart=FM
PNT,NMT03,CD1009,NO5664376.1086,ET687060.0606,EL125.3991,LT0.891868795821,LN0.203711284162,HT170.8685,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:23:59
GIS,FTPP,ATVermarkungsart=FM temp
PNT,NMT04,CD1009,NO5664373.4764,ET687059.0609,EL128.2587,LT0.891868388848,LN0.203711011460,HT173.7282,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:24:31
GIS,FTPP,ATVermarkungsart=FM
PNT,NMT05,CD1009,NO5664378.2806,ET687056.0797,EL128.1598,LT0.891869159008,LN0.203710312584,HT173.6293,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:26:17
GIS,FTPP,ATVermarkungsart=FM
PNT,NMFF220826035,CD1001,NO5664367.7537,ET687053.6449,EL128.9509,LT0.891867522506,LN0.203709611125,HT174.4206,TPTPS_STATION,NTFreier Standpunkt,DT2022-08-26,HM08:46:01
PNT,NMFF220826036,CD1001,NO5664367.7583,ET687053.6485,EL128.9511,LT0.891867523215,LN0.203709612078,HT174.4207,TPTPS_STATION,NTFreier Standpunkt,DT2022-08-26,HM08:49:19
PNT,NMT06,CD1009,NO5664378.2706,ET687055.1702,EL128.1884,LT0.891869162620,LN0.203710086019,HT173.6579,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:53:16
GIS,FTPP,ATVermarkungsart=FM
PNT,NMT07,CD1009,NO5664372.6445,ET687058.7818,EL128.3537,LT0.891868260025,LN0.203710934420,HT173.8232,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:53:49
GIS,FTPP,ATVermarkungsart=FM
PNT,NMT08,CD1009,NO5664369.6200,ET687052.8705,EL128.2976,LT0.891867819506,LN0.203709435196,HT173.7672,TPTPS_POINT,NTGround Control Point (GCP),DT2022-08-26,HM08:54:43
GIS,FTPP,ATVermarkungsart=FM
NTE,DT2022-08-17,HM09:46:27,CD,NTConnected: Rover GPS Model: GeoMax - Zenith60 S/N: Z60ST272100193 RTK Device: External GPRS Server: Sapos TH IPAddress: 195.191.15.131 Port: 2101 Mountpoint: VRS_3_4G_TH UserID: Gast NetworkMode: Nearest Message type: RTCM3MSM 
[PP_RW5_START]
--PP Time: StartWeek=2223,StartSec=294676,StopWeek=2223,StopSec=294679
--Antenna: Desc=GeoMax GNSS Zenith 60,True=1.950m,Meas=1.950m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA1.950,ME2,RA1.950
EP,TM09:50:45,LA51.098403231,LN11.665672182,HT197.2040,RH0.0147,RV0.0216,DH0.7,DV1.2,GM4,CL1
GS,PNFF220817001,N 5664147.6845,E 686639.0358,EL151.7266,--6012
[PP_RW5_END]
GPS,DT2022-08-17,HM09:50:45,BS2521,PTFF220817001,CD6012,LT0.891835378887,LN0.203604389041,HT197.2040,AH1.9500,BH0.0000,US09:51:00,UE09:51:03,NTNutzungsartengrenze
QTY,EP15,GP8,GS3,BD0,GA7,HD0.700,VD1.200,PD1.400,GD2.000,PH0.0147,PV0.0216,FQRTK_FIXED,ES1
COV,XX0.000161715,XY0.000015179,XZ0.000086821,YY0.000054691,YZ0.000037523,ZZ0.000261995
[PP_RW5_START]
--PP Time: StartWeek=2223,StartSec=294766,StopWeek=2223,StopSec=294769
--Antenna: Desc=GeoMax GNSS Zenith 60,True=1.980m,Meas=1.980m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA1.980,ME2,RA1.980
EP,TM09:52:15,LA51.098414376,LN11.665658136,HT197.0401,RH0.0117,RV0.0180,DH0.7,DV1.2,GM4,CL1
GS,PNFF220817002,N 5664148.8880,E 686638.0076,EL151.5627,--6017
[PP_RW5_END]
GPS,DT2022-08-17,HM09:52:15,BS2521,PTFF220817002,CD6017,LT0.891835573406,LN0.203604143893,HT197.0401,AH1.9800,BH0.0000,US09:52:30,UE09:52:33,NTBöschung deutlich oben
QTY,EP15,GP8,GS3,BD0,GA7,HD0.700,VD1.200,PD1.400,GD2.000,PH0.0117,PV0.0180,FQRTK_FIXED,ES1
COV,XX0.000102963,XY0.000009101,XZ0.000057346,YY0.000029966,YZ0.000020873,ZZ0.000157684
[PP_RW5_START]
--PP Time: StartWeek=2223,StartSec=294809,StopWeek=2223,StopSec=294812
--Antenna: Desc=GeoMax GNSS Zenith 60,True=1.980m,Meas=1.980m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA1.980,ME2,RA1.980
EP,TM09:52:57,LA51.098422622,LN11.665652192,HT196.5834,RH0.0126,RV0.0184,DH0.7,DV1.2,GM4,CL1
GS,PNFF220817003,N 5664149.7897,E 686637.5583,EL151.1061,--6015
[PP_RW5_END]
GPS,DT2022-08-17,HM09:52:57,BS2521,PTFF220817003,CD6015,LT0.891835717321,LN0.203604040145,HT196.5834,AH1.9800,BH0.0000,US09:53:13,UE09:53:16,NTBöschung deutlich unten
QTY,EP15,GP8,GS3,BD0,GA7,HD0.700,VD1.200,PD1.400,GD2.000,PH0.0126,PV0.0184,FQRTK_FIXED,ES1
COV,XX0.000118485,XY0.000010602,XZ0.000062410,YY0.000039064,YZ0.000025987,ZZ0.000186398
[PP_RW5_START]
--PP Time: StartWeek=2223,StartSec=294820,StopWeek=2223,StopSec=294823
--Antenna: Desc=GeoMax GNSS Zenith 60,True=1.980m,Meas=1.980m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA1.980,ME2,RA1.980
EP,TM09:53:09,LA51.098428001,LN11.665649020,HT196.5977,RH0.0144,RV0.0209,DH0.7,DV1.2,GM4,CL1
GS,PNFF220817004,N 5664150.3797,E 686637.3145,EL151.1203,--6015
[PP_RW5_END]
GPS,DT2022-08-17,HM09:53:09,BS2521,PTFF220817004,CD6015,LT0.891835811203,LN0.203603984783,HT196.5977,AH1.9800,BH0.0000,US09:53:24,UE09:53:27,NTBöschung deutlich unten
QTY,EP15,GP8,GS3,BD0,GA7,HD0.700,VD1.200,PD1.400,GD2.100,PH0.0144,PV0.0209,FQRTK_FIXED,ES1
COV,XX0.000132435,XY0.000012970,XZ0.000074165,YY0.000043831,YZ0.000030087,ZZ0.000213079
[PP_RW5_START]
--PP Time: StartWeek=2223,StartSec=294857,StopWeek=2223,StopSec=294860
--Antenna: Desc=GeoMax GNSS Zenith 60,True=1.980m,Meas=1.980m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA1.980,ME2,RA1.980
EP,TM09:53:46,LA51.098435281,LN11.665642677,HT197.0293,RH0.0119,RV0.0182,DH0.7,DV1.2,GM4,CL1
GS,PNFF220817005,N 5664151.1731,E 686636.8411,EL151.5519,--6017
[PP_RW5_END]
GPS,DT2022-08-17,HM09:53:46,BS2521,PTFF220817005,CD6017,LT0.891835938277,LN0.203603874067,HT197.0293,AH1.9800,BH0.0000,US09:54:01,UE09:54:04,NTBöschung deutlich oben
QTY,EP15,GP8,GS3,BD0,GA7,HD0.700,VD1.200,PD1.400,GD2.000,PH0.0119,PV0.0182,FQRTK_FIXED,ES1
COV,XX0.000100711,XY0.000008901,XZ0.000054660,YY0.000029954,YZ0.000020600,ZZ0.000152212
TPS,DT2022-08-23,HM09:19:30,IH0.0000,STFF220823001,PTPP05,CD1002,HA6.011402769,VA1.577385826,SD37.8177,H16.011374703,V11.577396158,S137.8183,H22.869838181,V24.705809814,S237.8172,TH1.4500,RT0,PK23.100,PM28,AM3,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM09:21:33,IH0.0000,STFF220823001,PTPP04,CD1002,HA5.916940213,VA1.591160595,SD136.4064,H15.916940025,V11.591178154,S1136.4073,H22.775347748,V24.692042272,S2136.4056,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM09:25:20,IH0.0000,STFF220823001,PTPP06,CD1002,HA2.725757850,VA1.552048478,SD114.9449,H12.725763646,V11.552041846,S1114.9465,H25.867344708,V24.731130198,S2114.9434,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
NTE,DT2022-08-23,HM09:25:57,CD,NTStationierung: FF220823001 Freie Stationierung
STB,DT2022-08-23,HM09:25:57,TPFREE_STATION,STFF220823001,IH0.0000,AZ0.000000000
TPS,DT2022-08-23,HM09:19:30,IH0.0000,STFF220823001,PTPP05,CD1002,HA6.011402769,VA1.577385826,SD37.8177,H16.011374703,V11.577396158,S137.8183,H22.869838181,V24.705809814,S237.8172,TH1.4500,RT0,PK23.100,PM28,AM3,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM09:21:33,IH0.0000,STFF220823001,PTPP04,CD1002,HA5.916940213,VA1.591160595,SD136.4064,H15.916940025,V11.591178154,S1136.4073,H22.775347748,V24.692042272,S2136.4056,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM09:25:20,IH0.0000,STFF220823001,PTPP06,CD1002,HA2.725757850,VA1.552048478,SD114.9449,H12.725763646,V11.552041846,S1114.9465,H25.867344708,V24.731130198,S2114.9434,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
STE,TPFREE_STATION,STFF220823001
TPS,DT2022-08-23,HM09:26:58,IH0.0000,STFF220823001,PTPP06_STK,CD9101,HA2.725729809,VA1.552036250,SD114.9484,TH1.4500,RT0,PK23.100,PM28,AM3,NTAbsteckung von PP06
TPS,DT2022-08-23,HM09:28:43,IH0.0000,STFF220823001,PTFF220822706,CD4014,HA2.731382401,VA1.548976442,SD113.2255,TH2.0000,RT0,PK23.100,PM28,AM3,NTVZ Hinweis
TPS,DT2022-08-23,HM09:29:06,IH0.0000,STFF220823001,PTFF220822707,CD4054,HA2.745532200,VA1.548296814,SD104.1249,TH2.0000,RT0,PK23.100,PM28,AM3,NTLeitpfosten
TPS,DT2022-08-23,HM09:29:29,IH0.0000,STFF220823001,PTFF220822708,CD4054,HA2.784764604,VA1.547398162,SD77.6145,TH2.0000,RT0,PK23.100,PM28,AM3,NTLeitpfosten
TPS,DT2022-08-23,HM09:29:47,IH0.0000,STFF220823001,PTFF220822709,CD4003,HA2.692186979,VA1.549444654,SD77.1319,TH2.0000,RT0,PK23.100,PM28,AM3,NTStationszeichen
NTE,DT2022-08-23,HM12:24:23,CD,NTConnected: TPSModel GeoMax - Zoom 75/95 
TPS,DT2022-08-23,HM12:34:22,IH0.0000,STFF220823596,PTPP08,CD1002,HA2.421788342,VA1.594195510,SD128.9783,H12.421791805,V11.594188489,S1128.9799,H25.563377533,V24.688982776,S2128.9768,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM12:36:43,IH0.0000,STFF220823596,PTPP07,CD1002,HA5.429006379,VA1.596649794,SD34.1987,H15.429026475,V11.596634505,S134.1990,H22.287393629,V24.686520224,S234.1985,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM12:38:21,IH0.0000,STFF220823596,PTPP06,CD1002,HA5.588218789,VA1.597284702,SD130.4359,H15.588229713,V11.597281275,S1130.4371,H22.446615211,V24.685897178,S2130.4347,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
NTE,DT2022-08-23,HM12:38:40,CD,NTStationierung: FF220823596 Freie Stationierung
STB,DT2022-08-23,HM12:38:40,TPFREE_STATION,STFF220823596,IH0.0000,AZ0.000000000
TPS,DT2022-08-23,HM12:34:22,IH0.0000,STFF220823596,PTPP08,CD1002,HA2.421788342,VA1.594195510,SD128.9783,H12.421791805,V11.594188489,S1128.9799,H25.563377533,V24.688982776,S2128.9768,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM12:36:43,IH0.0000,STFF220823596,PTPP07,CD1002,HA5.429006379,VA1.596649794,SD34.1987,H15.429026475,V11.596634505,S134.1990,H22.287393629,V24.686520224,S234.1985,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-23,HM12:38:21,IH0.0000,STFF220823596,PTPP06,CD1002,HA5.588218789,VA1.597284702,SD130.4359,H15.588229713,V11.597281275,S1130.4371,H22.446615211,V24.685897178,S2130.4347,TH1.4500,RT0,PK23.100,PM28,AM1,NTPolygonpunkt (PP)
NTE,DT2022-08-23,HM13:49:28,CD,NTConnected: Rover GPS Model: GeoMax - Zenith60 RTK Device: External GPRS Server: Sapos TH IPAddress: 195.191.15.131 Port: 2101 Mountpoint: VRS_3_4G_TH UserID: Gast NetworkMode: Nearest Message type: RTCM3MSM 
[PP_RW5_START]
--PP Time: StartWeek=2224,StartSec=222760,StopWeek=2224,StopSec=222763
--Antenna: Desc=GeoMax GNSS Zenith 60,True=2.000m,Meas=2.000m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA2.000,ME2,RA2.000
EP,TM13:52:08,LA51.102309946,LN11.670054353,HT172.0118,RH0.0148,RV0.0194,DH1.2,DV1.4,GM4,CL1
GS,PNFF220823748,N 5664593.1585,E 686930.0458,EL126.5434,--3017
[PP_RW5_END]
GPS,DT2022-08-23,HM13:52:08,BS2504,PTFF220823748,CD3017,LT0.891903563927,LN0.203680872347,HT172.0118,AH2.0000,BH0.0000,US13:52:24,UE13:52:27,NTZaun
QTY,EP15,GP5,GS3,BD3,GA5,HD1.200,VD1.400,PD1.800,GD2.600,PH0.0148,PV0.0194,FQRTK_FIXED,ES1
COV,XX0.000101578,XY0.000023546,XZ0.000059230,YY0.000050496,YZ-0.000005729,ZZ0.000237414
[PP_RW5_START]
--PP Time: StartWeek=2224,StartSec=222771,StopWeek=2224,StopSec=222774
--Antenna: Desc=GeoMax GNSS Zenith 60,True=2.000m,Meas=2.000m,ARP_V=0.0mm,ARP_H=0.0mm,NGS_ID="                    ",NGS_L1=71.9mm,NGS_L2=63.2mm
AH,DC2,MA2.000,ME2,RA2.000
EP,TM13:52:19,LA51.102303096,LN11.670017811,HT172.5502,RH0.0166,RV0.0221,DH1.2,DV1.4,GM4,CL1
GS,PNFF220823749,N 5664592.3042,E 686927.5156,EL127.0818,--3017
[PP_RW5_END]
GPS,DT2022-08-23,HM13:52:19,BS2504,PTFF220823749,CD3017,LT0.891903444383,LN0.203680234574,HT172.5502,AH2.0000,BH0.0000,US13:52:35,UE13:52:38,NTZaun
QTY,EP15,GP5,GS2,BD3,GA5,HD1.200,VD1.400,PD1.800,GD2.600,PH0.0166,PV0.0221,FQRTK_FIXED,ES1
COV,XX0.000143216,XY0.000029747,XZ0.000085371,YY0.000071326,YZ-0.000002277,ZZ0.000340170
NTE,DT2022-08-24,HM07:31:28,CD,NTConnected: TPSModel GeoMax - Zoom 75/95 
TPS,DT2022-08-24,HM07:36:41,IH0.0000,STFF220824001,PTPP09,CD1002,HA2.923351678,VA1.548185474,SD16.0754,H12.923327875,V11.548195562,S116.0721,H26.064968135,V24.735009922,S216.0788,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM07:37:45,IH0.0000,STFF220824001,PT5402,CD,HA5.662693152,VA1.476785437,TH1.3000,RT0,PK0.000,PM28,AM2,NTTrigonometrischer Punkt (TP)
TPS,DT2022-08-24,HM07:39:00,IH0.0000,STFF220824001,PTPP11,CD1002,HA6.006280498,VA1.627891933,SD180.5671,H16.006280541,V11.627896707,S1180.5683,H22.864687801,V24.655298148,S2180.5660,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
NTE,DT2022-08-24,HM07:39:14,CD,NTStationierung: FF220824001 Freie Stationierung
STB,DT2022-08-24,HM07:39:14,TPFREE_STATION,STFF220824001,IH0.0000,AZ0.000000000
TPS,DT2022-08-24,HM07:36:41,IH0.0000,STFF220824001,PTPP09,CD1002,HA2.923351678,VA1.548185474,SD16.0754,H12.923327875,V11.548195562,S116.0721,H26.064968135,V24.735009922,S216.0788,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM07:37:45,IH0.0000,STFF220824001,PT5402,CD,HA5.662693152,VA1.476785437,TH1.3000,RT0,PK0.000,PM28,AM2,NTTrigonometrischer Punkt (TP)
TPS,DT2022-08-24,HM07:39:00,IH0.0000,STFF220824001,PTPP11,CD1002,HA6.006280498,VA1.627891933,SD180.5671,H16.006280541,V11.627896707,S1180.5683,H22.864687801,V24.655298148,S2180.5660,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
STE,TPFREE_STATION,STFF220824001
TPS,DT2022-08-24,HM07:45:04,IH0.0000,STFF220824001,PTFF220824002,CD8205,HA3.304292542,VA1.586161880,SD13.3657,TH2.0000,RT0,PK0.400,PM28,AM2,NTSohle Wasserentsorgung
TPS,DT2022-08-24,HM07:50:34,IH0.0000,STFF220824001,PTFF220824006,CD8210,HA3.560865995,VA1.561431261,SD15.6864,OA0.0500,OD0.0000,OV0.0000,TH999.0000,RT1,PK34.400,PM28,AM0,NTRegenfallrohr
NTE,DT2022-08-24,HM07:54:28,CD,NTStation setup from previous job
TPS,DT2022-08-24,HM07:36:41,IH0.0000,STFF220824001,PTPP09,CD1002,HA2.923351678,VA1.548185474,SD16.0754,H12.923327875,V11.548195562,S116.0721,H26.064968135,V24.735009922,S216.0788,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM07:37:45,IH0.0000,STFF220824001,PT5402,CD,HA5.662693152,VA1.476785437,TH1.3000,RT0,PK0.000,PM28,AM2,NTTrigonometrischer Punkt (TP)
TPS,DT2022-08-24,HM07:39:00,IH0.0000,STFF220824001,PTPP11,CD1002,HA6.006280498,VA1.627891933,SD180.5671,H16.006280541,V11.627896707,S1180.5683,H22.864687801,V24.655298148,S2180.5660,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
STB,DT2022-08-24,HM07:39:14,TPFREE_STATION,STFF220824001,IH0.0000,AZ0.000000000
TPS,DT2022-08-24,HM07:36:41,IH0.0000,STFF220824001,PTPP09,CD1002,HA2.923351678,VA1.548185474,SD16.0754,H12.923327875,V11.548195562,S116.0721,H26.064968135,V24.735009922,S216.0788,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM07:37:45,IH0.0000,STFF220824001,PT5402,CD,HA5.662693152,VA1.476785437,TH1.3000,RT0,PK0.000,PM28,AM2,NTTrigonometrischer Punkt (TP)
TPS,DT2022-08-24,HM07:39:00,IH0.0000,STFF220824001,PTPP11,CD1002,HA6.006280498,VA1.627891933,SD180.5671,H16.006280541,V11.627896707,S1180.5683,H22.864687801,V24.655298148,S2180.5660,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
STE,TPFREE_STATION,STFF220824001
TPS,DT2022-08-24,HM07:56:06,IH0.0000,STFF220824001,PTFF220824007,CD8205,HA2.869303501,VA1.647078959,SD10.1508,TH1.8000,RT1,PK34.400,PM28,AM0,NTINDIREKTE MESSUNG
NTE,DT2022-08-24,HM08:14:39,CD,NTConnected: TPSModel GeoMax - Zoom 75/95 
TPS,DT2022-08-24,HM08:17:43,IH0.0000,STFF220824008,PTPP04,CD1002,HA1.581854606,VA1.678497465,SD11.7111,H11.581852688,V11.678508843,S111.7111,H24.723449178,V24.604699221,S211.7111,TH0.0900,RT0,PK-0.600,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM08:20:09,IH0.0000,STFF220824008,PTPP03,CD1002,HA4.248943586,VA1.416811762,SD46.3135,H14.248880140,V11.416823746,S146.3148,H21.107414379,V24.866385530,S246.3122,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
NTE,DT2022-08-24,HM08:23:23,CD,NTStationierung: FF220824008 Freie Stationierung
STB,DT2022-08-24,HM08:23:23,TPFREE_STATION,STFF220824008,IH0.0000,AZ0.000000000
TPS,DT2022-08-24,HM08:17:43,IH0.0000,STFF220824008,PTPP04,CD1002,HA1.581854606,VA1.678497465,SD11.7111,H11.581852688,V11.678508843,S111.7111,H24.723449178,V24.604699221,S211.7111,TH0.0900,RT0,PK-0.600,PM28,AM1,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM08:20:09,IH0.0000,STFF220824008,PTPP03,CD1002,HA4.248943586,VA1.416811762,SD46.3135,H14.248880140,V11.416823746,S146.3148,H21.107414379,V24.866385530,S246.3122,TH1.3000,RT0,PK0.000,PM28,AM2,NTPolygonpunkt (PP)
STE,TPFREE_STATION,STFF220824008
TPS,DT2022-08-24,HM08:24:09,IH0.0000,STFF220824008,PTFF220824009,CD8205,HA2.484109914,VA1.602047059,SD10.9652,TH2.0000,RT0,PK0.400,PM28,AM2,NTSohle Wasserentsorgung
NTE,DT2022-08-24,HM09:12:07,CD,NTConnected: TPSModel GeoMax - Zoom 75/95 
TPS,DT2022-08-24,HM09:14:09,IH0.0000,STFF220824010,PTPP06,CD1002,HA4.540664853,VA1.602477907,SD6.6928,H14.540713043,V11.602490155,S16.6930,H21.399024009,V24.680719649,S26.6926,TH1.3000,RT0,PK0.000,PM28,AM3,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM09:16:13,IH0.0000,STFF220824010,PTPP07,CD1002,HA2.566081358,VA1.545819928,SD93.9908,H12.566062199,V11.545821153,S193.9921,H25.707693171,V24.737366603,S293.9896,TH1.3000,RT0,PK0.000,PM28,AM3,NTPolygonpunkt (PP)
TPS,DT2022-08-24,HM09:22:32,IH0.0000,STFF220824010,PTPP05,CD1002,HA5.860291520,VA1.587825646,SD153.9972,TH1.3000,RT0,PK0.000,PM28,AM3,NTPolygonpunkt (PP)
NTE,DT2022-08-24,HM09:22:47,CD,NTStationierung: FF220824010 Freie Stationierung
STB,DT2022-08-24,HM09:22:47,TPFREE_STATION,STFF220824010,IH0.0000,AZ0.000000000
DPL,CD6017,CLN,CT8,FF220817002,0,FF220817012,0,FF220817016,0,FF220817022,0,FF220817027,0,FF220817030,0,FF220817035,0,FF220817038,0
DPL,CD6015,CLN,CT8,FF220817003,0,FF220817011,0,FF220817017,0,FF220817023,0,FF220817026,0,FF220817031,0,FF220817034,0,FF220817039,0
STK,STPOINT,PNPP06,PX687050.5424,PY5664374.0486,PZ127.6534,SNPP06_STK,SX687050.5510,SY5664374.0477,SZ127.6447,DX-0.0087,DY0.0008,DZ0.0087
STK,STPOINT,PNPP04,PX686955.2759,PY5664606.5162,PZ122.7125,SNPP04_STK,SX686955.2808,SY5664606.5202,SZ122.7074,DX-0.0050,DY-0.0040,DZ0.0051
Für andere Hinweise meinem Code bezüglich bin ich auch dankbar.

VG
Fabian
Antworten