CSV-Export: Bounding-Box (Position/Boundingbox) und Planquadrat-Spalte ergaenzt
Nur EXPORTCSV betroffen, EXPORTSIVAS bleibt unveraendert: - Position/Boundingbox: Bounding-Box je Block per vla-getboundingbox (Lisp/export.lsp, csv:get-bbox), Mittelpunkt und Ausdehnung x/y/z. - Planquadrat: aus x/y-Koordinate berechnet nach cfg/export.cfg [Planquadrate] (Schrittweite, numerisch/alphabetisch je Achse, alphabetische Zaehlung mit Excel-Spalten-Umlauf Z->AA), siehe lib/export_planquadrat.py. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+70
-2
@@ -11,7 +11,16 @@ Aufruf:
|
||||
python export_csv.py <export_raw.json> <data_dir> <output.csv>
|
||||
|
||||
CSV-Format:
|
||||
Elementnummer;TeileArt;TeileId;NachbarIds;Bezeichnung;Planquadrat;rotation;Merkmale
|
||||
Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;Merkmale
|
||||
|
||||
Position und Boundingbox stammen aus der von export.lsp (csv:get-bbox, per
|
||||
vla-getboundingbox) ermittelten Bounding-Box je Block:
|
||||
Position = Mittenkoordinate x, y, z
|
||||
Boundingbox = Ausdehnung (Laenge, Breite, Hoehe) in x, y, z
|
||||
Planquadrat wird aus der x/y-Koordinate des Blocks berechnet, siehe
|
||||
export_planquadrat.py ([Planquadrate] in cfg/export.cfg).
|
||||
Position, Boundingbox und Planquadrat sind nur fuer EXPORTCSV vorhanden
|
||||
(nicht EXPORTSIVAS) - siehe csv:run-export.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -19,8 +28,10 @@ import sys
|
||||
import os
|
||||
|
||||
from export_blockpatterns import load_patterns, matches_any
|
||||
from export_planquadrat import load_planquadrat_config, compute_planquadrat
|
||||
|
||||
BLOCKPATTERNS = load_patterns()
|
||||
PLANQUADRAT_CFG = load_planquadrat_config()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -219,6 +230,41 @@ def build_kreisel_merkmale(block):
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bounding-Box-Spalten (Position/Boundingbox)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def bbox_columns(block):
|
||||
"""Liest die von export.lsp (csv:get-bbox) ermittelte Bounding-Box.
|
||||
|
||||
Rueckgabe: dict mit "position" (Mittenkoordinate x,y,z) und "boundingbox"
|
||||
(Ausdehnung x,y,z) als Strings, oder leere Strings falls kein bbox-Feld
|
||||
vorhanden ist (z.B. EXPORTSIVAS oder die synthetische Omniflo-Sum-Zeile).
|
||||
"""
|
||||
bbox = block.get("bbox")
|
||||
if not bbox:
|
||||
return {"position": "", "boundingbox": ""}
|
||||
return {
|
||||
"position": f'{bbox.get("cx", 0):.2f}, {bbox.get("cy", 0):.2f}, {bbox.get("cz", 0):.2f}',
|
||||
"boundingbox": f'{bbox.get("dx", 0):.2f}, {bbox.get("dy", 0):.2f}, {bbox.get("dz", 0):.2f}',
|
||||
}
|
||||
|
||||
|
||||
def planquadrat_column(block):
|
||||
"""Berechnet das Planquadrat aus x/y des Blocks (siehe export_planquadrat.py).
|
||||
|
||||
Leerer String, wenn keine Planquadrat-Konfiguration geladen werden konnte
|
||||
(fehlende/unvollstaendige [Planquadrate]-Sektion in cfg/export.cfg).
|
||||
"""
|
||||
if PLANQUADRAT_CFG is None:
|
||||
return ""
|
||||
x = block.get("x")
|
||||
y = block.get("y")
|
||||
if x is None or y is None:
|
||||
return ""
|
||||
return compute_planquadrat(float(x), float(y), PLANQUADRAT_CFG)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bekannte Blocknamen
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -268,7 +314,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "Omniflo Kurve",
|
||||
"teileid": shape_id,
|
||||
"bezeichnung": f"OFBogen :{bogen_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_bogen_merkmale(block, eintrag),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
|
||||
elif typ == "weiche":
|
||||
@@ -279,7 +327,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "Omniflo Weiche",
|
||||
"teileid": shape_id,
|
||||
"bezeichnung": f"OFWeiche :{weiche_count[wt]}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_weiche_merkmale(block, eintrag),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
subtyp = weichensubtyp(block, eintrag)
|
||||
if subtyp == "weichenkoerper":
|
||||
@@ -304,7 +354,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "Omniflo Gerade",
|
||||
"teileid": block.get("attribs", {}).get("ID", "0000"),
|
||||
"bezeichnung": f"OFGerade :{gerade_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_gerade_merkmale(block),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
len_ap110_mm += get_laenge_mm(block)
|
||||
continue
|
||||
@@ -318,7 +370,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "ILS 2.0 Strecke",
|
||||
"teileid": block.get("attribs", {}).get("ID", "0000"),
|
||||
"bezeichnung": f"VarioFoerderer :{vf_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_variofoerderer_merkmale(block),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -331,7 +385,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "ILS 2.0 Gefaellestrecke",
|
||||
"teileid": block.get("attribs", {}).get("ID", "0000"),
|
||||
"bezeichnung": f"Gefaellestrecke :{gf_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_variofoerderer_merkmale(block),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -345,7 +401,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "ILS 2.0 Eckrad",
|
||||
"teileid": block.get("attribs", {}).get("ID", "0000"),
|
||||
"bezeichnung": f"Eckrad :{eckrad_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_kreisel_merkmale(block),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -358,7 +416,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "ILS 2.0 Kreisel",
|
||||
"teileid": block.get("attribs", {}).get("ID", "0000"),
|
||||
"bezeichnung": f"Kreisel :{kreisel_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": build_kreisel_merkmale(block),
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -371,7 +431,9 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "ILS 2.0 Strecke - Modul",
|
||||
"teileid": block.get("attribs", {}).get("ID", "0000"),
|
||||
"bezeichnung": f"Streckenmodul :{strecke_modul_count}",
|
||||
"planquadrat": planquadrat_column(block),
|
||||
"merkmale": {"Blockname": bname},
|
||||
**bbox_columns(block),
|
||||
})
|
||||
continue
|
||||
|
||||
@@ -382,9 +444,12 @@ def process_blocks(blocks, lookup):
|
||||
"teileart": "Omniflo Sum",
|
||||
"teileid": "autogenerated_of_json",
|
||||
"bezeichnung": "Omniflo sum",
|
||||
"planquadrat": "",
|
||||
"merkmale": build_omni_sum_merkmale(
|
||||
bogen_count, cnt_wk, cnt_einzel, cnt_delta, cnt_doppel, cnt_stern,
|
||||
len_ap110_mm, len_ap60_mm),
|
||||
"position": "",
|
||||
"boundingbox": "",
|
||||
})
|
||||
|
||||
return items
|
||||
@@ -401,7 +466,10 @@ def format_csv_line(item):
|
||||
f';"{item["teileart"]}"'
|
||||
f';"{item["teileid"]}"'
|
||||
f';"{item["bezeichnung"]}"'
|
||||
f';"{item["planquadrat"]}"'
|
||||
f';1'
|
||||
f';"{item["position"]}"'
|
||||
f';"{item["boundingbox"]}"'
|
||||
f';{merkmale_json}'
|
||||
)
|
||||
|
||||
@@ -433,7 +501,7 @@ def main():
|
||||
|
||||
items = process_blocks(blocks, lookup)
|
||||
|
||||
header = "Elementnummer;TeileArt;TeileId;Bezeichnung;Anzahl;Merkmale"
|
||||
header = "Elementnummer;TeileArt;TeileId;Bezeichnung;Planquadrat;Anzahl;Position;Boundingbox;Merkmale"
|
||||
with open(output_csv, "w", encoding="utf-8") as f:
|
||||
f.write(header + "\n")
|
||||
for item in items:
|
||||
|
||||
Reference in New Issue
Block a user