Programm versteht auch eine Polylinie als Weg an dem die Nummerierung entlang gehen kann.
This commit is contained in:
+157
-32
@@ -24,9 +24,10 @@ PROJECT_CFG = os.getenv('PROJECT_CFG', os.path.join(PROJECT, 'cfg'))
|
||||
class TestDataGenerator:
|
||||
"""Generiert Test-DXF-Dateien für verschiedene Szenarien"""
|
||||
|
||||
def __init__(self, filename, test_type, config_file=None):
|
||||
def __init__(self, filename, test_type, config_file=None, scene_name=None):
|
||||
self.filename = filename
|
||||
self.test_type = test_type
|
||||
self.scene_name = scene_name
|
||||
self.doc = None
|
||||
self.msp = None
|
||||
self.config = None
|
||||
@@ -330,13 +331,14 @@ class TestDataGenerator:
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
def create_renamer_attrib_block(self, block_name, attrib_tags):
|
||||
def create_renamer_attrib_block(self, block_name, attrib_tags, frame_type='MA'):
|
||||
"""
|
||||
Erstellt einen Block mit ATTDEF-Attributen für Renamer-Frames
|
||||
|
||||
Args:
|
||||
block_name: Name des Attribut-Blocks (z.B. 'RENAMER_ATTRIB_MA')
|
||||
attrib_tags: Liste der Attribut-Tags (z.B. ['NAME', 'KENNZEICHNUNG', ...])
|
||||
frame_type: 'MA' oder 'MULTI' für Frame-Typ
|
||||
|
||||
Returns:
|
||||
Block-Definition
|
||||
@@ -346,9 +348,20 @@ class TestDataGenerator:
|
||||
|
||||
attrib_block = self.doc.blocks.new(block_name)
|
||||
|
||||
# Definiere Standard-Positionen und Werte für Attribute
|
||||
# Font-Größe auf ein Viertel reduziert (85.0 → 21.25)
|
||||
attrib_definitions = {
|
||||
# Hole Positionen aus Config, falls vorhanden
|
||||
if self.config and 'general' in self.config:
|
||||
general = self.config['general']
|
||||
if frame_type == 'MA' and 'ma_frame' in general:
|
||||
config_positions = general['ma_frame'].get('attdef_positions', {})
|
||||
elif frame_type == 'MULTI' and 'multi_frame' in general:
|
||||
config_positions = general['multi_frame'].get('attdef_positions', {})
|
||||
else:
|
||||
config_positions = {}
|
||||
else:
|
||||
config_positions = {}
|
||||
|
||||
# Definiere Standard-Positionen und Werte für Attribute (Fallback)
|
||||
default_definitions = {
|
||||
'NAME': {'insert': (10, 50), 'default': 'MA@@', 'height': 21.25},
|
||||
'NAME1': {'insert': (10, 80), 'default': 'BG1@@@', 'height': 21.25},
|
||||
'NAME2': {'insert': (10, 60), 'default': 'MB1@@@', 'height': 21.25},
|
||||
@@ -364,14 +377,25 @@ class TestDataGenerator:
|
||||
|
||||
# Füge nur die angeforderten Attribute hinzu
|
||||
for tag in attrib_tags:
|
||||
if tag in attrib_definitions:
|
||||
attdef = attrib_definitions[tag]
|
||||
if tag in default_definitions:
|
||||
default_def = default_definitions[tag]
|
||||
|
||||
# Verwende Config-Werte, falls vorhanden, sonst Defaults
|
||||
if tag in config_positions and not tag.startswith('_'):
|
||||
config_pos = config_positions[tag]
|
||||
x = config_pos.get('x', default_def['insert'][0])
|
||||
y = config_pos.get('y', default_def['insert'][1])
|
||||
height = config_pos.get('height', default_def['height'])
|
||||
else:
|
||||
x, y = default_def['insert']
|
||||
height = default_def['height']
|
||||
|
||||
attrib_block.add_attdef(
|
||||
tag=tag,
|
||||
insert=attdef['insert'],
|
||||
text=attdef['default'],
|
||||
insert=(x, y),
|
||||
text=default_def['default'],
|
||||
dxfattribs={
|
||||
'height': attdef['height'],
|
||||
'height': height,
|
||||
'layer': 'ILS_RENAMER',
|
||||
'color': 1,
|
||||
'style': 'textstyle3'
|
||||
@@ -412,8 +436,8 @@ class TestDataGenerator:
|
||||
'LAYER_NAME1', 'LAYER_NAME2', 'LAYER_NAME3', 'DIRECTION', 'ID']
|
||||
attrib_block_name = 'RENAMER_ATTRIB_MULTI'
|
||||
|
||||
# Erstelle Attribut-Block (wiederverwendbar)
|
||||
self.create_renamer_attrib_block(attrib_block_name, attrib_tags)
|
||||
# Erstelle Attribut-Block (wiederverwendbar) mit Config-Unterstützung
|
||||
self.create_renamer_attrib_block(attrib_block_name, attrib_tags, frame_type=frame_type)
|
||||
|
||||
# Erstelle äußeren Renamer-Block mit eindeutigem Namen (inkl. Position und Größe)
|
||||
# Jeder Rahmen bekommt einen eindeutigen Namen basierend auf Position
|
||||
@@ -462,13 +486,79 @@ class TestDataGenerator:
|
||||
dxfattribs={'layer': 'ILS_RENAMER'}
|
||||
)
|
||||
|
||||
def generate_nummerierung(self):
|
||||
def create_polyline_renamer_frame(self, path_points, name, kennzeichnung, layer_name, direction):
|
||||
"""
|
||||
Erstellt einen Renamer-Rahmen mit Polyline-Pfad
|
||||
|
||||
Struktur:
|
||||
- Block (RENAMER_POLYLINE_xxx):
|
||||
1. LWPOLYLINE (Pfad durch die Punkte)
|
||||
2. Block-Referenz mit Attributen (RENAMER_ATTRIB_MA)
|
||||
|
||||
Args:
|
||||
path_points: Liste von Dictionaries mit 'x' und 'y' Koordinaten
|
||||
name: NAME-Attribut
|
||||
kennzeichnung: KENNZEICHNUNG-Attribut
|
||||
layer_name: LAYER_NAME-Attribut
|
||||
direction: DIRECTION-Attribut (z.B. 'POLYLINE_PATH')
|
||||
"""
|
||||
# Erstelle Attribut-Block (wiederverwendbar)
|
||||
attrib_tags = ['NAME', 'KENNZEICHNUNG', 'LAYER_NAME', 'DIRECTION']
|
||||
attrib_block_name = 'RENAMER_ATTRIB_MA'
|
||||
self.create_renamer_attrib_block(attrib_block_name, attrib_tags, frame_type='MA')
|
||||
|
||||
# Erstelle eindeutigen Block-Namen basierend auf erstem Punkt
|
||||
first_point = path_points[0] if path_points else {'x': 0, 'y': 0}
|
||||
block_name = f"RENAMER_POLYLINE_{name.replace('@', '').replace('-', '_')}_{int(first_point['x'])}_{int(first_point['y'])}"
|
||||
|
||||
if block_name not in self.doc.blocks:
|
||||
renamer_block = self.doc.blocks.new(block_name)
|
||||
|
||||
# 1. Füge LWPOLYLINE hinzu (Pfad)
|
||||
# Konvertiere Punkte von Dict zu Tupeln
|
||||
points = [(p['x'], p['y']) for p in path_points]
|
||||
|
||||
renamer_block.add_lwpolyline(points, dxfattribs={
|
||||
'layer': 'ILS_RENAMER',
|
||||
'color': 1
|
||||
})
|
||||
|
||||
# 2. Füge Block-Referenz mit Attributen hinzu
|
||||
# Position neben dem ersten Punkt des Pfades (mit kleinem Offset)
|
||||
first_x = points[0][0]
|
||||
first_y = points[0][1]
|
||||
attrib_insert_pos = (first_x + 10, first_y + 30) # Offset vom ersten Punkt
|
||||
attrib_blockref = renamer_block.add_blockref(
|
||||
attrib_block_name,
|
||||
insert=attrib_insert_pos,
|
||||
dxfattribs={'layer': 'ILS_RENAMER'}
|
||||
)
|
||||
|
||||
# Setze Attribut-Werte
|
||||
attrib_blockref.add_auto_attribs({
|
||||
'NAME': name,
|
||||
'KENNZEICHNUNG': kennzeichnung,
|
||||
'LAYER_NAME': layer_name,
|
||||
'DIRECTION': direction
|
||||
})
|
||||
|
||||
# Füge Block-Referenz im Modelspace ein (am Ursprung, da Pfad absolute Koordinaten hat)
|
||||
blockref = self.msp.add_blockref(
|
||||
block_name,
|
||||
insert=(0, 0),
|
||||
dxfattribs={'layer': 'ILS_RENAMER'}
|
||||
)
|
||||
|
||||
def generate_nummerierung(self, scene_name='Nummerierung1'):
|
||||
"""
|
||||
Generiert Testdaten für Nummerierung-Szenario
|
||||
|
||||
Verwendet entweder die JSON-Config oder Hard-coded Defaults
|
||||
|
||||
Args:
|
||||
scene_name: Name der Testszene (z.B. 'Nummerierung1', 'Nummerierung2')
|
||||
"""
|
||||
print("Generiere Nummerierung-Testdaten...")
|
||||
print(f"Generiere Nummerierung-Testdaten ({scene_name})...")
|
||||
|
||||
# Erstelle io-Block direkt (ohne Referenzdatei)
|
||||
io_block = self.create_io_block()
|
||||
@@ -478,9 +568,9 @@ class TestDataGenerator:
|
||||
return
|
||||
|
||||
# Wenn Config geladen ist, verwende sie, ansonsten Hard-coded Defaults
|
||||
if self.config and 'test_scenes' in self.config and 'Nummerierung1' in self.config['test_scenes']:
|
||||
print("Verwende JSON-Config für Nummerierung1...")
|
||||
self._generate_nummerierung_from_config()
|
||||
if self.config and 'test_scenes' in self.config and scene_name in self.config['test_scenes']:
|
||||
print(f"Verwende JSON-Config für {scene_name}...")
|
||||
self._generate_nummerierung_from_config(scene_name)
|
||||
else:
|
||||
print("Verwende Hard-coded Defaults für Nummerierung...")
|
||||
self._generate_nummerierung_hardcoded()
|
||||
@@ -548,9 +638,14 @@ class TestDataGenerator:
|
||||
|
||||
blockref.add_auto_attribs(attrib_values)
|
||||
|
||||
def _generate_nummerierung_from_config(self):
|
||||
"""Generiert Nummerierung-Testdaten aus JSON-Config"""
|
||||
scene = self.config['test_scenes']['Nummerierung1']
|
||||
def _generate_nummerierung_from_config(self, scene_name='Nummerierung1'):
|
||||
"""
|
||||
Generiert Nummerierung-Testdaten aus JSON-Config
|
||||
|
||||
Args:
|
||||
scene_name: Name der Testszene in der Config
|
||||
"""
|
||||
scene = self.config['test_scenes'][scene_name]
|
||||
ma_defaults = self.config.get('ma_defaults', {})
|
||||
general = self.config.get('general', {})
|
||||
|
||||
@@ -570,16 +665,29 @@ class TestDataGenerator:
|
||||
|
||||
# Generiere Renamer-Rahmen aus Config
|
||||
for frame_config in scene.get('renaming_frames', []):
|
||||
self.create_renamer_frame(
|
||||
insert_point=(frame_config['x'], frame_config['y']),
|
||||
width=frame_config['width'],
|
||||
height=frame_config['height'],
|
||||
name=frame_config['name'],
|
||||
kennzeichnung=frame_config['kennzeichnung'],
|
||||
layer_name=frame_config['layer_name'],
|
||||
direction=frame_config['direction'],
|
||||
use_polyline=frame_config.get('use_polyline', False)
|
||||
)
|
||||
frame_type = frame_config.get('type', 'rectangle')
|
||||
|
||||
if frame_type == 'polyline_path':
|
||||
# Polyline-Pfad Frame
|
||||
self.create_polyline_renamer_frame(
|
||||
path_points=frame_config['path_points'],
|
||||
name=frame_config['name'],
|
||||
kennzeichnung=frame_config['kennzeichnung'],
|
||||
layer_name=frame_config['layer_name'],
|
||||
direction=frame_config['direction']
|
||||
)
|
||||
else:
|
||||
# Standard Rectangle Frame
|
||||
self.create_renamer_frame(
|
||||
insert_point=(frame_config['x'], frame_config['y']),
|
||||
width=frame_config['width'],
|
||||
height=frame_config['height'],
|
||||
name=frame_config['name'],
|
||||
kennzeichnung=frame_config['kennzeichnung'],
|
||||
layer_name=frame_config['layer_name'],
|
||||
direction=frame_config['direction'],
|
||||
use_polyline=frame_config.get('use_polyline', False)
|
||||
)
|
||||
|
||||
def _generate_nummerierung_hardcoded(self):
|
||||
"""Generiert Nummerierung-Testdaten mit Hard-coded Werten (Fallback)"""
|
||||
@@ -727,7 +835,17 @@ class TestDataGenerator:
|
||||
self.create_document()
|
||||
|
||||
if self.test_type == 'nummerierung':
|
||||
self.generate_nummerierung()
|
||||
# Bestimme Scene-Name: entweder explizit angegeben oder automatisch aus Filename
|
||||
scene_name = self.scene_name
|
||||
if not scene_name:
|
||||
# Versuche Scene-Name aus Filename zu extrahieren (z.B. "Nummerierung2.dxf" -> "Nummerierung2")
|
||||
import re
|
||||
match = re.match(r'(Nummerierung\d+)', self.filename, re.IGNORECASE)
|
||||
if match:
|
||||
scene_name = match.group(1)
|
||||
else:
|
||||
scene_name = 'Nummerierung1' # Default
|
||||
self.generate_nummerierung(scene_name)
|
||||
elif self.test_type == 'sps':
|
||||
print("SPS-Testdaten noch nicht implementiert")
|
||||
elif self.test_type == 'todraw':
|
||||
@@ -780,6 +898,13 @@ def main():
|
||||
help='JSON-Konfigurationsdatei (Standard: create_tests.json)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--scene',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Name der Testszene (z.B. Nummerierung1, Nummerierung2). Falls nicht angegeben, wird aus Filename extrahiert.'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Stelle sicher, dass Dateiname .dxf Endung hat
|
||||
@@ -787,7 +912,7 @@ def main():
|
||||
args.filename += '.dxf'
|
||||
|
||||
# Generiere Testdaten
|
||||
generator = TestDataGenerator(args.filename, args.type, config_file=args.config)
|
||||
generator = TestDataGenerator(args.filename, args.type, config_file=args.config, scene_name=args.scene)
|
||||
|
||||
if generator.generate():
|
||||
generator.save(args.output_dir)
|
||||
|
||||
Reference in New Issue
Block a user