K2 der Bögen wird erzeugt
This commit is contained in:
+20
-173
@@ -30,8 +30,11 @@ import os
|
||||
import sys
|
||||
|
||||
import ezdxf
|
||||
from ezdxf import bbox as ezdxf_bbox
|
||||
from ezdxf.addons.importer import Importer
|
||||
|
||||
from utils import (
|
||||
ROW_GROUPS, TEXT_HEIGHT, TEXT_MARGIN, CROSS_SIZE, ROW_LABEL_WIDTH,
|
||||
build_row_layout, import_element_as_block, draw_cross,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -333,195 +336,43 @@ def process_dxf(data_dir, label, json_file, filter_func, insertion_func,
|
||||
# show-omniflo
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def find_min_y_point(doc):
|
||||
"""Findet den Punkt mit dem geringsten Y-Wert im Modelspace."""
|
||||
min_y = float('inf')
|
||||
min_point = None
|
||||
for e in doc.modelspace():
|
||||
points = []
|
||||
if e.dxftype() == 'LINE':
|
||||
points = [(e.dxf.start[0], e.dxf.start[1]),
|
||||
(e.dxf.end[0], e.dxf.end[1])]
|
||||
elif e.dxftype() == 'ARC':
|
||||
cx, cy = e.dxf.center[0], e.dxf.center[1]
|
||||
r = e.dxf.radius
|
||||
a_s = math.radians(e.dxf.start_angle)
|
||||
a_e = math.radians(e.dxf.end_angle)
|
||||
points = [
|
||||
(cx + r * math.cos(a_s), cy + r * math.sin(a_s)),
|
||||
(cx + r * math.cos(a_e), cy + r * math.sin(a_e)),
|
||||
]
|
||||
for p in points:
|
||||
if p[1] < min_y:
|
||||
min_y = p[1]
|
||||
min_point = p
|
||||
return min_point
|
||||
|
||||
|
||||
ROW_GROUPS = [
|
||||
("Boegen 22.5", "boegen",
|
||||
lambda b: b["KurvenWinkel"] == 22.5),
|
||||
("Boegen 45", "boegen",
|
||||
lambda b: b["KurvenWinkel"] == 45),
|
||||
("Boegen 67.5", "boegen",
|
||||
lambda b: b["KurvenWinkel"] == 67.5),
|
||||
("Boegen 90", "boegen",
|
||||
lambda b: b["KurvenWinkel"] == 90),
|
||||
("Boegen 180", "boegen",
|
||||
lambda b: b["KurvenWinkel"] == 180),
|
||||
("Weichenkoerper Einzel", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Einzelweiche" and w["KurvenWinkel"] == 22.5),
|
||||
("Weichenkoerper Doppel", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Doppelweiche" and w["KurvenWinkel"] == 22.5),
|
||||
("Weichenkoerper Dreiwege", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Dreiwegeweiche" and w["KurvenWinkel"] == 22.5),
|
||||
("Einzelweiche 45", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Einzelweiche" and w["KurvenWinkel"] == 45),
|
||||
("Einzelweiche 90", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Einzelweiche" and w["KurvenWinkel"] == 90),
|
||||
("Einzelweiche Parallel", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Einzelweiche" and w["KurvenWinkel"] == 0),
|
||||
("Doppelweiche 45", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Doppelweiche" and w["KurvenWinkel"] == 45),
|
||||
("Doppelweiche 90", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Doppelweiche" and w["KurvenWinkel"] == 90),
|
||||
("Doppelweiche Parallel", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Doppelweiche" and w["KurvenWinkel"] == 0),
|
||||
("Dreiwegeweiche 45", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Dreiwegeweiche" and w["KurvenWinkel"] == 45),
|
||||
("Dreiwegeweiche 90", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Dreiwegeweiche" and w["KurvenWinkel"] == 90),
|
||||
("Dreiwegeweiche Parallel", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Dreiwegeweiche" and w["KurvenWinkel"] == 0),
|
||||
("Dreifachweiche", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Dreifachweiche"),
|
||||
("Deltaweiche", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Deltaweiche"),
|
||||
("Sternweiche", "weichen",
|
||||
lambda w: w["WeichenTyp"] == "Sternweiche"),
|
||||
]
|
||||
|
||||
PADDING_X = 200
|
||||
PADDING_Y = 400
|
||||
TEXT_HEIGHT = 30
|
||||
CROSS_SIZE = 40
|
||||
TEXT_MARGIN = 20
|
||||
ROW_LABEL_WIDTH = 600
|
||||
|
||||
|
||||
def show_omniflo(data_dir, results_dir):
|
||||
"""Erzeugt eine Uebersichts-DXF mit allen Omniflo-Elementen in Reihen."""
|
||||
boegen_path = os.path.join(data_dir, "json", "omniflo_boegen.json")
|
||||
weichen_path = os.path.join(data_dir, "json", "omniflo_weichen.json")
|
||||
|
||||
with open(boegen_path, "r", encoding="utf-8") as f:
|
||||
boegen_data = json.load(f)
|
||||
with open(weichen_path, "r", encoding="utf-8") as f:
|
||||
weichen_data = json.load(f)
|
||||
|
||||
sources = {"boegen": boegen_data, "weichen": weichen_data}
|
||||
omniflo_dir = os.path.join(data_dir, "omniflo")
|
||||
sources, rows = build_row_layout(data_dir, results_dir)
|
||||
|
||||
target = ezdxf.new(dxfversion='R2010')
|
||||
target_msp = target.modelspace()
|
||||
target.layers.add('ANNOTATION', color=7)
|
||||
target.layers.add('INSPOINT', color=1)
|
||||
target.layers.add('INSLINE', color=5)
|
||||
target.layers.add('ROW_LABEL', color=3)
|
||||
|
||||
cursor_y = 0.0
|
||||
block_counter = 0
|
||||
|
||||
for label, source_key, filter_func in ROW_GROUPS:
|
||||
items = [item for item in sources[source_key] if filter_func(item)]
|
||||
if not items:
|
||||
continue
|
||||
|
||||
row_elements = []
|
||||
for item in items:
|
||||
sivasnr = str(item["Sivasnr"])
|
||||
dxf_path_result = os.path.join(results_dir, f"{sivasnr}.dxf")
|
||||
dxf_path_orig = os.path.join(omniflo_dir, f"{sivasnr}.dxf")
|
||||
dxf_path = dxf_path_result if os.path.exists(dxf_path_result) else dxf_path_orig
|
||||
|
||||
if not os.path.exists(dxf_path):
|
||||
print(f" WARNUNG: {sivasnr}.dxf nicht gefunden, ueberspringe.")
|
||||
continue
|
||||
|
||||
source_doc = ezdxf.readfile(dxf_path)
|
||||
bb = ezdxf_bbox.extents(source_doc.modelspace())
|
||||
if not bb.has_data:
|
||||
continue
|
||||
|
||||
min_y_pt = find_min_y_point(source_doc)
|
||||
insbase = source_doc.header.get("$INSBASE", (0, 0, 0))
|
||||
|
||||
row_elements.append({
|
||||
'sivasnr': sivasnr,
|
||||
'source': source_doc,
|
||||
'extmin': bb.extmin,
|
||||
'extmax': bb.extmax,
|
||||
'width': bb.extmax[0] - bb.extmin[0],
|
||||
'height': bb.extmax[1] - bb.extmin[1],
|
||||
'insbase': insbase,
|
||||
'min_y_point': min_y_pt,
|
||||
})
|
||||
|
||||
if not row_elements:
|
||||
continue
|
||||
|
||||
max_height = max(e['height'] for e in row_elements)
|
||||
|
||||
label_y = cursor_y + max_height / 2
|
||||
for row in rows:
|
||||
label_y = row['cursor_y'] + row['max_height'] / 2
|
||||
target_msp.add_mtext(
|
||||
label,
|
||||
row['label'],
|
||||
dxfattribs={
|
||||
'layer': 'ROW_LABEL',
|
||||
'char_height': TEXT_HEIGHT * 1.2,
|
||||
}
|
||||
).set_location(insert=(-ROW_LABEL_WIDTH, label_y))
|
||||
|
||||
cursor_x = 0.0
|
||||
for elem in row_elements:
|
||||
for elem in row['elements']:
|
||||
block_name = f"BLK_{block_counter}"
|
||||
block_counter += 1
|
||||
|
||||
importer = Importer(elem['source'], target)
|
||||
importer.import_tables()
|
||||
blk = target.blocks.new(name=block_name)
|
||||
for entity in elem['source'].modelspace():
|
||||
importer.import_entity(entity, blk)
|
||||
importer.finalize()
|
||||
import_element_as_block(elem['source'], target, block_name)
|
||||
target_msp.add_blockref(block_name,
|
||||
insert=(elem['offset_x'], elem['offset_y']))
|
||||
|
||||
offset_x = cursor_x - elem['extmin'][0]
|
||||
offset_y = cursor_y - elem['extmin'][1]
|
||||
target_msp.add_blockref(block_name, insert=(offset_x, offset_y))
|
||||
insbase = elem['source'].header.get("$INSBASE", (0, 0, 0))
|
||||
ipx = insbase[0] + elem['offset_x']
|
||||
ipy = insbase[1] + elem['offset_y']
|
||||
draw_cross(target_msp, ipx, ipy, CROSS_SIZE, 1, 'INSPOINT')
|
||||
|
||||
ipx = elem['insbase'][0] + offset_x
|
||||
ipy = elem['insbase'][1] + offset_y
|
||||
|
||||
target_msp.add_line(
|
||||
(ipx - CROSS_SIZE, ipy),
|
||||
(ipx + CROSS_SIZE, ipy),
|
||||
dxfattribs={'layer': 'INSPOINT', 'color': 1}
|
||||
)
|
||||
target_msp.add_line(
|
||||
(ipx, ipy - CROSS_SIZE),
|
||||
(ipx, ipy + CROSS_SIZE),
|
||||
dxfattribs={'layer': 'INSPOINT', 'color': 1}
|
||||
)
|
||||
|
||||
if elem['min_y_point']:
|
||||
low_x = elem['min_y_point'][0] + offset_x
|
||||
low_y = elem['min_y_point'][1] + offset_y
|
||||
target_msp.add_line(
|
||||
(ipx, ipy),
|
||||
(low_x, low_y),
|
||||
dxfattribs={'layer': 'INSLINE', 'color': 5}
|
||||
)
|
||||
|
||||
text_x = cursor_x
|
||||
text_y = cursor_y + elem['height'] + TEXT_MARGIN
|
||||
text_x = elem['offset_x'] + elem['extmin'][0]
|
||||
text_y = row['cursor_y'] + elem['height'] + TEXT_MARGIN
|
||||
target_msp.add_mtext(
|
||||
elem['sivasnr'],
|
||||
dxfattribs={
|
||||
@@ -530,14 +381,10 @@ def show_omniflo(data_dir, results_dir):
|
||||
}
|
||||
).set_location(insert=(text_x, text_y))
|
||||
|
||||
cursor_x += elem['width'] + PADDING_X
|
||||
|
||||
cursor_y -= max_height + TEXT_HEIGHT + TEXT_MARGIN * 2 + PADDING_Y
|
||||
|
||||
out_path = os.path.join(results_dir, "omniflo_uebersicht.dxf")
|
||||
target.saveas(out_path)
|
||||
print(f"Uebersicht gespeichert: {out_path}")
|
||||
print(f" {block_counter} Elemente in {sum(1 for l, s, f in ROW_GROUPS if any(f(i) for i in sources[s]))} Reihen")
|
||||
print(f" {block_counter} Elemente in {len(rows)} Reihen")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user