This commit is contained in:
2026-06-30 10:01:04 +02:00
4 changed files with 211 additions and 225 deletions
+4
View File
@@ -9,7 +9,11 @@
;; --- String fuer JSON escapen (Anfuehrungszeichen/Backslash) --- ;; --- String fuer JSON escapen (Anfuehrungszeichen/Backslash) ---
;; Konvertiert nicht-String-Werte (z.B. T, nil, Zahlen) defensiv in String.
(defun csv:json-escape (s) (defun csv:json-escape (s)
(if (not (= (type s) 'STR))
(setq s (if s (vl-princ-to-string s) ""))
)
(setq s (vl-string-subst "\\\\" "\\" s)) (setq s (vl-string-subst "\\\\" "\\" s))
(vl-string-subst "\\\"" "\"" s) (vl-string-subst "\\\"" "\"" s)
) )
+10
View File
@@ -64,3 +64,13 @@ SIVASNR_TEF = SivasnrTEF
HOEHE = "" HOEHE = ""
DREHUNG = "" DREHUNG = ""
[gerade]
ARTINR = Sivasnr
TEILEART = "Omniflo Gerade"
ID = ""
LAENGE = Laenge
LAYER = "A-2"
HOEHE = ""
DREHUNG = ""
+172 -205
View File
@@ -1,10 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
export_csv.py - Erzeugt CSV aus den von LISP gesammelten Block-Daten. export_sivas.py - Erzeugt Sivas-Export-CSV mit gruppierten Zeilen und Summierungszeilen.
Neues CSV-Format:
Nr;TeileArt;SivasNummer;Dispgruppe;Anzahl;Laenge[mm];Hoehe[m];details
- Omniflo Bogen/Weiche: gruppiert nach SivasNummer, Anzahl summiert
- Omniflo Gerade: gruppiert nach ARTINR-Attribut, Laenge[mm] summiert
- ILS 2.0 Kreisel: je Kreisel eine Zeile, details = JSON mit Parametern
- ILS 2.0 Automation: Summierungszeile (nur wenn ILS-Elemente vorhanden)
Aufruf: Aufruf:
python export_csv.py <export_raw.json> <data_dir> <output.csv> python export_sivas.py <export_raw.json> <data_dir> <output.csv>
Argumente: Argumente:
export_raw.json - JSON-Datei mit allen INSERT-Entities aus der Zeichnung export_raw.json - JSON-Datei mit allen INSERT-Entities aus der Zeichnung
@@ -26,94 +34,49 @@ def build_lookup(boegen, weichen):
"""Erzeugt ein Dict: SivasNr (als String) -> (typ, eintrag)""" """Erzeugt ein Dict: SivasNr (als String) -> (typ, eintrag)"""
lookup = {} lookup = {}
for b in boegen: for b in boegen:
key = str(b["Sivasnr"]) lookup[str(b["Sivasnr"])] = ("bogen", b)
lookup[key] = ("bogen", b)
for w in weichen: for w in weichen:
key = str(w["Sivasnr"]) lookup[str(w["Sivasnr"])] = ("weiche", w)
lookup[key] = ("weiche", w)
return lookup return lookup
def classify_weiche(eintrag): def classify_weiche(eintrag):
"""Bestimmt den Weichen-Subtyp fuer die Omniflo Sum Zaehlung.""" """Bestimmt den Weichen-Subtyp fuer die ILS-Automation-Zaehlung."""
wt = eintrag.get("WeichenTyp", "") wt = eintrag.get("WeichenTyp", "")
profil = eintrag.get("ProfilTyp", "") profil = eintrag.get("ProfilTyp", "")
if "WEICHENKOERPER" in profil.upper(): if "WEICHENKOERPER" in profil.upper():
return "weichenkoerper" return "weichenkoerper"
if wt == "Einzelweiche": if wt == "Einzelweiche":
return "einzelweiche" return "einzelweiche"
if wt == "Doppelweiche": if wt in ("Doppelweiche", "Dreiwegeweiche"):
return "doppelweiche" return "doppelweiche"
if wt == "Dreiwegeweiche": if wt in ("Deltaweiche", "Dreifachweiche") or "DELTA" in profil.upper():
return "dreiwegeweiche"
if wt == "Deltaweiche" or "DELTA" in profil.upper():
return "deltaweiche"
if wt == "Dreifachweiche":
return "deltaweiche" return "deltaweiche"
if wt == "Sternweiche" or "STAR" in profil.upper(): if wt == "Sternweiche" or "STAR" in profil.upper():
return "sternweiche" return "sternweiche"
return "einzelweiche" return "einzelweiche"
def get_hoehe(block): def get_hoehe_mm(block):
"""Liest HOEHE aus Block-Attributen. Fallback: Z-Koordinate.""" """Liest HOEHE aus Block-Attributen. Fallback: Z-Koordinate."""
attribs = block.get("attribs", {}) attribs = block.get("attribs", {})
return attribs.get("HOEHE") or str(int(block.get("z", 0) or 0)) or "2000" v = attribs.get("HOEHE") or str(int(block.get("z", 0) or 0)) or "2000"
return v
def get_drehung(block): def format_hoehe_m(hoehe_mm_str):
"""Liest DREHUNG aus Block-Attributen. Fallback: CAD-Rotation.""" """Konvertiert mm-String nach m mit deutschem Dezimaltrennzeichen."""
attribs = block.get("attribs", {})
drehung_raw = attribs.get("DREHUNG")
if drehung_raw is not None:
try: try:
return float(drehung_raw) m = float(hoehe_mm_str) / 1000.0
if m == int(m):
return str(int(m))
return f"{m:.1f}".replace(".", ",")
except (ValueError, TypeError): except (ValueError, TypeError):
pass return ""
return block.get("rotation", 0.0)
def build_bogen_merkmale(block, eintrag): def build_kreisel_details(block):
"""Merkmale-JSON fuer einen Omniflo Bogen.""" """Merkmale-Dict fuer einen ILS Kreisel."""
return {
"Kurvenwinkel": eintrag.get("KurvenWinkel", 0),
"Radius": eintrag.get("Radius", 0),
"Höhe": get_hoehe(block),
"Drehung": get_drehung(block),
"SivasNummer": str(eintrag.get("Sivasnr", ""))
}
def build_weiche_merkmale(block, eintrag):
"""Merkmale-JSON fuer eine Omniflo Weiche."""
wt = eintrag.get("WeichenTyp", "Einzelweiche")
return {
"Weichentyp": wt,
"Richtung": str(eintrag.get("KurvenRichtung", "")),
"Weichenwinkel": eintrag.get("KurvenWinkel", 0),
"Höhe": get_hoehe(block),
"Drehung": get_drehung(block),
"Antrieb Kurve": eintrag.get("SivasnrTEF") is not None,
"SivasNummer": str(eintrag.get("Sivasnr", ""))
}
def build_gerade_merkmale(block):
"""Merkmale-JSON fuer eine Omniflo Gerade (AP110)."""
return {
"Anzahl der Separatoren": "0",
"Länge in Meter": "2",
"Winkel": "0",
"Anzahl der Scanner": 0,
"Höhe oben": "2000",
"Höhe unten": "2000",
"Drehung": block.get("rotation", 0.0),
"SivasNummer": ""
}
def build_kreisel_merkmale(block):
"""Merkmale-JSON fuer einen ILS Kreisel (liest Attribute aus Block)."""
attribs = block.get("attribs", {}) attribs = block.get("attribs", {})
abstand_mm = attribs.get("ABSTAND", "2300") abstand_mm = attribs.get("ABSTAND", "2300")
try: try:
@@ -131,15 +94,14 @@ def build_kreisel_merkmale(block):
"Kreiselart": attribs.get("KREISELART", "STANDARD"), "Kreiselart": attribs.get("KREISELART", "STANDARD"),
"Anzahl der Scanner": attribs.get("N_SCANNER", "0"), "Anzahl der Scanner": attribs.get("N_SCANNER", "0"),
"Anzahl der Rampen": attribs.get("N_RAMPEN", "0"), "Anzahl der Rampen": attribs.get("N_RAMPEN", "0"),
"Höhe in m": hoehe_m, "Hoehe in m": hoehe_m,
"Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"), "Drehrichtung": attribs.get("DREHRICHTUNG", "UZS"),
"Drehung": block.get("rotation", 0.0), "Drehung": block.get("rotation", 0.0),
"Name": attribs.get("NAME", ""),
} }
# --- Bekannte Blocknamen fuer nicht-Omniflo Elemente --- # --- Bekannte Bloecke ignorieren ---
## Kreisel-Bloecke werden ueber Praefix "KR_" erkannt (siehe process_blocks) SKIP_BLOCKS = {"K1", "K2", "K3", "K4", "KS_EIN", "KS_AUS"}
VARIO_BLOCKS = { VARIO_BLOCKS = {
"AUS_Element_links", "EIN_Element_links", "AUS_Element_links", "EIN_Element_links",
@@ -147,19 +109,23 @@ VARIO_BLOCKS = {
"Vario_Spannstation_SP_500mm", "Vario_Motorstation_SP_500mm", "Vario_Spannstation_SP_500mm", "Vario_Motorstation_SP_500mm",
} }
# Koordinatensystem-Bloecke (ignorieren)
SKIP_BLOCKS = {"K1", "K2", "K3", "K4", "KS_EIN", "KS_AUS"}
def process_blocks(blocks, lookup): def process_blocks(blocks, lookup):
""" """
Verarbeitet alle Bloecke und erzeugt: Verarbeitet alle Bloecke.
- items: Liste der CSV-Einzelzeilen
- counters: Zaehler fuer Summierungszeilen Rueckgabe:
items - Liste der CSV-Zeilen als Dicts
counters - Zaehler fuer ILS-Automation-Summierungszeile
""" """
items = [] # Gruppen: sivasnr_str -> {anzahl, hoehe_mm}
bogen_groups = {} # sivasnr -> dict
weiche_groups = {} # sivasnr -> dict
# Gerade: artinr_str -> {anzahl, laenge_mm_total, hoehe_mm}
gerade_groups = {}
kreisel_list = [] # Liste von blocks
counters = { counters = {
# Omniflo Sum
"anzahl_boegen": 0, "anzahl_boegen": 0,
"anzahl_weichenkoerper": 0, "anzahl_weichenkoerper": 0,
"anzahl_einzelweichen": 0, "anzahl_einzelweichen": 0,
@@ -168,7 +134,6 @@ def process_blocks(blocks, lookup):
"anzahl_sternweichen": 0, "anzahl_sternweichen": 0,
"gesamtlaenge_ap110": 0.0, "gesamtlaenge_ap110": 0.0,
"gesamtlaenge_ap60": 0.0, "gesamtlaenge_ap60": 0.0,
# ILS Automation
"anzahl_kreisel": 0, "anzahl_kreisel": 0,
"anzahl_kreisel_pinband": 0, "anzahl_kreisel_pinband": 0,
"sep_kreisel_pin": 0, "sep_kreisel_pin": 0,
@@ -191,54 +156,32 @@ def process_blocks(blocks, lookup):
"anzahl_abwurfstationen": 0, "anzahl_abwurfstationen": 0,
} }
elem_nr = 0
bogen_count = 0
weiche_count = {}
gerade_count = 0
kreisel_count = 0
for block in blocks: for block in blocks:
bname = block.get("block_name", "") bname = block.get("block_name", "")
# Koordinatensystem-Bloecke ueberspringen
if bname in SKIP_BLOCKS: if bname in SKIP_BLOCKS:
continue continue
# Omniflo Bogen oder Weiche? # --- Omniflo Bogen oder Weiche (erkannt via Katalog) ---
if bname in lookup: if bname in lookup:
typ, eintrag = lookup[bname] typ, eintrag = lookup[bname]
elem_nr += 1 sivasnr = str(eintrag.get("Sivasnr", bname))
shape_id = block.get("attribs", {}).get("ID", "0000") hoehe = get_hoehe_mm(block)
if typ == "bogen": if typ == "bogen":
bogen_count += 1 if sivasnr not in bogen_groups:
items.append({ bogen_groups[sivasnr] = {"anzahl": 0, "hoehe_mm": hoehe}
"nr": elem_nr, bogen_groups[sivasnr]["anzahl"] += 1
"teileart": "Omniflo Kurve",
"teileid": shape_id,
"bezeichnung": f"OFBogen :{bogen_count}",
"anzahl": 1,
"merkmale": build_bogen_merkmale(block, eintrag)
})
counters["anzahl_boegen"] += 1 counters["anzahl_boegen"] += 1
elif typ == "weiche": elif typ == "weiche":
if sivasnr not in weiche_groups:
weiche_groups[sivasnr] = {"anzahl": 0, "hoehe_mm": hoehe}
weiche_groups[sivasnr]["anzahl"] += 1
subtyp = classify_weiche(eintrag) subtyp = classify_weiche(eintrag)
wt = eintrag.get("WeichenTyp", "Einzelweiche")
weiche_count[wt] = weiche_count.get(wt, 0) + 1
items.append({
"nr": elem_nr,
"teileart": "Omniflo Weiche",
"teileid": shape_id,
"bezeichnung": f"OFWeiche :{weiche_count[wt]}",
"anzahl": 1,
"merkmale": build_weiche_merkmale(block, eintrag)
})
if subtyp == "einzelweiche": if subtyp == "einzelweiche":
counters["anzahl_einzelweichen"] += 1 counters["anzahl_einzelweichen"] += 1
elif subtyp == "doppelweiche" or subtyp == "dreiwegeweiche": elif subtyp in ("doppelweiche", "dreiwegeweiche"):
counters["anzahl_doppel_dreiwegeweichen"] += 1 counters["anzahl_doppel_dreiwegeweichen"] += 1
elif subtyp == "deltaweiche": elif subtyp == "deltaweiche":
counters["anzahl_deltaweichen"] += 1 counters["anzahl_deltaweichen"] += 1
@@ -246,36 +189,33 @@ def process_blocks(blocks, lookup):
counters["anzahl_sternweichen"] += 1 counters["anzahl_sternweichen"] += 1
elif subtyp == "weichenkoerper": elif subtyp == "weichenkoerper":
counters["anzahl_weichenkoerper"] += 1 counters["anzahl_weichenkoerper"] += 1
continue continue
# Omniflo Gerade (AP110) # --- Omniflo Gerade (AP110) ---
if "AP110" in bname.upper() or "AP_110" in bname.upper(): if "AP110" in bname.upper() or "AP_110" in bname.upper():
elem_nr += 1 attribs = block.get("attribs", {})
gerade_count += 1 artinr = attribs.get("ARTINR", "")
items.append({ key = artinr if artinr else "AP110"
"nr": elem_nr, hoehe = get_hoehe_mm(block)
"teileart": "Omniflo Gerade", laenge = 2000.0
"teileid": block.get("attribs", {}).get("ID", "0000"), laenge_attr = attribs.get("LAENGE") or attribs.get("A")
"bezeichnung": f"OFGerade :{gerade_count}", if laenge_attr:
"anzahl": 1, try:
"merkmale": build_gerade_merkmale(block) laenge = float(laenge_attr)
}) except (ValueError, TypeError):
counters["gesamtlaenge_ap110"] += 2000.0 pass
if key not in gerade_groups:
gerade_groups[key] = {
"anzahl": 0, "laenge_mm": 0.0, "hoehe_mm": hoehe, "artinr": artinr
}
gerade_groups[key]["anzahl"] += 1
gerade_groups[key]["laenge_mm"] += laenge
counters["gesamtlaenge_ap110"] += laenge
continue continue
# ILS Kreisel (Compound-Bloecke mit Praefix KR_) # --- ILS Kreisel ---
if bname.startswith("KR_"): if bname.startswith("KR_") or bname.startswith("KREISEL_"):
elem_nr += 1 kreisel_list.append(block)
kreisel_count += 1
items.append({
"nr": elem_nr,
"teileart": "ILS 2.0 Kreisel",
"teileid": block.get("attribs", {}).get("ID", "0000"),
"bezeichnung": f"Kreisel :{kreisel_count}",
"anzahl": 1,
"merkmale": build_kreisel_merkmale(block)
})
attribs = block.get("attribs", {}) attribs = block.get("attribs", {})
counters["anzahl_kreisel"] += 1 counters["anzahl_kreisel"] += 1
n_sep = int(attribs.get("N_SEPARATOREN", "2") or "2") n_sep = int(attribs.get("N_SEPARATOREN", "2") or "2")
@@ -293,98 +233,136 @@ def process_blocks(blocks, lookup):
counters["anzahl_streckengruppen"] = 1 counters["anzahl_streckengruppen"] = 1
continue continue
# VarioFoerderer-Bloecke # --- VarioFoerderer ---
is_vario = False
for vb in VARIO_BLOCKS: for vb in VARIO_BLOCKS:
if vb in bname: if vb in bname:
is_vario = True
break
if is_vario:
counters["anzahl_variofoerderer"] += 1 counters["anzahl_variofoerderer"] += 1
continue break
return items, counters # --- Zeilen aufbauen ---
items = []
nr = 1
for sivasnr, g in bogen_groups.items():
items.append({
"nr": nr,
"teileart": "Omniflo Bogen",
"sivasnr": sivasnr,
"sivasnr_quoted": False,
"dispgruppe": 10,
"anzahl": g["anzahl"],
"laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {},
})
nr += 1
def build_ils_automation_row(elem_nr, counters): for sivasnr, g in weiche_groups.items():
"""Erzeugt die ILS 2.0 Automation Summierungszeile.""" items.append({
merkmale = { "nr": nr,
"teileart": "Omniflo Weiche",
"sivasnr": sivasnr,
"sivasnr_quoted": False,
"dispgruppe": 10,
"anzahl": g["anzahl"],
"laenge_mm": "",
"hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {},
})
nr += 1
for key, g in gerade_groups.items():
items.append({
"nr": nr,
"teileart": "Omniflo Gerade",
"sivasnr": g["artinr"],
"sivasnr_quoted": True,
"dispgruppe": 10,
"anzahl": g["anzahl"],
"laenge_mm": int(g["laenge_mm"]),
"hoehe_m": format_hoehe_m(g["hoehe_mm"]),
"details": {},
})
nr += 1
for block in kreisel_list:
items.append({
"nr": nr,
"teileart": "ILS 2.0 Kreisel",
"sivasnr": "6200",
"sivasnr_quoted": True,
"dispgruppe": 20,
"anzahl": 1,
"laenge_mm": "",
"hoehe_m": "",
"details": build_kreisel_details(block),
})
nr += 1
# ILS Automation Summierungszeile (nur wenn ILS-Elemente vorhanden)
if counters["anzahl_kreisel"] > 0 or counters["anzahl_variofoerderer"] > 0:
automation_details = {
"Anzahl Kreisel": counters["anzahl_kreisel"], "Anzahl Kreisel": counters["anzahl_kreisel"],
"Anzahl Kreisel mit Pinband": counters["anzahl_kreisel_pinband"], "Anzahl Kreisel mit Pinband": counters["anzahl_kreisel_pinband"],
"Anzahl aller Separatoren in Kreisel mit PIN": counters["sep_kreisel_pin"], "Anzahl aller Separatoren in Kreisel mit PIN": counters["sep_kreisel_pin"],
"Anzahl aller Separatoren in Kreisel ohne PIN": counters["sep_kreisel_ohne_pin"], "Anzahl aller Separatoren in Kreisel ohne PIN": counters["sep_kreisel_ohne_pin"],
"Anzahl Verbindungskreisel": counters["anzahl_verbindungskreisel"], "Anzahl Verbindungskreisel": counters["anzahl_verbindungskreisel"],
"Längen aller Kreisel": counters["laengen_kreisel"], "Laengen aller Kreisel": counters["laengen_kreisel"],
"Anzahl der Weichen": counters["anzahl_weichen_ils"], "Anzahl der Weichen": counters["anzahl_weichen_ils"],
"Anzahl der Eckräder": counters["anzahl_eckraeder"], "Anzahl der Eckraeder": counters["anzahl_eckraeder"],
"Anzahl der einzelnen Gefällestrecken": counters["anzahl_gefaellestrecken"], "Anzahl der einzelnen Gefaellestrecken": counters["anzahl_gefaellestrecken"],
"Anzahl der einzelnen Varioförderer": counters["anzahl_variofoerderer"], "Anzahl der einzelnen Variofoerderer": counters["anzahl_variofoerderer"],
"Anzahl der Streckengruppen": counters["anzahl_streckengruppen"], "Anzahl der Streckengruppen": counters["anzahl_streckengruppen"],
"Längen aller Gefällestrecken": counters["laengen_gefaellestrecken"], "Laengen aller Gefaellestrecken": counters["laengen_gefaellestrecken"],
"Anzahl der Motoren Varioförderer": counters["anzahl_motoren_vario"], "Anzahl der Motoren Variofoerderer": counters["anzahl_motoren_vario"],
"Längen aller Varioförderer": counters["laengen_variofoerderer"], "Laengen aller Variofoerderer": counters["laengen_variofoerderer"],
"Anzahl ETFs": counters["anzahl_etf"], "Anzahl ETFs": counters["anzahl_etf"],
"Längen aller ETFs": counters["laengen_etf"], "Laengen aller ETFs": counters["laengen_etf"],
"Anzahl aller Separatoren": counters["anzahl_separatoren"], "Anzahl aller Separatoren": counters["anzahl_separatoren"],
"Anzahl aller Scanner": counters["anzahl_scanner"], "Anzahl aller Scanner": counters["anzahl_scanner"],
"Anzahl aller BTBeladung": counters["anzahl_btbeladung"], "Anzahl aller BTBeladung": counters["anzahl_btbeladung"],
"Anzahl aller Abwurfstationen": counters["anzahl_abwurfstationen"], "Anzahl aller Abwurfstationen": counters["anzahl_abwurfstationen"],
} }
return { items.append({
"nr": elem_nr, "nr": nr,
"teileart": "ILS 2.0 Automation", "teileart": "ILS 2.0 Automation",
"teileid": "autogenerated_ils_automation_json", "sivasnr": "6270",
"bezeichnung": "Automation ILS structgen", "sivasnr_quoted": True,
"dispgruppe": 20,
"anzahl": 1, "anzahl": 1,
"merkmale": merkmale, "laenge_mm": "",
} "hoehe_m": "",
"details": automation_details,
})
return items, counters
def build_omniflo_sum_row(elem_nr, counters):
"""Erzeugt die Omniflo Sum Summierungszeile."""
merkmale = {
"Anzahl Bögen": counters["anzahl_boegen"],
"Anzahl Weichengrundkörper": counters["anzahl_weichenkoerper"],
"Anzahl Einwegweichen": counters["anzahl_einzelweichen"],
"Anzahl Deltaweichen": counters["anzahl_deltaweichen"],
"Anzahl Doppelweichen und Dreiwegeweichen": counters["anzahl_doppel_dreiwegeweichen"],
"Anzahl Sternweichen": counters["anzahl_sternweichen"],
"Gesamtlänge AP110": counters["gesamtlaenge_ap110"],
"Gesamtlänge AP60": counters["gesamtlaenge_ap60"],
}
return {
"nr": elem_nr,
"teileart": "Omniflo Sum",
"teileid": "autogenerated_of_json",
"bezeichnung": "Omniflo sum",
"anzahl": 1,
"merkmale": merkmale,
}
def format_csv_line(item): def format_csv_line(item):
"""Formatiert eine CSV-Zeile im geforderten Format.""" """Formatiert eine CSV-Zeile im neuen Sivas-Format."""
merkmale_json = json.dumps(item["merkmale"], ensure_ascii=False) details_json = json.dumps(item["details"], ensure_ascii=False)
return '{nr};"{teileart}";"{teileid}";"{bezeichnung}";{anzahl};{merkmale}'.format( sivasnr = f'"{item["sivasnr"]}"' if item["sivasnr_quoted"] else item["sivasnr"]
nr=item["nr"], return (
teileart=item["teileart"], f'{item["nr"]}'
teileid=item["teileid"], f';"{item["teileart"]}"'
bezeichnung=item["bezeichnung"], f';{sivasnr}'
anzahl=item["anzahl"], f';{item["dispgruppe"]}'
merkmale=merkmale_json, f';{item["anzahl"]}'
f';{item["laenge_mm"]}'
f';{item["hoehe_m"]}'
f';{details_json}'
) )
def main(): def main():
if len(sys.argv) < 4: if len(sys.argv) < 4:
print("Aufruf: python export_csv.py <export_raw.json> <data_dir> <output.csv>") print("Aufruf: python export_sivas.py <export_raw.json> <data_dir> <output.csv>")
sys.exit(1) sys.exit(1)
raw_json_path = sys.argv[1] raw_json_path = sys.argv[1]
data_dir = sys.argv[2] data_dir = sys.argv[2]
output_csv = sys.argv[3] output_csv = sys.argv[3]
# Daten laden
blocks = load_json(raw_json_path) blocks = load_json(raw_json_path)
boegen_path = os.path.join(data_dir, "json", "omniflo_boegen.json") boegen_path = os.path.join(data_dir, "json", "omniflo_boegen.json")
weichen_path = os.path.join(data_dir, "json", "omniflo_weichen.json") weichen_path = os.path.join(data_dir, "json", "omniflo_weichen.json")
@@ -394,29 +372,18 @@ def main():
lookup = build_lookup(boegen, weichen) lookup = build_lookup(boegen, weichen)
print(f"[export_csv] {len(blocks)} Bloecke geladen, " print(f"[export_sivas] {len(blocks)} Bloecke geladen, "
f"{len(boegen)} Boegen, {len(weichen)} Weichen im Katalog.") f"{len(boegen)} Boegen, {len(weichen)} Weichen im Katalog.")
# Bloecke verarbeiten items, _ = process_blocks(blocks, lookup)
items, counters = process_blocks(blocks, lookup)
# Summierungszeilen anhaengen header = "Nr;TeileArt;SivasNummer;Dispgruppe;Anzahl;Laenge[mm];Hoehe[m];details"
next_nr = (items[-1]["nr"] + 1) if items else 1
ils_row = build_ils_automation_row(next_nr, counters)
items.append(ils_row)
of_row = build_omniflo_sum_row(next_nr + 1, counters)
items.append(of_row)
# CSV schreiben
header = "Elementnummer;TeileArt;TeileId;Bezeichnung;Anzahl;Merkmale"
with open(output_csv, "w", encoding="utf-8") as f: with open(output_csv, "w", encoding="utf-8") as f:
f.write(header + "\n") f.write(header + "\n")
for item in items: for item in items:
f.write(format_csv_line(item) + "\n") f.write(format_csv_line(item) + "\n")
print(f"[export_csv] CSV geschrieben: {output_csv} ({len(items)} Zeilen)") print(f"[export_sivas] CSV geschrieben: {output_csv} ({len(items)} Zeilen)")
if __name__ == "__main__": if __name__ == "__main__":
+6 -1
View File
@@ -307,8 +307,13 @@ def process_all(data_dir, cfg_path, results_dir, single_nr=None, dry_run=False):
# JSON-Daten laden # JSON-Daten laden
boegen = load_json(os.path.join(data_dir, "json", "omniflo_boegen.json")) boegen = load_json(os.path.join(data_dir, "json", "omniflo_boegen.json"))
weichen = load_json(os.path.join(data_dir, "json", "omniflo_weichen.json")) weichen = load_json(os.path.join(data_dir, "json", "omniflo_weichen.json"))
geraden_path = os.path.join(data_dir, "json", "omniflo_geraden.json")
geraden = load_json(geraden_path) if os.path.exists(geraden_path) else []
lookup = build_lookup(boegen, weichen) lookup = build_lookup(boegen, weichen)
print(f"[set_attributs] {len(boegen)} Boegen, {len(weichen)} Weichen geladen.") for g in geraden:
lookup[str(g["Sivasnr"])] = ("gerade", g)
print(f"[set_attributs] {len(boegen)} Boegen, {len(weichen)} Weichen, "
f"{len(geraden)} Geraden geladen.")
# Ausgabeverzeichnis # Ausgabeverzeichnis
out_dir = os.path.join(results_dir, "omniflo") out_dir = os.path.join(results_dir, "omniflo")