#!/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()