Merge branch 'main' of http://gitea.schoenenberger.de/mistangl/SSG-Ruledesigner-Konfigurator
@@ -0,0 +1,6 @@
|
|||||||
|
@echo off
|
||||||
|
REM ~dp0 steht für das Verzeichnis, in der diese Datei liegt
|
||||||
|
|
||||||
|
call setenv.bat
|
||||||
|
|
||||||
|
python "%PROJECT_LIB%\diff_dimensions.py" %*
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@echo off
|
||||||
|
REM ~dp0 steht für das Verzeichnis, in der diese Datei liegt
|
||||||
|
|
||||||
|
call diff_dimensions.bat --type WEICHE --json_2d omniflo_weichen.json --json_dimensions dimensions.json --tolerance 0.05
|
||||||
@@ -2,8 +2,12 @@
|
|||||||
REM ~dp0 steht für das Verzeichnis, in der diese Datei liegt
|
REM ~dp0 steht für das Verzeichnis, in der diese Datei liegt
|
||||||
pushd %~dp0\..
|
pushd %~dp0\..
|
||||||
|
|
||||||
set PROJECT_DIR=%cd%
|
for /f "delims=" %%i in ('git rev-parse --show-toplevel') do set SSG_RD_DIR=%%i
|
||||||
|
|
||||||
|
|
||||||
|
set PROJECT_DIR=%SSG_RD_DIR%\CAD\Code
|
||||||
|
|
||||||
|
set PROJECT_BIN=%PROJECT_DIR%\bin
|
||||||
set PROJECT_LIB=%PROJECT_DIR%\lib
|
set PROJECT_LIB=%PROJECT_DIR%\lib
|
||||||
set PROJECT_WORK=%PROJECT_DIR%\work
|
set PROJECT_WORK=%PROJECT_DIR%\work
|
||||||
set PROJECT_DATA=%PROJECT_DIR%\data
|
set PROJECT_DATA=%PROJECT_DIR%\data
|
||||||
@@ -12,5 +16,10 @@ set PROJECT_INPUT=%PROJECT_DIR%\input
|
|||||||
if not exist %PROJECT_WORK% mkdir %PROJECT_WORK%
|
if not exist %PROJECT_WORK% mkdir %PROJECT_WORK%
|
||||||
if not exist %PROJECT_INPUT% mkdir %PROJECT_INPUT%
|
if not exist %PROJECT_INPUT% mkdir %PROJECT_INPUT%
|
||||||
|
|
||||||
|
set PROJECT_JSON_BOGEN=%SSG_RD_DIR%\SVGs\Omniflo\python\OFBogen\json
|
||||||
|
set PROJECT_JSON_WEICHE=%SSG_RD_DIR%\SVGs\Omniflo\python\OFWeiche\json
|
||||||
|
set PROJECT_JSON_TEFBOGEN=%SSG_RD_DIR%\SVGs\Omniflo\python\TEFBogen\json
|
||||||
|
set PROJECT_JSON_TEFWEICHE=%SSG_RD_DIR%\SVGs\Omniflo\python\TEFWeiche\json
|
||||||
|
|
||||||
popd
|
popd
|
||||||
goto :eof
|
goto :eof
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
#!/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()
|
||||||
@@ -742,6 +742,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Sivasnr": "834372210+0_B10080+0_B10090",
|
"Sivasnr": "834372210+0_B10080+0_B10090",
|
||||||
|
"Sivasnr": "834372404+BG080090",
|
||||||
"ProfilTyp": "WEICHE S T 90°-700/700, KPL. MIT P mit TEF links",
|
"ProfilTyp": "WEICHE S T 90°-700/700, KPL. MIT P mit TEF links",
|
||||||
"WeichenTyp": "Dreiwegeweiche",
|
"WeichenTyp": "Dreiwegeweiche",
|
||||||
"KurvenWinkel": 90,
|
"KurvenWinkel": 90,
|
||||||
@@ -753,6 +754,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Sivasnr": "834372210+0_B10090+0_B10080",
|
"Sivasnr": "834372210+0_B10090+0_B10080",
|
||||||
|
"Sivasnr": "BG080090+834372404",
|
||||||
"ProfilTyp": "WEICHE S T 90°-700/700, KPL. MIT P mit TEF rechts",
|
"ProfilTyp": "WEICHE S T 90°-700/700, KPL. MIT P mit TEF rechts",
|
||||||
"WeichenTyp": "Dreiwegeweiche",
|
"WeichenTyp": "Dreiwegeweiche",
|
||||||
"KurvenWinkel": 90,
|
"KurvenWinkel": 90,
|
||||||
@@ -764,6 +766,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Sivasnr": "834372210+0_B10080+0_B10090+0_B10080+0_B10090",
|
"Sivasnr": "834372210+0_B10080+0_B10090+0_B10080+0_B10090",
|
||||||
|
"Sivasnr": "834372404+BG080090_B",
|
||||||
"ProfilTyp": "WEICHE S T 90°-700/700, KPL. MIT P mit TEF beideseitig",
|
"ProfilTyp": "WEICHE S T 90°-700/700, KPL. MIT P mit TEF beideseitig",
|
||||||
"WeichenTyp": "Dreiwegeweiche",
|
"WeichenTyp": "Dreiwegeweiche",
|
||||||
"KurvenWinkel": 90,
|
"KurvenWinkel": 90,
|
||||||
@@ -841,6 +844,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Sivasnr": "834372404+0_B10071+0_B10090+0_B10090+0_B10071+0_B10090+0_B10090",
|
"Sivasnr": "834372404+0_B10071+0_B10090+0_B10090+0_B10071+0_B10090+0_B10090",
|
||||||
|
"Sivasnr": "834372404+BG071090_B",
|
||||||
"ProfilTyp": "WEICHE S C DELTA 1600/800, KPL. P mit TEF beideseitig",
|
"ProfilTyp": "WEICHE S C DELTA 1600/800, KPL. P mit TEF beideseitig",
|
||||||
"WeichenTyp": "Dreifachweiche",
|
"WeichenTyp": "Dreifachweiche",
|
||||||
"KurvenWinkel": 90,
|
"KurvenWinkel": 90,
|
||||||
|
|||||||
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 582 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 664 B |
|
After Width: | Height: | Size: 1.3 KiB |