Files
SSG-Ruledesigner-Konfigurator/CAD/Code/lib/diff_dimensions.py
T

291 lines
11 KiB
Python

#!/usr/bin/env python3
"""
JSON Integration Script
Erzeugt neue JSON Datei mit den SIVAS-Nummern, dessen Maße von 3D (.par) und 2D (.dwg) nicht übereinstimmen.
"""
import json
import argparse
import sys
import os
from pathlib import Path
import math
def load_json_file(file_path):
"""
Lädt eine JSON-Datei und gibt den Inhalt zurück.
Args:
file_path (str): Pfad zur JSON-Datei
Returns:
list: JSON-Daten als Liste
Raises:
FileNotFoundError: Wenn die Datei nicht gefunden wird
json.JSONDecodeError: Wenn die JSON-Datei ungültig ist
"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"Fehler: Datei '{file_path}' nicht gefunden.")
sys.exit(1)
except json.JSONDecodeError as e:
print(f"Fehler beim Parsen der JSON-Datei '{file_path}': {e}")
sys.exit(1)
def save_json_file(data, file_path):
"""
Speichert Daten in eine JSON-Datei.
Args:
data (list): Zu speichernde Daten
file_path (str): Pfad zur Ausgabedatei
"""
try:
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"Integrierte Daten erfolgreich in '{file_path}' gespeichert.")
except Exception as e:
print(f"Fehler beim Speichern der Datei '{file_path}': {e}")
sys.exit(1)
def integrate_json_data(json_dimensions_data, json_2d_data, tolerance):
"""
Integriert Daten aus JSON_1 in JSON_2 über die Sivasnr.
Nur Einträge mit NICHT übereinstimmenden Objekt_width_mm und Objekt_height_mm werden integriert.
Args:
json_dimensions_data (dict): Dictionary mit Sivasnr als Key und Dimensionsdaten als Value
json_2d_data (list): Daten aus JSON_2
tolerance (float): Toleranz für die Übereinstimmung der Objekt-Abmessungen
Returns:
list: Integrierte Daten
"""
# Erstelle eine Kopie des Dictionary für die Verarbeitung
json_dimensions_dict = json_dimensions_data.copy()
integrated_data = []
updated_count = 0
new_count = 0
skipped_count = 0
# Durchlaufe JSON_2 und aktualisiere mit Daten aus JSON_1
for json_2d_item in json_2d_data:
sivasnr = json_2d_item['Sivasnr']
# Konvertiere Sivasnr zu String für Dictionary-Lookup
sivasnr_str = str(sivasnr)
if sivasnr_str in json_dimensions_dict:
json_dimensions_item = json_dimensions_dict[sivasnr_str]
# Prüfe Übereinstimmung der Objekt-Abmessungen
# Mapping der Attributnamen: 'breite' -> 'Objekt_width_mm', 'hoehe' -> 'Objekt_height_mm'
dimensions_width = json_dimensions_item.get('breite', 0)
dimensions_height = json_dimensions_item.get('hoehe', 0)
width_match = round(abs(dimensions_width - json_2d_item.get('Objekte_width_mm', 0)), 3) <= tolerance
height_match = round(abs(dimensions_height - json_2d_item.get('Objekte_height_mm', 0)), 3) <= tolerance
if not (width_match and height_match):
# Abmessungen stimmen NICHT überein - Eintrag mit Werten aus json_dimensions_data verwenden
width_diff = abs(dimensions_width - json_2d_item.get('Objekte_width_mm', 0))
height_diff = abs(dimensions_height - json_2d_item.get('Objekte_height_mm', 0))
print(f"Integriere Sivasnr {sivasnr}: Abmessungen stimmen nicht überein (Toleranz: {tolerance})")
print(f" Width-Differenz: {width_diff:.3f}mm, Height-Differenz: {height_diff:.3f}mm")
print(f" Verwende Werte aus json_dimensions_data")
# Erstelle einen neuen Eintrag mit den Werten aus json_dimensions_data
# und konvertiere die Attributnamen
integrated_item = {
'Sivasnr': sivasnr, # Verwende die ursprüngliche Sivasnr aus json_2d_data
'Objekt_width_mm': dimensions_width,
'Objekt_height_mm': dimensions_height,
'w_diff': round(width_diff, 3),
'h_diff': round(height_diff,3),
'tolerance': tolerance
}
# Weitere Attribute aus json_dimensions_data hinzufügen (falls vorhanden)
for key, value in json_dimensions_item.items():
if key not in ['breite', 'hoehe']:
integrated_item[key] = value
integrated_data.append(integrated_item)
updated_count += 1
else:
# Abmessungen stimmen überein - Eintrag überspringen
print(f"Überspringe Sivasnr {sivasnr}: Abmessungen stimmen überein, w_diff={abs(dimensions_width-json_2d_item.get('Objekte_width_mm', 0))}, h_diff={abs(dimensions_height-json_2d_item.get('Objekte_height_mm', 0))}, (innerhalb der Toleranz)")
skipped_count += 1
# Entferne das verarbeitete Item aus dem Dictionary
del json_dimensions_dict[sivasnr_str]
# Wenn Sivasnr nicht in JSON_1 gefunden wird, wird der Eintrag nicht zur Ausgabe hinzugefügt
# Füge verbleibende Items aus JSON_1 hinzu (die nicht in JSON_2 waren)
for sivasnr_str, json_dimensions_item in json_dimensions_dict.items():
# Erstelle einen neuen Eintrag mit konvertierten Attributnamen
integrated_item = {
'Sivasnr': sivasnr_str, # Verwende die String-Version der Sivasnr
'Objekt_width_mm': json_dimensions_item.get('breite', 0),
'Objekt_height_mm': json_dimensions_item.get('hoehe', 0)
}
# Weitere Attribute aus json_dimensions_data hinzufügen (falls vorhanden)
for key, value in json_dimensions_item.items():
if key not in ['breite', 'hoehe']:
integrated_item[key] = value
integrated_data.append(integrated_item)
new_count += 1
print(f"Neue Sivasnr {sivasnr_str} aus JSON_1 hinzugefügt (nicht in JSON_2 vorhanden).")
print(f"\nIntegration abgeschlossen:")
print(f"- {updated_count} Einträge integriert (Abmessungen stimmen nicht überein)")
print(f"- {new_count} neue Einträge hinzugefügt (nur in JSON_1 vorhanden)")
print(f"- {skipped_count} Einträge übersprungen (Abmessungen stimmen überein)")
print(f"- {len(integrated_data)} Einträge gesamt")
return integrated_data
def main():
"""
Hauptfunktion des Programms.
"""
parser = argparse.ArgumentParser(
description="Integriert JSON-Daten aus JSON_1 in JSON_2 über die Sivasnr",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Beispiel:
python json_integration.py --json_dimensions file1.json --json_2d file2.json --result result.json
python json_integration.py --type=BOGEN --output_dir /custom/output --json_dimensions file1.json --json_2d file2.json --result result.json
"""
)
parser.add_argument(
'--output_dir',
dest='output_dir',
required=False,
help='Ausgabeverzeichnis für integrierte Daten (Standard: PROJECT_WORK)'
)
parser.add_argument(
'--json_dimensions',
required=True,
help='Dateiname der ersten JSON-Datei (Quelldaten)',
metavar='[Weiche_3D, Bogen_3D, TEFWeiche_3D, TEFBogen_3D].json'
)
parser.add_argument(
'--json_2d',
required=True,
help='Dateiname der zweiten JSON-Datei (Zieldaten)',
metavar='[Weiche_2D, Bogen_2D, TEFWeiche_2D, TEFBogen_2D].json'
)
parser.add_argument(
'--tolerance',
type=float,
default=0.05,
required=False,
help='Toleranz in Millimetern, welche als Differenz akzeptiert wird.',
metavar='0.05'
)
parser.add_argument(
'--result',
default='Differenzen_2D_3D.json',
required=False,
help='Dateiname für die Ausgabedatei mit integrierten Daten'
)
parser.add_argument("--type", type=str, choices=["BOGEN", "WEICHE", "TEFBOGEN", "TEFWEICHE"], help="Art des Exports (BOGEN, WEICHE, TEFBOGEN, TEFWEICHE).")
if len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help"):
parser.print_help()
sys.exit(0)
args = parser.parse_args()
# Umgebungsvariablen & Ordner
output_dir = args.output_dir or os.environ.get("PROJECT_WORK", "./output")
input_3d_dir = os.environ.get("PROJECT_WORK")
bogen = os.environ.get("PROJECT_JSON_BOGEN")
weiche = os.environ.get("PROJECT_JSON_WEICHE")
tefbogen = os.environ.get("PROJECT_JSON_TEFBOGEN")
tefweiche = os.environ.get("PROJECT_JSON_TEFWEICHE")
tolerance = args.tolerance
if args.type == "BOGEN":
input_dir = bogen
elif args.type == "WEICHE":
input_dir = weiche
elif args.type == "TEFBOGEN":
input_dir = tefbogen
elif args.type == "TEFWEICHE":
input_dir = tefweiche
# Erstelle Verzeichnisse falls sie nicht existieren
if not Path(input_dir).exists():
print(f"Fehler: Eingabeverzeichnis existiert nicht.")
sys.exit(1)
Path(output_dir).mkdir(parents=True, exist_ok=True)
# Vollständige Pfade zu den Dateien
json_dimensions_path = Path(input_3d_dir) / args.json_dimensions
json_2d_path = Path(input_dir) / args.json_2d
output_path = Path(output_dir) / args.result
# Validiere Eingabedateien
if not json_dimensions_path.exists():
print(f"Fehler: JSON_1 Datei '{json_dimensions_path}' existiert nicht.")
sys.exit(1)
if not json_2d_path.exists():
print(f"Fehler: JSON_2 Datei '{json_2d_path}' existiert nicht.")
sys.exit(1)
# Lade JSON-Dateien
print(f"Lade JSON_1: {json_dimensions_path}")
json_dimensions_data = load_json_file(json_dimensions_path)
print(f"Lade JSON_2: {json_2d_path}")
json_2d_data = load_json_file(json_2d_path)
# # Validiere Datenstruktur
# if not isinstance(json_dimensions_data, list) or not isinstance(json_2d_data, list):
# print("Fehler: Beide JSON-Dateien müssen Arrays (Listen) enthalten.")
# parser.print_help()
# sys.exit(1)
# # Prüfe ob Sivasnr in allen Einträgen vorhanden ist
# for i, item in enumerate(json_dimensions_data):
# if 'Sivasnr' not in item:
# print(f"Fehler: Sivasnr fehlt in JSON_1 Eintrag {i}")
# parser.print_help()
# sys.exit(1)
for i, item in enumerate(json_2d_data):
if 'Sivasnr' not in item:
print(f"Fehler: Sivasnr fehlt in JSON_2 Eintrag {i}")
parser.print_help()
sys.exit(1)
print(f"JSON_1 enthält {len(json_dimensions_data)} Einträge")
print(f"JSON_2 enthält {len(json_2d_data)} Einträge")
# Integriere Daten
integrated_data = integrate_json_data(json_dimensions_data, json_2d_data, tolerance)
if len(integrated_data) > 0:
# Speichere integrierte Daten
save_json_file(integrated_data, output_path)
else:
print(f"Dateien enthalten keine Unterschiede")
if __name__ == "__main__":
main()