refactoring von collect_and_group_renamer_blocks in drei Einzelroutinen

This commit is contained in:
2026-01-23 20:00:17 +01:00
parent 42393e457e
commit 56e4e8ca85
3 changed files with 141 additions and 18 deletions
+6 -3
View File
@@ -721,7 +721,8 @@ class TestDataGenerator:
block_insert_y = top_right_y - text_d_y_offset
blockref = self.msp.add_blockref(
'io',
insert=(block_insert_x, block_insert_y),
# insert=(block_insert_x, block_insert_y),
insert=(x, y),
dxfattribs={'layer': 'ILS_MOTOR'}
)
# Erzeuge Attribut-Instanzen aus ATTDEFs mit Werten
@@ -752,7 +753,8 @@ class TestDataGenerator:
block_insert_y = left_bottom_y - text_d_y_offset
blockref = self.msp.add_blockref(
'io',
insert=(block_insert_x, block_insert_y),
#insert=(block_insert_x, block_insert_y),
insert=(left_bottom_x, left_bottom_y),
dxfattribs={'layer': 'ILS_MOTOR'}
)
blockref.add_auto_attribs({
@@ -787,7 +789,8 @@ class TestDataGenerator:
block_insert_y = y - text_d_y_offset
blockref = self.msp.add_blockref(
'io',
insert=(block_insert_x, block_insert_y),
#insert=(block_insert_x, block_insert_y),
insert=(x, y),
dxfattribs={'layer': 'ILS_MOTOR'}
)
blockref.add_auto_attribs({
+132 -12
View File
@@ -446,15 +446,13 @@ def validate_direction_with_geometry(direction, is_rectangle):
return True, f"Unbekannte DIRECTION '{direction}' - Verarbeitung wird fortgesetzt"
def process_renamer_blocks(doc, msp, renamer_layers, error_collector):
def collect_and_group_renamer_blocks(doc, msp, renamer_layers, error_collector):
"""
Verarbeitet alle Renamer-Blöcke auf den angegebenen Layern.
Gruppiert Blöcke mit identischer Konfiguration und nummeriert alle Symbole
aus allen Blöcken einer Gruppe gemeinsam.
Erster Pass: Sammelt und gruppiert alle Renamer-Blöcke nach Konfiguration.
Returns:
Dictionary mit {config_key: [(insert, boundary, attributes, is_rectangle), ...]}
"""
all_renamed = []
# Erste Pass: Sammle und gruppiere alle Renamer-Blöcke
renamer_groups = {} # {config_key: [(insert, boundary, attributes, is_rectangle), ...]}
for layer in renamer_layers:
@@ -511,7 +509,18 @@ def process_renamer_blocks(doc, msp, renamer_layers, error_collector):
renamer_groups[config_key] = []
renamer_groups[config_key].append((insert, boundary, attributes, is_rectangle))
# Zweite Pass: Verarbeite jede Gruppe
return renamer_groups
def process_renamer_groups(doc, msp, renamer_layers, renamer_groups, error_collector):
"""
Zweiter Pass: Verarbeitet jede Renamer-Block-Gruppe.
Sammelt Symbole, sortiert sie und nummeriert sie.
Returns:
Liste aller umbenannten Symbole
"""
all_renamed = []
for config_key, group_blocks in renamer_groups.items():
if not group_blocks:
continue
@@ -540,21 +549,42 @@ def process_renamer_blocks(doc, msp, renamer_layers, error_collector):
seen_entities[entity_id] = (symbol, [renamer_pos])
all_symbols.append(symbol)
else:
# Symbol wurde bereits in einem anderen Bereich gefunden - Warnung
# Symbol wurde bereits in einem anderen Bereich gefunden - Fehler
existing_symbol, existing_positions = seen_entities[entity_id]
existing_positions.append(renamer_pos)
symbol_pos = symbol['position']
warning_msg = (
io_value = symbol['attributes'].get('IO', 'N/A')
error_msg = (
f"Symbol an Position ({symbol_pos[0]:.1f}, {symbol_pos[1]:.1f}) "
f"liegt in mehreren Renamer-Bereichen der Gruppe '{block_name}'. "
f"mit IO='{io_value}' liegt in mehreren Renamer-Bereichen der Gruppe '{block_name}'. "
f"Gefunden in Renamer-Blöcken an Positionen: "
f"{', '.join([f'({p[0]:.1f}, {p[1]:.1f})' for p in existing_positions])}"
)
error_collector.add_warnings({"symbol_in_multiple_boundaries": warning_msg})
print(f" FEHLER: {error_msg}")
error_collector.add_errors({"symbol_in_multiple_boundaries": error_msg})
print(f" Gesamt {len(all_symbols)} eindeutige Template-Symbole aus {len(group_blocks)} Blöcken")
if not all_symbols:
# Fehlermeldung: Keine Symbole gefunden
layer_names = []
for i in range(1, 4):
layer_key = f"LAYER_NAME{i}"
if layer_key in reference_attributes and reference_attributes[layer_key]:
layer_names.append(reference_attributes[layer_key])
if "LAYER_NAME" in reference_attributes and reference_attributes["LAYER_NAME"]:
layer_names.append(reference_attributes["LAYER_NAME"])
renamer_positions = [f"({insert.dxf.insert[0]:.1f}, {insert.dxf.insert[1]:.1f})"
for insert, _, _, _ in group_blocks]
error_msg = (
f"Renamer-Block-Gruppe '{block_name}' (DIRECTION: {direction}) "
f"hat keine passenden Symbole gefunden. "
f"Gesucht auf Layer: {', '.join(layer_names) if layer_names else 'N/A'}. "
f"Renamer-Blöcke an Positionen: {', '.join(renamer_positions)}"
)
print(f" FEHLER: {error_msg}")
error_collector.add_errors({"no_symbols_found": error_msg})
continue
# Sortiere alle Symbole zusammen nach Richtung
@@ -568,6 +598,96 @@ def process_renamer_blocks(doc, msp, renamer_layers, error_collector):
return all_renamed
def check_symbols_in_boundaries(doc, msp, renamer_groups, error_collector):
"""
Dritter Pass: Prüft ob alle Symbole mit "@" im IO in einem Renamer-Bereich liegen.
"""
print("\n" + "="*60)
print("Prüfe ob alle Symbole mit '@' im IO in einem Renamer-Bereich liegen")
print("="*60)
# Sammle alle Renamer-Boundaries
all_boundaries = []
for group_blocks in renamer_groups.values():
for insert, boundary, attributes, is_rectangle in group_blocks:
all_boundaries.append((boundary, attributes))
# Finde alle Symbole mit "@" im IO-Attribut
symbols_with_at = []
for entity in msp.query('INSERT'):
symbol_attribs = extract_block_attributes(doc, entity)
if not symbol_attribs:
continue
# Prüfe ob IO-Attribut "@" enthält
io_value = symbol_attribs.get('IO', '')
if '@' in str(io_value):
pos = entity.dxf.insert
point = (pos[0], pos[1])
symbols_with_at.append({
'entity': entity,
'position': point,
'attributes': symbol_attribs,
'layer': entity.dxf.layer,
'io': io_value
})
# Prüfe für jedes Symbol, ob es in mindestens einem Renamer-Bereich liegt
symbols_not_in_any_boundary = []
for symbol in symbols_with_at:
in_any_boundary = False
for boundary, attributes in all_boundaries:
# Prüfe ob Symbol auf dem richtigen Layer ist
search_layers = []
for i in range(1, 4):
layer_key = f"LAYER_NAME{i}"
if layer_key in attributes and attributes[layer_key]:
search_layers.append(attributes[layer_key])
if "LAYER_NAME" in attributes and attributes["LAYER_NAME"]:
search_layers.append(attributes["LAYER_NAME"])
if symbol['layer'] not in search_layers:
continue
# Prüfe ob Symbol innerhalb des Bereichs liegt
if point_in_polygon(symbol['position'], boundary):
in_any_boundary = True
break
if not in_any_boundary:
symbols_not_in_any_boundary.append(symbol)
# Melde Fehler für Symbole, die in keinem Bereich liegen
if symbols_not_in_any_boundary:
for symbol in symbols_not_in_any_boundary:
error_msg = (
f"Symbol an Position ({symbol['position'][0]:.1f}, {symbol['position'][1]:.1f}) "
f"mit IO='{symbol['io']}' auf Layer '{symbol['layer']}' "
f"enthält '@' im IO-Attribut, liegt aber in keinem Renamer-Bereich."
)
print(f" FEHLER: {error_msg}")
error_collector.add_errors({"symbol_with_at_not_in_boundary": error_msg})
else:
print(f" Alle {len(symbols_with_at)} Symbole mit '@' im IO liegen in einem Renamer-Bereich.")
def process_renamer_blocks(doc, msp, renamer_layers, error_collector):
"""
Verarbeitet alle Renamer-Blöcke auf den angegebenen Layern.
Gruppiert Blöcke mit identischer Konfiguration und nummeriert alle Symbole
aus allen Blöcken einer Gruppe gemeinsam.
"""
# Erster Pass: Sammle und gruppiere alle Renamer-Blöcke
renamer_groups = collect_and_group_renamer_blocks(doc, msp, renamer_layers, error_collector)
# Zweiter Pass: Verarbeite jede Gruppe
all_renamed = process_renamer_groups(doc, msp, renamer_layers, renamer_groups, error_collector)
# Dritter Pass: Prüfe ob alle Symbole mit "@" im IO in einem Renamer-Bereich liegen
check_symbols_in_boundaries(doc, msp, renamer_groups, error_collector)
return all_renamed
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Nummeriert Symbole in DXF-Dateien basierend auf Renamer-Blöcken', prog='create_numbers')