Die Code zur automatischen Erzeungung der SVG für OFWeiche wurde funitoniert.
This commit is contained in:
@@ -0,0 +1,513 @@
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
|
||||
def modify_json_values(json_file):
|
||||
# Constant definitions
|
||||
WeichenKoerperWidth = 32.5437
|
||||
BogenProfileWidth = 42.080
|
||||
WeichenkProfileWidth = 42.000
|
||||
WeichenGerade = 360.000
|
||||
|
||||
# Read JSON file
|
||||
with open(json_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
process_einzelweiche_items(data, WeichenKoerperWidth, WeichenkProfileWidth, BogenProfileWidth, WeichenGerade)
|
||||
process_doppelweiche_items(data, BogenProfileWidth, WeichenGerade)
|
||||
process_deltaweiche_items(data, WeichenkProfileWidth)
|
||||
process_sternweiche_items(data)
|
||||
# Save changes without confirmation
|
||||
with open(json_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
print("All changes saved automatically!")
|
||||
|
||||
def process_einzelweiche_items(data, WeichenKoerperWidth, WeichenkProfileWidth, BogenProfileWidth, WeichenGerade):
|
||||
# Filter matching items with additional Sivasnr check
|
||||
filtered_items = [
|
||||
item for item in data
|
||||
if (item.get("SivasnrTEF") is None and
|
||||
item.get("KurvenRichtung") == 1 and
|
||||
item.get("Schaltungstyp") == "M" and
|
||||
str(item.get("Sivasnr", "")).isdigit())
|
||||
]
|
||||
|
||||
print(f"Found {len(filtered_items)} matching records with numeric Sivasnr")
|
||||
|
||||
# Process each item
|
||||
for item in filtered_items:
|
||||
# Calculate related values
|
||||
if (item["OFWeiche_center_line_width_mm"] is not None and
|
||||
item["OFWeiche_center_line_height_mm"] is not None):
|
||||
|
||||
angle_rad = math.radians(item["KurvenWinkel"])
|
||||
|
||||
# Calculate basic values
|
||||
item["Objekt_width_mm"] = round(WeichenKoerperWidth +
|
||||
(BogenProfileWidth/2 * math.cos(angle_rad)) +
|
||||
item["OFWeiche_center_line_width_mm"] +
|
||||
WeichenkProfileWidth/2, 3)
|
||||
|
||||
if item["KurvenWinkel"] == 22.5:
|
||||
item["Objekt_height_mm"] = round(
|
||||
item["OFWeiche_center_line_height_mm"], 3)
|
||||
else:
|
||||
item["Objekt_height_mm"] = round(
|
||||
(BogenProfileWidth/2 * math.sin(angle_rad)) +
|
||||
item["OFWeiche_center_line_height_mm"], 3)
|
||||
|
||||
# Calculate CP point coordinates
|
||||
item["OFWeiche_CP1_x_mm"] = round(
|
||||
(BogenProfileWidth/2 * math.cos(angle_rad)) +
|
||||
item["OFWeiche_center_line_width_mm"], 3)
|
||||
|
||||
item["OFWeiche_CP1_y_mm"] = round(
|
||||
item["Objekt_height_mm"] - WeichenGerade, 3)
|
||||
|
||||
item["OFWeiche_CP2_x_mm"] = round(item["OFWeiche_CP1_x_mm"], 3)
|
||||
|
||||
item["OFWeiche_CP2_y_mm"] = round(item["Objekt_height_mm"], 3)
|
||||
|
||||
item["OFWeiche_CP3_x_mm"] = round(
|
||||
BogenProfileWidth/2 * math.cos(angle_rad), 3)
|
||||
|
||||
item["OFWeiche_CP3_y_mm"] = round(
|
||||
BogenProfileWidth/2 * math.sin(angle_rad), 3)
|
||||
|
||||
# Update items with identical ProfilTyp
|
||||
current_profil = item["ProfilTyp"]
|
||||
exact_matches = [x for x in data
|
||||
if x["ProfilTyp"] == current_profil and
|
||||
x is not item and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
if exact_matches:
|
||||
for match in exact_matches:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
match[field] = item[field]
|
||||
|
||||
# Find similar items with Schaltungstyp=P
|
||||
if "S" in current_profil:
|
||||
prefix = current_profil.rsplit(" ", 1)[0]
|
||||
|
||||
similar_items_p = [x for x in data
|
||||
if x["ProfilTyp"].startswith(prefix) and
|
||||
x["ProfilTyp"] != current_profil and
|
||||
"WEICHE" in x["ProfilTyp"] and
|
||||
x.get("SivasnrTEF") is None and
|
||||
x.get("Schaltungstyp") == "P"]
|
||||
|
||||
for similar in similar_items_p:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
similar[field] = item[field]
|
||||
|
||||
# Find L→R similar items with KurvenRichtung=2
|
||||
if "S" in current_profil and "-L-" in current_profil:
|
||||
r_profil = current_profil.replace("-L-", "-R-")
|
||||
|
||||
similar_items_r = [x for x in data
|
||||
if x["ProfilTyp"] == r_profil and
|
||||
x.get("SivasnrTEF") is None and
|
||||
x.get("KurvenRichtung") == 2 and
|
||||
x.get("Schaltungstyp") == "M"]
|
||||
|
||||
for similar in similar_items_r:
|
||||
# Copy basic values
|
||||
base_fields = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm"
|
||||
]
|
||||
|
||||
for field in base_fields:
|
||||
similar[field] = item[field]
|
||||
|
||||
# Calculate R-type specific CP points
|
||||
similar["OFWeiche_CP1_x_mm"] = round(WeichenKoerperWidth+WeichenkProfileWidth/2, 3)
|
||||
similar["OFWeiche_CP1_y_mm"] = round(item["Objekt_height_mm"] - WeichenGerade, 3)
|
||||
similar["OFWeiche_CP2_x_mm"] = similar["OFWeiche_CP1_x_mm"]
|
||||
similar["OFWeiche_CP2_y_mm"] = round(item["Objekt_height_mm"], 3)
|
||||
similar["OFWeiche_CP3_x_mm"] = round(
|
||||
similar["OFWeiche_CP1_x_mm"] + item["OFWeiche_center_line_width_mm"], 3)
|
||||
similar["OFWeiche_CP3_y_mm"] = round(
|
||||
BogenProfileWidth/2 * math.sin(angle_rad), 3)
|
||||
|
||||
# Find P-type counterparts for this R-type item
|
||||
r_p_profil = r_profil.replace("MIT M", "MIT P")
|
||||
|
||||
similar_items_r_p = [x for x in data
|
||||
if x["ProfilTyp"] == r_p_profil and
|
||||
x.get("SivasnrTEF") is None and
|
||||
x.get("Schaltungstyp") == "P"]
|
||||
|
||||
for similar_r_p in similar_items_r_p:
|
||||
fields_to_copy_r_p = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy_r_p:
|
||||
similar_r_p[field] = similar[field]
|
||||
|
||||
def process_doppelweiche_items(data, BogenProfileWidth, WeichenGerade):
|
||||
# Filter Doppelweiche type items with numeric Sivasnr check
|
||||
filtered_items = [
|
||||
item for item in data
|
||||
if (item.get("WeichenTyp") == "Doppelweiche" and
|
||||
item.get("Schaltungstyp") == "M" and
|
||||
item.get("SivasnrTEF") is None and
|
||||
str(item.get("Sivasnr", "")).isdigit())
|
||||
]
|
||||
|
||||
print(f"\nFound {len(filtered_items)} Doppelweiche type records with numeric Sivasnr")
|
||||
|
||||
# Process each Doppelweiche item
|
||||
for item in filtered_items:
|
||||
# Calculate related values
|
||||
if (item["OFWeiche_center_line_width_mm"] is not None and
|
||||
item["OFWeiche_center_line_height_mm"] is not None):
|
||||
|
||||
angle_rad = math.radians(item["KurvenWinkel"])
|
||||
|
||||
# Calculate basic values (Doppelweiche specific formula)
|
||||
item["Objekt_width_mm"] = round(
|
||||
(BogenProfileWidth/2 * math.cos(angle_rad)) +
|
||||
item["OFWeiche_center_line_width_mm"] +
|
||||
BogenProfileWidth/2 * math.cos(angle_rad), 3)
|
||||
|
||||
item["Objekt_height_mm"] = round(
|
||||
(BogenProfileWidth/2 * math.sin(angle_rad)) +
|
||||
item["OFWeiche_center_line_height_mm"], 3)
|
||||
|
||||
# Calculate CP point coordinates (Doppelweiche specific formula)
|
||||
item["OFWeiche_CP1_x_mm"] = round(item["Objekt_width_mm"]/2, 3)
|
||||
item["OFWeiche_CP1_y_mm"] = round(item["Objekt_height_mm"], 3)
|
||||
item["OFWeiche_CP2_x_mm"] = round(BogenProfileWidth/2 * math.cos(angle_rad), 3)
|
||||
item["OFWeiche_CP2_y_mm"] = round(BogenProfileWidth/2 * math.sin(angle_rad), 3)
|
||||
item["OFWeiche_CP3_x_mm"] = round(BogenProfileWidth/2 * math.cos(angle_rad) + item["OFWeiche_center_line_width_mm"], 3)
|
||||
item["OFWeiche_CP3_y_mm"] = item["OFWeiche_CP2_y_mm"]
|
||||
|
||||
# Update items with identical ProfilTyp
|
||||
current_profil = item["ProfilTyp"]
|
||||
exact_matches = [x for x in data
|
||||
if x["ProfilTyp"] == current_profil and
|
||||
x is not item and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
if exact_matches:
|
||||
for match in exact_matches:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
match[field] = item[field]
|
||||
|
||||
# Find similar items (D-type P-type)
|
||||
if "S D" in current_profil:
|
||||
d_p_profil = current_profil.replace("MIT M", "MIT P")
|
||||
|
||||
similar_items_d_p = [x for x in data
|
||||
if x["ProfilTyp"] == d_p_profil and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
for similar in similar_items_d_p:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
similar[field] = item[field]
|
||||
|
||||
# Find similar items (T-type M-type)
|
||||
if "S D" in current_profil:
|
||||
t_m_profil = current_profil.replace("S D", "S T")
|
||||
|
||||
similar_items_t_m = [x for x in data
|
||||
if x["ProfilTyp"] == t_m_profil and
|
||||
x.get("SivasnrTEF") is None and
|
||||
x.get("Schaltungstyp") == "M"]
|
||||
|
||||
for similar in similar_items_t_m:
|
||||
if similar["KurvenWinkel"] == 22.5:
|
||||
# Special handling for KurvenWinkel=22.5
|
||||
similar["OFWeiche_center_line_width_mm"] = item["OFWeiche_center_line_width_mm"]
|
||||
similar["OFWeiche_center_line_height_mm"] = WeichenGerade
|
||||
similar["Objekt_width_mm"] = item["Objekt_width_mm"]
|
||||
similar["Objekt_height_mm"] = WeichenGerade
|
||||
similar["OFWeiche_CP1_x_mm"] = item["OFWeiche_CP1_x_mm"]
|
||||
similar["OFWeiche_CP1_y_mm"] = similar["Objekt_height_mm"]
|
||||
similar["OFWeiche_CP2_x_mm"] = item["OFWeiche_CP2_x_mm"]
|
||||
similar["OFWeiche_CP2_y_mm"] = 20
|
||||
similar["OFWeiche_CP3_x_mm"] = item["OFWeiche_CP3_x_mm"]
|
||||
similar["OFWeiche_CP3_y_mm"] = 20
|
||||
else:
|
||||
# Update basic fields
|
||||
base_fields = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in base_fields:
|
||||
similar[field] = item[field]
|
||||
|
||||
# Add CP4 point (T-type specific)
|
||||
similar["OFWeiche_CP4_x_mm"] = round(similar["Objekt_width_mm"]/2, 3)
|
||||
similar["OFWeiche_CP4_y_mm"] = round(similar["Objekt_height_mm"] - WeichenGerade, 3)
|
||||
|
||||
# Find T-type P-type counterparts
|
||||
t_p_profil = t_m_profil.replace("MIT M", "MIT P")
|
||||
|
||||
similar_items_t_p = [x for x in data
|
||||
if x["ProfilTyp"] == t_p_profil and
|
||||
x.get("SivasnrTEF") is None and
|
||||
x.get("Schaltungstyp") == "P"]
|
||||
|
||||
for similar_t_p in similar_items_t_p:
|
||||
fields_to_copy_t_p = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm",
|
||||
"OFWeiche_CP4_x_mm",
|
||||
"OFWeiche_CP4_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy_t_p:
|
||||
similar_t_p[field] = similar[field]
|
||||
|
||||
def process_deltaweiche_items(data, WeichenkProfileWidth):
|
||||
# Filter deltaweiche type items
|
||||
filtered_items = [
|
||||
item for item in data
|
||||
if (item.get("WeichenTyp") == "Dreifachweiche" and
|
||||
item.get("Schaltungstyp") == "M" and
|
||||
item.get("SivasnrTEF") is None and
|
||||
str(item.get("Sivasnr", "")).isdigit())
|
||||
]
|
||||
|
||||
print(f"\nFound {len(filtered_items)} deltaweiche type records")
|
||||
|
||||
for item in filtered_items:
|
||||
# Calculate related values
|
||||
if (item["OFWeiche_center_line_width_mm"] is not None and
|
||||
item["OFWeiche_center_line_height_mm"] is not None):
|
||||
|
||||
# Calculate basic dimensions
|
||||
item["Objekt_width_mm"] = round(item["OFWeiche_center_line_width_mm"], 3)
|
||||
item["Objekt_height_mm"] = round(WeichenkProfileWidth/2 + item["OFWeiche_center_line_height_mm"]+32.5437, 3)
|
||||
|
||||
# Calculate control points
|
||||
item["OFWeiche_CP1_x_mm"] = round(item["Objekt_width_mm"]/2, 3)
|
||||
item["OFWeiche_CP1_y_mm"] = round(item["Objekt_height_mm"], 3)
|
||||
item["OFWeiche_CP2_x_mm"] = 0
|
||||
item["OFWeiche_CP2_y_mm"] = round(WeichenkProfileWidth/2+32.5437 , 3)
|
||||
item["OFWeiche_CP3_x_mm"] = round(item["Objekt_width_mm"], 3)
|
||||
item["OFWeiche_CP3_y_mm"] = item["OFWeiche_CP2_y_mm"]
|
||||
|
||||
# Update items with identical ProfilTyp
|
||||
current_profil = item["ProfilTyp"]
|
||||
exact_matches = [x for x in data
|
||||
if x["ProfilTyp"] == current_profil and
|
||||
x is not item and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
if exact_matches:
|
||||
for match in exact_matches:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
match[field] = item[field]
|
||||
|
||||
# Find similar items (P-type)
|
||||
if "WEICHE S C DELTA" in item["ProfilTyp"]:
|
||||
similar_profil = item["ProfilTyp"].replace("KPL. MIT M", "KPL. MIT P")
|
||||
|
||||
similar_items = [x for x in data
|
||||
if x["ProfilTyp"] == similar_profil and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
for similar in similar_items:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
similar[field] = item[field]
|
||||
def process_sternweiche_items(data):
|
||||
# Filter sternweiche type items
|
||||
filtered_items = [
|
||||
item for item in data
|
||||
if (item.get("WeichenTyp") == "Sternweiche" and
|
||||
item.get("Schaltungstyp") == "M" and
|
||||
item.get("SivasnrTEF") is None and
|
||||
str(item.get("Sivasnr", "")).isdigit())
|
||||
]
|
||||
|
||||
print(f"\nFound {len(filtered_items)} sternweiche type records")
|
||||
|
||||
for item in filtered_items:
|
||||
# Calculate related values
|
||||
if (item["OFWeiche_center_line_width_mm"] is not None and
|
||||
item["OFWeiche_center_line_height_mm"] is not None):
|
||||
|
||||
# Calculate basic dimensions
|
||||
item["Objekt_width_mm"] = round(item["OFWeiche_center_line_width_mm"], 3)
|
||||
item["Objekt_height_mm"] = round(item["OFWeiche_center_line_height_mm"], 3)
|
||||
|
||||
# Calculate control points
|
||||
|
||||
item["OFWeiche_CP1_x_mm"] = round(item["Objekt_width_mm"]/2, 3)
|
||||
item["OFWeiche_CP1_y_mm"] = round(item["Objekt_height_mm"], 3)
|
||||
item["OFWeiche_CP2_x_mm"] = 0
|
||||
item["OFWeiche_CP2_y_mm"] = round(item["OFWeiche_center_line_height_mm"]/2, 3)
|
||||
item["OFWeiche_CP3_x_mm"] = round(item["OFWeiche_center_line_width_mm"], 3)
|
||||
item["OFWeiche_CP3_y_mm"] = item["OFWeiche_CP2_y_mm"]
|
||||
item["OFWeiche_CP4_x_mm"] = item["OFWeiche_CP1_x_mm"]
|
||||
item["OFWeiche_CP4_y_mm"] = 0
|
||||
|
||||
# Update items with identical ProfilTyp
|
||||
current_profil = item["ProfilTyp"]
|
||||
exact_matches = [x for x in data
|
||||
if x["ProfilTyp"] == current_profil and
|
||||
x is not item and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
if exact_matches:
|
||||
for match in exact_matches:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm",
|
||||
"OFWeiche_CP4_x_mm",
|
||||
"OFWeiche_CP4_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
match[field] = item[field]
|
||||
|
||||
# Find similar items (P-type)
|
||||
if "WEICHE S C STERN" in item["ProfilTyp"]:
|
||||
similar_profil = item["ProfilTyp"].replace("KPL. MIT M", "KPL. MIT P")
|
||||
|
||||
similar_items = [x for x in data
|
||||
if x["ProfilTyp"] == similar_profil and
|
||||
x.get("SivasnrTEF") is None]
|
||||
|
||||
for similar in similar_items:
|
||||
fields_to_copy = [
|
||||
"OFWeiche_center_line_width_mm",
|
||||
"OFWeiche_center_line_height_mm",
|
||||
"Objekt_width_mm",
|
||||
"Objekt_height_mm",
|
||||
"OFWeiche_CP1_x_mm",
|
||||
"OFWeiche_CP1_y_mm",
|
||||
"OFWeiche_CP2_x_mm",
|
||||
"OFWeiche_CP2_y_mm",
|
||||
"OFWeiche_CP3_x_mm",
|
||||
"OFWeiche_CP3_y_mm",
|
||||
"OFWeiche_CP4_x_mm",
|
||||
"OFWeiche_CP4_y_mm"
|
||||
]
|
||||
|
||||
for field in fields_to_copy:
|
||||
similar[field] = item[field]
|
||||
if __name__ == "__main__":
|
||||
json_path = os.environ.get("JSON_PATH", "JSON")
|
||||
input_filename = os.path.join(json_path, "omniflo_weichen.json")
|
||||
|
||||
modify_json_values(input_filename)
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
def process_json_file(input_file, output_file):
|
||||
# 确保输出目录存在
|
||||
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
||||
|
||||
# 检查输入文件是否存在
|
||||
if not os.path.exists(input_file):
|
||||
raise FileNotFoundError(f"输入文件不存在: {input_file}")
|
||||
|
||||
# 加载JSON数据
|
||||
with open(input_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Process each item in the JSON data
|
||||
for item in data:
|
||||
if item.get("SivasnrTEF") is None:
|
||||
# Step 1: Calculate pixel dimensions
|
||||
width_mm = item["Objekt_width_mm"]
|
||||
height_mm = item["Objekt_height_mm"]
|
||||
|
||||
# Calculate initial pixel values
|
||||
item["Objekt_width_px"] = round(width_mm * 3.7795, 3)
|
||||
item["Objekt_height_px"] = round(height_mm * 3.7795, 3)
|
||||
|
||||
# Determine which dimension is larger and calculate scaling factor
|
||||
if width_mm >= height_mm:
|
||||
|
||||
scale = 1000 / width_mm
|
||||
item["calculated_SVG_width_px"] = 1000.0
|
||||
item["calculated_SVG_height_px"] = round(height_mm * scale, 3)
|
||||
scale_RD_H = round(1000 / item["calculated_SVG_height_px"],6)
|
||||
scale_RD_W = 1
|
||||
else:
|
||||
scale = 1000 / height_mm
|
||||
item["calculated_SVG_width_px"] = round(width_mm * scale, 3)
|
||||
item["calculated_SVG_height_px"] = 1000.0
|
||||
scale_RD_W = round(1000 / item["calculated_SVG_width_px"], 6)
|
||||
scale_RD_H = 1
|
||||
|
||||
|
||||
item["scale_factor"] = round(scale, 6)
|
||||
item["scale_factor_RD_Width"] = round(scale_RD_W, 6)
|
||||
item["scale_factor_RD_Height"] = round(scale_RD_H, 6)
|
||||
# Process connection points
|
||||
connection_points = []
|
||||
|
||||
# CP1
|
||||
cp1_x = round(item["OFWeiche_CP1_x_mm"] * scale*scale_RD_W, 3)
|
||||
cp1_y = round(item["OFWeiche_CP1_y_mm"] * scale*scale_RD_H, 3)
|
||||
|
||||
# CP2
|
||||
cp2_x = round(item["OFWeiche_CP2_x_mm"] * scale*scale_RD_W, 3)
|
||||
cp2_y = round(item["OFWeiche_CP2_y_mm"] * scale*scale_RD_H, 3)
|
||||
|
||||
# CP3
|
||||
cp3_x = round(item["OFWeiche_CP3_x_mm"] * scale*scale_RD_W, 3)
|
||||
cp3_y = round(item["OFWeiche_CP3_y_mm"] * scale*scale_RD_H, 3)
|
||||
|
||||
# Determine directions based on WeichenTyp
|
||||
weichen_typ = item["WeichenTyp"]
|
||||
kurven_winkel = item["KurvenWinkel"]
|
||||
profil_typ = item["ProfilTyp"]
|
||||
|
||||
if weichen_typ == "Einzelweiche":
|
||||
cp1_dir = 0.0
|
||||
cp2_dir = 180.0
|
||||
if "-L-" in profil_typ:
|
||||
cp3_dir = round(360 - kurven_winkel, 1)
|
||||
elif "-R-" in profil_typ:
|
||||
cp3_dir = round(kurven_winkel, 1)
|
||||
else:
|
||||
cp3_dir = 0.0 # Default if pattern not found
|
||||
elif weichen_typ == "Doppelweiche":
|
||||
cp1_dir = 180.0
|
||||
cp2_dir = round(360 - kurven_winkel, 1)
|
||||
cp3_dir = round(kurven_winkel, 1)
|
||||
elif weichen_typ == "Dreifachweiche":
|
||||
cp1_dir = 180.0
|
||||
cp2_dir = round(360 - kurven_winkel, 1)
|
||||
cp3_dir = round(kurven_winkel, 1)
|
||||
|
||||
elif weichen_typ == "Dreiwegeweiche":
|
||||
cp1_dir = 180.0
|
||||
cp2_dir = round(360 - kurven_winkel, 1)
|
||||
cp3_dir = round(kurven_winkel, 1)
|
||||
# CP4 exists for Dreiwegeweiche
|
||||
cp4_x = round(item["OFWeiche_CP4_x_mm"] * scale*scale_RD_W, 3)
|
||||
cp4_y = round(item["OFWeiche_CP4_y_mm"] * scale*scale_RD_H, 3)
|
||||
cp4_dir = 90.0
|
||||
|
||||
connection_points.append({
|
||||
"id": "cp4",
|
||||
"x": cp4_x,
|
||||
"y": cp4_y,
|
||||
"direction": cp4_dir
|
||||
})
|
||||
|
||||
# Add common connection points
|
||||
elif weichen_typ == "Sternweiche":
|
||||
cp1_dir = 180
|
||||
cp2_dir = round(360 - kurven_winkel, 1)
|
||||
cp3_dir = round(kurven_winkel, 1)
|
||||
# CP4 exists for Dreiwegeweiche
|
||||
cp4_x = round(item["OFWeiche_CP4_x_mm"] * scale*scale_RD_W, 3)
|
||||
cp4_y = round(item["OFWeiche_CP4_y_mm"] * scale*scale_RD_H, 3)
|
||||
cp4_dir = 0
|
||||
|
||||
connection_points.append({
|
||||
"id": "cp4",
|
||||
"x": cp4_x,
|
||||
"y": cp4_y,
|
||||
"direction": cp4_dir
|
||||
})
|
||||
|
||||
connection_points.extend([
|
||||
{
|
||||
"id": "cp1",
|
||||
"x": cp1_x,
|
||||
"y": cp1_y,
|
||||
"direction": cp1_dir
|
||||
},
|
||||
{
|
||||
"id": "cp2",
|
||||
"x": cp2_x,
|
||||
"y": cp2_y,
|
||||
"direction": cp2_dir
|
||||
},
|
||||
{
|
||||
"id": "cp3",
|
||||
"x": cp3_x,
|
||||
"y": cp3_y,
|
||||
"direction": cp3_dir
|
||||
}
|
||||
])
|
||||
|
||||
item["connectionPoints"] = connection_points
|
||||
|
||||
# Save the processed data
|
||||
with open(output_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
json_path = os.environ.get("JSON_PATH", "JSON")
|
||||
input_filename = os.path.join(json_path, "omniflo_weichen.json")
|
||||
output_filename = os.path.join(json_path, "omniflo_weichen_output.json")
|
||||
|
||||
try:
|
||||
process_json_file(input_filename, output_filename)
|
||||
print(f"Process is finished , the File is saved as: {output_filename}")
|
||||
except Exception as e:
|
||||
print(f"Errno: {str(e)}")
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
''' Script Analysis
|
||||
|
||||
This Python script processes JSON and TXT files to update dimensions and connection points in SVG-related data, but only for entries where SivasnrTEF is null. Here's the main logic:
|
||||
Input Handling:
|
||||
Reads a JSON file containing reference data
|
||||
Processes all TXT files in a specified directory
|
||||
Data Processing:
|
||||
Creates a mapping between Sivasnr (from filenames) and JSON data (only for entries with SivasnrTEF = null)
|
||||
For each matching TXT file:
|
||||
Updates width and height based on JSON data (converting mm to px)
|
||||
Updates connection points (x, y, direction) from JSON data
|
||||
Preserves the original file structure while updating specific values
|
||||
Reporting:
|
||||
Prints detailed change reports to console
|
||||
Skips files without matching JSON data or where SivasnrTEF is not null '''
|
||||
import json
|
||||
import os
|
||||
import glob
|
||||
from datetime import datetime
|
||||
|
||||
def process_files(json_file_path, txt_files_dir):
|
||||
# Create a log file with timestamp
|
||||
if not os.path.exists(json_file_path):
|
||||
print(f"Error: JSON file does not exist at {json_file_path}")
|
||||
exit(1)
|
||||
|
||||
if not os.path.exists(txt_files_dir):
|
||||
print(f"Error: Directory does not exist at {txt_files_dir}")
|
||||
exit(1)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
log_file_path = os.path.join(txt_files_dir, f"modification_report_OFWeiche_{timestamp}.txt")
|
||||
|
||||
# Read JSON file
|
||||
with open(json_file_path, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
|
||||
# Create Sivasnr to JSON data mapping ONLY for items with SivasnrTEF = null
|
||||
sivasnr_mapping = {str(item["Sivasnr"]): item for item in json_data if item["SivasnrTEF"] is None}
|
||||
|
||||
# Initialize counters
|
||||
total_files = 0
|
||||
processed_files = 0
|
||||
skipped_files = 0
|
||||
skipped_due_to_tef = 0
|
||||
|
||||
# Prepare report content
|
||||
report_content = []
|
||||
report_content.append(f"Modification Report - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
report_content.append(f"JSON Reference File: {json_file_path}")
|
||||
report_content.append(f"TXT Files Directory: {txt_files_dir}")
|
||||
report_content.append("Processing only files where SivasnrTEF is null")
|
||||
report_content.append(f"Total JSON entries with SivasnrTEF=null: {len(sivasnr_mapping)}")
|
||||
report_content.append("="*50 + "\n")
|
||||
|
||||
# Process all TXT files
|
||||
for txt_file_path in glob.glob(os.path.join(txt_files_dir, '*.txt')):
|
||||
total_files += 1
|
||||
filename = os.path.basename(txt_file_path)
|
||||
sivasnr = os.path.splitext(filename)[0]
|
||||
|
||||
# Check if corresponding JSON data exists and SivasnrTEF is null
|
||||
if sivasnr in sivasnr_mapping:
|
||||
json_item = sivasnr_mapping[sivasnr]
|
||||
|
||||
try:
|
||||
# Read TXT file content
|
||||
with open(txt_file_path, 'r', encoding='utf-8-sig') as f:
|
||||
txt_content = json.load(f)
|
||||
|
||||
# Record old values
|
||||
old_width = txt_content["width"]
|
||||
old_height = txt_content["height"]
|
||||
old_cps = {cp["id"]: {"x": cp["x"], "y": cp["y"], "direction": cp["direction"]}
|
||||
for cp in txt_content["connectionPoints"]}
|
||||
|
||||
# Update width and height (using direct pixel values now)
|
||||
new_width = round(json_item["Objekt_width_px"], 3)
|
||||
new_height = round(json_item["Objekt_height_px"], 3)
|
||||
txt_content["width"] = new_width
|
||||
txt_content["height"] = new_height
|
||||
|
||||
# Update connectionPoints
|
||||
cp_changes = []
|
||||
for cp in txt_content["connectionPoints"]:
|
||||
cp_id = cp["id"]
|
||||
# Find corresponding connection point in JSON data
|
||||
json_cp = next((item for item in json_item["connectionPoints"] if item["id"] == cp_id), None)
|
||||
if json_cp:
|
||||
# Record old values
|
||||
old_x = cp["x"]
|
||||
old_y = cp["y"]
|
||||
old_dir = cp["direction"]
|
||||
|
||||
# Update values
|
||||
cp["x"] = json_cp["x"]
|
||||
cp["y"] = json_cp["y"]
|
||||
cp["direction"] = json_cp["direction"]
|
||||
|
||||
# Record changes
|
||||
cp_changes.append({
|
||||
"id": cp_id,
|
||||
"x": (old_x, cp["x"]),
|
||||
"y": (old_y, cp["y"]),
|
||||
"direction": (old_dir, cp["direction"])
|
||||
})
|
||||
|
||||
# Write back to TXT file
|
||||
with open(txt_file_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(txt_content, f, indent=2, ensure_ascii=False)
|
||||
|
||||
# Print success message to console
|
||||
print(f"\nSuccessfully processed file: {filename}")
|
||||
print("[Dimension Changes]")
|
||||
print(f"width: {old_width} → {new_width}")
|
||||
print(f"height: {old_height} → {new_height}")
|
||||
|
||||
if cp_changes:
|
||||
print("\n[Connection Point Changes]")
|
||||
for change in cp_changes:
|
||||
print(f"Connection point {change['id']}:")
|
||||
print(f" x: {change['x'][0]} → {change['x'][1]}")
|
||||
print(f" y: {change['y'][0]} → {change['y'][1]}")
|
||||
print(f" direction: {change['direction'][0]} → {change['direction'][1]}")
|
||||
print("="*50)
|
||||
|
||||
# Add to report
|
||||
file_entry = []
|
||||
file_entry.append(f"\nProcessing file: {filename}")
|
||||
file_entry.append("="*50)
|
||||
file_entry.append("[Dimension Changes]")
|
||||
file_entry.append(f"width: {old_width} → {new_width}")
|
||||
file_entry.append(f"height: {old_height} → {new_height}")
|
||||
|
||||
if cp_changes:
|
||||
file_entry.append("\n[Connection Point Changes]")
|
||||
for change in cp_changes:
|
||||
file_entry.append(f"Connection point {change['id']}:")
|
||||
file_entry.append(f" x: {change['x'][0]} → {change['x'][1]}")
|
||||
file_entry.append(f" y: {change['y'][0]} → {change['y'][1]}")
|
||||
file_entry.append(f" direction: {change['direction'][0]} → {change['direction'][1]}")
|
||||
|
||||
processed_files += 1
|
||||
file_entry.append(f"\nFile processed successfully")
|
||||
file_entry.append("="*50)
|
||||
report_content.extend(file_entry)
|
||||
|
||||
except Exception as e:
|
||||
report_content.append(f"\nError processing file {filename}: {str(e)}")
|
||||
else:
|
||||
skipped_files += 1
|
||||
# Check if the file was skipped because SivasnrTEF is not null
|
||||
matching_json_items = [item for item in json_data if str(item["Sivasnr"]) == sivasnr]
|
||||
if matching_json_items and matching_json_items[0]["SivasnrTEF"] is not None:
|
||||
skipped_due_to_tef += 1
|
||||
|
||||
# Add processing statistics to report
|
||||
report_content.append("\n" + "="*50)
|
||||
report_content.append("Processing Statistics:")
|
||||
report_content.append(f"Total TXT files found: {total_files}")
|
||||
report_content.append(f"Total JSON records available: {len(json_data)}")
|
||||
report_content.append(f"JSON records with SivasnrTEF = null: {len(sivasnr_mapping)}")
|
||||
report_content.append(f"Successfully processed: {processed_files}")
|
||||
report_content.append(f"Skipped files (no match): {skipped_files - skipped_due_to_tef}")
|
||||
report_content.append(f"Skipped files (SivasnrTEF not null): {skipped_due_to_tef}")
|
||||
if len(sivasnr_mapping) > 0:
|
||||
success_rate = (processed_files / len(sivasnr_mapping)) * 100
|
||||
report_content.append(f"Success rate: {success_rate:.2f}%")
|
||||
report_content.append("="*50)
|
||||
|
||||
# Print final statistics to console
|
||||
print("\n" + "="*50)
|
||||
print("Processing Complete - Summary Statistics:")
|
||||
print(f"Successfully processed files: {processed_files}")
|
||||
print(f"Total files found in directory: {total_files}")
|
||||
if len(sivasnr_mapping) > 0:
|
||||
print(f"Success rate: {success_rate:.2f}%")
|
||||
print("="*50)
|
||||
print(f"Detailed report saved to: {log_file_path}")
|
||||
|
||||
# Write the report file
|
||||
with open(log_file_path, 'w', encoding='utf-8') as f:
|
||||
f.write("\n".join(report_content))
|
||||
|
||||
if __name__ == "__main__":
|
||||
json_path = os.environ.get("JSON_PATH", "JSON")
|
||||
json_file_path = os.path.join(json_path, "omniflo_weichen_output.json")
|
||||
|
||||
# txt_files_dir = r"C:\Program Files\RuleDesigner\RDConfigurator Fusion\WebApi\Editor2D\SSG\shapes\props"
|
||||
txt_files_dir= os.environ.get("PROPS_PATH", "props")
|
||||
process_files(json_file_path, txt_files_dir)
|
||||
+27
-75
@@ -177,69 +177,7 @@ def analyze_and_normalize_path(d, path_type, path_id=""):
|
||||
full_report.append("Path not modified")
|
||||
|
||||
return new_d, '\n'.join(full_report)
|
||||
''' def analyze_and_normalize_path(d, path_type, path_id=""):
|
||||
"""Strictly normalize path direction and generate detailed report"""
|
||||
original_d = d
|
||||
report = []
|
||||
normalized = []
|
||||
changed = False
|
||||
|
||||
# First check if path contains any arc commands
|
||||
if 'A' in d or 'a' in d:
|
||||
report.append(" Path contains arc commands - leaving unchanged")
|
||||
return original_d, report, False
|
||||
|
||||
# Ensure path starts with M command
|
||||
if not d.strip().startswith('M'):
|
||||
d = 'M' + d[1:] if d.startswith('L') else 'M ' + d
|
||||
report.append(" Fix: Added M command at path start")
|
||||
changed = True
|
||||
|
||||
# Parse path commands
|
||||
commands = []
|
||||
current_cmd = None
|
||||
for token in re.split('([A-Za-z])', d):
|
||||
if not token:
|
||||
continue
|
||||
if token in 'MLAZHVCSQTa-z':
|
||||
current_cmd = token
|
||||
else:
|
||||
if current_cmd:
|
||||
commands.append((current_cmd, token.strip()))
|
||||
|
||||
prev_x, prev_y = None, None
|
||||
|
||||
for cmd, params in commands:
|
||||
params = [float(p) for p in re.split('[, ]+', params.strip()) if p]
|
||||
|
||||
if cmd == 'M':
|
||||
if len(params) >= 2:
|
||||
x, y = params[0], params[1]
|
||||
normalized.append(f"M {x} {y}")
|
||||
prev_x, prev_y = x, y
|
||||
continue
|
||||
|
||||
if path_type == 'Line segment' and cmd == 'L':
|
||||
if len(params) >= 2 and prev_x is not None:
|
||||
x, y = params[0], params[1]
|
||||
need_swap = x < prev_x or (x == prev_x and y < prev_y)
|
||||
|
||||
if need_swap:
|
||||
new_segment = [f"M {x} {y}", f"L {prev_x} {prev_y}"]
|
||||
report.append(f" Need to swap start/end → New path: {' '.join(new_segment)}")
|
||||
normalized = new_segment
|
||||
changed = True
|
||||
else:
|
||||
normalized.append(f"L {x} {y}")
|
||||
report.append(" Path direction already correct, no changes made")
|
||||
|
||||
prev_x, prev_y = x, y
|
||||
continue
|
||||
|
||||
normalized.append(f"{cmd} {' '.join(map(str, params))}")
|
||||
|
||||
normalized_path = ' '.join(normalized)
|
||||
return normalized_path if changed else original_d, report, changed '''
|
||||
|
||||
def optimize_svg(input_path, output_path):
|
||||
"""Process single SVG file with all optimizations"""
|
||||
try:
|
||||
@@ -443,21 +381,32 @@ if __name__ == '__main__':
|
||||
|
||||
args = parser.parse_args()
|
||||
in_dir = None
|
||||
if args.bogen:
|
||||
in_dir = os.environ.get('RD_CONF_BOGEN')
|
||||
if args.tefbogen:
|
||||
in_dir = os.environ.get('RD_CONF_TEFBOGEN')
|
||||
if args.weichen:
|
||||
in_dir = os.environ.get('RD_CONF_WEICHEN')
|
||||
if args.tefweichen:
|
||||
in_dir = os.environ.get('RD_CONF_TEFWEICHEN')
|
||||
if args.inputdir:
|
||||
in_dir = args.inputdir
|
||||
else:
|
||||
if args.bogen:
|
||||
in_dir = os.environ.get('RD_CONF_BOGEN')
|
||||
elif args.tefbogen:
|
||||
in_dir = os.environ.get('RD_CONF_TEFBOGEN')
|
||||
elif args.weichen:
|
||||
in_dir = os.environ.get('RD_CONF_WEICHEN')
|
||||
elif args.tefweichen:
|
||||
in_dir = os.environ.get('RD_CONF_TEFWEICHEN')
|
||||
|
||||
out_dir = os.environ.get('RD_CONF_WORK')
|
||||
|
||||
if args.outputdir:
|
||||
out_dir = args.outputdir
|
||||
|
||||
if not out_dir:
|
||||
print("Error: RD_CONF_WORK environment variable must be set as output directory")
|
||||
exit(1)
|
||||
# Check if input directory exists
|
||||
if not os.path.exists(in_dir):
|
||||
print(f"Error: Input directory does not exist - {in_dir}")
|
||||
exit(1)
|
||||
|
||||
# Ensure output directory exists (create if doesn't exist, ignore if already exists)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
# Processing logic
|
||||
if args.file:
|
||||
filename = args.file
|
||||
input_path = os.path.join(in_dir, filename)
|
||||
@@ -469,5 +418,8 @@ if __name__ == '__main__':
|
||||
if in_dir:
|
||||
"""Batch process SVG files"""
|
||||
batch_process_svgs(in_dir, out_dir)
|
||||
|
||||
else:
|
||||
parser.print_help()
|
||||
print("Error: No input directory specified")
|
||||
parser.print_help()
|
||||
exit(1)
|
||||
@@ -0,0 +1,247 @@
|
||||
import os
|
||||
from lxml import etree
|
||||
import re
|
||||
from math import sqrt, isclose
|
||||
from collections import defaultdict
|
||||
|
||||
# Constants
|
||||
WEICHEN_PROFILE_WIDTH = 42.000
|
||||
L_R_TARGET_LENGTH = 55.7237
|
||||
DELTA_TARGET_LENGTH = 53.5437
|
||||
MATCH_TOLERANCE = 0.1 # Matching tolerance 0.1mm
|
||||
|
||||
def process_svg_files(directory):
|
||||
print(f"🔍 Scanning directory: {directory}")
|
||||
print("-" * 60)
|
||||
|
||||
result_stats = {
|
||||
'total_files': 0,
|
||||
'L_R_files': {'with_pairs': [], 'no_pairs': [], 'excess_pairs': []},
|
||||
'Delta_files': {'with_triples': [], 'no_triples': [], 'excess_triples': []}
|
||||
}
|
||||
|
||||
for filename in os.listdir(directory):
|
||||
if not filename.endswith('.svg'):
|
||||
continue
|
||||
|
||||
filepath = os.path.join(directory, filename)
|
||||
result_stats['total_files'] += 1
|
||||
|
||||
if '_L_' in filename or '_R_' in filename:
|
||||
print(f"\n📄 Processing L/R file: {filename}")
|
||||
process_lr_file(filepath, filename, result_stats)
|
||||
elif 'DeltaWeiche' in filename:
|
||||
print(f"\n📄 Processing DeltaWeiche file: {filename}")
|
||||
process_delta_file(filepath, filename, result_stats)
|
||||
|
||||
# Print final statistics
|
||||
print("\n" + "="*60)
|
||||
print("📊 Final processing statistics:")
|
||||
print(f"Total files processed: {result_stats['total_files']}")
|
||||
|
||||
print("\nL/R type files results:")
|
||||
print(f"✅ Files with matching path pairs: {len(result_stats['L_R_files']['with_pairs'])}")
|
||||
print(f" {result_stats['L_R_files']['with_pairs']}")
|
||||
print(f"⚠️ Files with no matching paths: {len(result_stats['L_R_files']['no_pairs'])}")
|
||||
print(f" {result_stats['L_R_files']['no_pairs']}")
|
||||
print(f"❌ Files with >2 matching paths: {len(result_stats['L_R_files']['excess_pairs'])}")
|
||||
print(f" {result_stats['L_R_files']['excess_pairs']}")
|
||||
|
||||
print("\nDeltaWeiche type files results:")
|
||||
print(f"✅ Files with matching path triples: {len(result_stats['Delta_files']['with_triples'])}")
|
||||
print(f" {result_stats['Delta_files']['with_triples']}")
|
||||
print(f"⚠️ Files with no matching paths: {len(result_stats['Delta_files']['no_triples'])}")
|
||||
print(f" {result_stats['Delta_files']['no_triples']}")
|
||||
print(f"❌ Files with ≠3 matching paths: {len(result_stats['Delta_files']['excess_triples'])}")
|
||||
print(f" {result_stats['Delta_files']['excess_triples']}")
|
||||
|
||||
print("\n✨ Processing complete!")
|
||||
|
||||
def process_lr_file(filepath, filename, stats):
|
||||
try:
|
||||
tree = etree.parse(filepath)
|
||||
root = tree.getroot()
|
||||
|
||||
# Find all straight line paths
|
||||
straight_lines = find_straight_lines(root)
|
||||
print(f" 📊 Found {len(straight_lines)} straight paths")
|
||||
|
||||
# Print all straight paths
|
||||
print("\n 🔍 All straight path details:")
|
||||
for line in straight_lines:
|
||||
print(f" Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
|
||||
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f}) length={line['length']:.4f}mm")
|
||||
|
||||
# Group by length
|
||||
length_groups = group_lines_by_length(straight_lines)
|
||||
|
||||
# Only print groups with exactly 2 paths
|
||||
print("\n 🔍 Same-length path groups (2 paths):")
|
||||
perfect_pairs = [group for group in length_groups.values() if len(group) == 2]
|
||||
for group in perfect_pairs:
|
||||
print(f" ┌ Length group ({group[0]['length']:.4f}mm, 2 paths)")
|
||||
for line in group:
|
||||
print(f" │ Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
|
||||
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f})")
|
||||
print(" └" + "─" * 40)
|
||||
|
||||
if len(perfect_pairs) == 1:
|
||||
pair = perfect_pairs[0]
|
||||
original_length = pair[0]['length']
|
||||
scale_factor = WEICHEN_PROFILE_WIDTH / original_length
|
||||
print(f"\n 🔄 Scaling calculation (based on length {original_length:.4f}mm):")
|
||||
print(f" Scale factor: {scale_factor:.4f}")
|
||||
|
||||
# Print scaled lengths
|
||||
print("\n 🔍 Scaled path lengths:")
|
||||
for line in straight_lines:
|
||||
scaled_len = line['length'] * scale_factor
|
||||
print(f" Path{line['index']}: {line['length']:.4f}mm → {scaled_len:.4f}mm")
|
||||
|
||||
# Find path matching target length (within tolerance)
|
||||
target_path = find_target_path(straight_lines, scale_factor, L_R_TARGET_LENGTH)
|
||||
if target_path:
|
||||
target_path['element'].set('style', 'stroke:none;fill:none;')
|
||||
tree.write(filepath, encoding='utf-8', xml_declaration=True)
|
||||
print(f"\n ✅ Hid path{target_path['index']} matching target length {L_R_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm)")
|
||||
stats['L_R_files']['with_pairs'].append(filename)
|
||||
else:
|
||||
print(f"\n ❌ No path found matching {L_R_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm)")
|
||||
stats['L_R_files']['no_pairs'].append(filename)
|
||||
elif len(perfect_pairs) > 1:
|
||||
print(f"\n ❗ Found multiple same-length path groups: {[len(g) for g in length_groups.values()]}")
|
||||
stats['L_R_files']['excess_pairs'].append(filename)
|
||||
else:
|
||||
print("\n ❌ No same-length path pairs found")
|
||||
stats['L_R_files']['no_pairs'].append(filename)
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Processing failed: {str(e)}")
|
||||
|
||||
def process_delta_file(filepath, filename, stats):
|
||||
try:
|
||||
tree = etree.parse(filepath)
|
||||
root = tree.getroot()
|
||||
|
||||
# Find all straight line paths
|
||||
straight_lines = find_straight_lines(root)
|
||||
print(f" 📊 Found {len(straight_lines)} straight paths")
|
||||
|
||||
# Print all straight paths
|
||||
print("\n 🔍 All straight path details:")
|
||||
for line in straight_lines:
|
||||
print(f" Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
|
||||
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f}) length={line['length']:.4f}mm")
|
||||
|
||||
# Group by length
|
||||
length_groups = group_lines_by_length(straight_lines)
|
||||
|
||||
# Only print groups with exactly 3 paths
|
||||
print("\n 🔍 Same-length path groups (3 paths):")
|
||||
perfect_triples = [group for group in length_groups.values() if len(group) == 3]
|
||||
for group in perfect_triples:
|
||||
print(f" ┌ Length group ({group[0]['length']:.4f}mm, 3 paths)")
|
||||
for line in group:
|
||||
print(f" │ Path{line['index']}: ({line['p1'][0]:.2f},{line['p1'][1]:.2f})→"
|
||||
f"({line['p2'][0]:.2f},{line['p2'][1]:.2f})")
|
||||
print(" └" + "─" * 40)
|
||||
|
||||
if len(perfect_triples) == 1:
|
||||
triple = perfect_triples[0]
|
||||
original_length = triple[0]['length']
|
||||
scale_factor = WEICHEN_PROFILE_WIDTH / original_length
|
||||
print(f"\n 🔄 Scaling calculation (based on length {original_length:.4f}mm):")
|
||||
print(f" Scale factor: {scale_factor:.4f}")
|
||||
|
||||
# Print scaled lengths
|
||||
print("\n 🔍 Scaled path lengths:")
|
||||
for line in straight_lines:
|
||||
scaled_len = line['length'] * scale_factor
|
||||
print(f" Path{line['index']}: {line['length']:.4f}mm → {scaled_len:.4f}mm")
|
||||
|
||||
# Find all paths matching target length (there might be multiple)
|
||||
target_paths = [line for line in straight_lines
|
||||
if abs(line['length'] * scale_factor - DELTA_TARGET_LENGTH) < MATCH_TOLERANCE]
|
||||
|
||||
if target_paths:
|
||||
for target in target_paths:
|
||||
target['element'].set('style', 'stroke:none;fill:none;')
|
||||
tree.write(filepath, encoding='utf-8', xml_declaration=True)
|
||||
print(f"\n ✅ Hid {len(target_paths)} paths matching target length {DELTA_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm):")
|
||||
for target in target_paths:
|
||||
print(f" - Path{target['index']}")
|
||||
stats['Delta_files']['with_triples'].append(filename)
|
||||
else:
|
||||
print(f"\n ❌ No path found matching {DELTA_TARGET_LENGTH:.4f}mm (±{MATCH_TOLERANCE}mm)")
|
||||
stats['Delta_files']['no_triples'].append(filename)
|
||||
elif len(perfect_triples) > 1:
|
||||
print(f"\n ❗ Found multiple same-length path groups: {[len(g) for g in length_groups.values()]}")
|
||||
stats['Delta_files']['excess_triples'].append(filename)
|
||||
else:
|
||||
print("\n ❌ No same-length path groups (3 paths) found")
|
||||
stats['Delta_files']['no_triples'].append(filename)
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Processing failed: {str(e)}")
|
||||
|
||||
def find_straight_lines(root):
|
||||
"""Find all straight line paths"""
|
||||
lines = []
|
||||
paths = root.xpath('.//svg:path|.//svg:g//svg:path',
|
||||
namespaces={'svg': 'http://www.w3.org/2000/svg'})
|
||||
|
||||
for i, path in enumerate(paths, 1):
|
||||
d = path.get('d', '').strip()
|
||||
if not d:
|
||||
continue
|
||||
|
||||
if is_straight_line(d):
|
||||
length, (p1, p2) = calculate_line_length(d)
|
||||
if length > 0:
|
||||
lines.append({
|
||||
'index': i,
|
||||
'element': path,
|
||||
'length': round(length, 4), # Keep 4 decimal places
|
||||
'p1': (round(p1[0], 2), round(p1[1], 2)), # Coordinates rounded to 2 decimals
|
||||
'p2': (round(p2[0], 2), round(p2[1], 2))
|
||||
})
|
||||
return lines
|
||||
|
||||
def group_lines_by_length(lines):
|
||||
"""Group straight paths by length"""
|
||||
groups = defaultdict(list)
|
||||
for line in lines:
|
||||
groups[line['length']].append(line)
|
||||
return groups
|
||||
|
||||
def find_target_path(lines, scale_factor, target_length):
|
||||
"""Find path that matches target length after scaling (within tolerance)"""
|
||||
for line in lines:
|
||||
scaled_length = line['length'] * scale_factor
|
||||
if abs(scaled_length - target_length) < MATCH_TOLERANCE:
|
||||
return line
|
||||
return None
|
||||
|
||||
def is_straight_line(d):
|
||||
"""Check if path is strictly a straight line"""
|
||||
commands = [cmd[0].upper() for cmd in re.findall('([A-Za-z])', d)]
|
||||
return len(commands) == 2 and commands[0] == 'M' and commands[1] == 'L'
|
||||
|
||||
def calculate_line_length(d):
|
||||
"""Calculate line length and return endpoints"""
|
||||
points = []
|
||||
for cmd, params in re.findall('([A-Za-z])([^A-Za-z]*)', d):
|
||||
if cmd.upper() in ('M', 'L'):
|
||||
coords = [float(p) for p in re.findall('[-+]?\d*\.\d+|[-+]?\d+', params)]
|
||||
points.append((coords[0], coords[1]))
|
||||
|
||||
if len(points) != 2:
|
||||
return 0, ((0,0), (0,0))
|
||||
|
||||
length = sqrt((points[1][0]-points[0][0])**2 + (points[1][1]-points[0][1])**2)
|
||||
return round(length, 4), (points[0], points[1]) # Length rounded to 4 decimals
|
||||
if __name__ == '__main__':
|
||||
# Set SVG files directory path
|
||||
# svg_directory = r'C:\Users\y.wang\Documents\SSG-Ruledesigner-Konfigurator\SVGs\Omniflo\work'
|
||||
svg_directory =os.environ.get('RD_CONF_WORK')
|
||||
process_svg_files(svg_directory)
|
||||
+7
-7
@@ -68,15 +68,15 @@ def normalize_stroke_widths2(root, scale):
|
||||
# Remove existing stroke-width
|
||||
del elem.attrib['stroke-width']
|
||||
# Apply scaled stroke width (e.g., 1px → 1/scale)
|
||||
elem.set('stroke-width', f'{1/scale:.6f}mm')
|
||||
elem.set('stroke-width', f'{1/scale:.6f}px')
|
||||
|
||||
def apply_non_scaling_stroke(root):
|
||||
"""确保所有有描边的元素的描边宽度不随缩放变化"""
|
||||
|
||||
for elem in root.iter():
|
||||
if 'stroke' in elem.attrib and elem.attrib['stroke'] != 'none':
|
||||
# 强制设置 stroke-width=1(无单位)
|
||||
# set stroke-width=1(no unit)
|
||||
elem.set('stroke-width', '1')
|
||||
# 确保 vector-effect 生效
|
||||
# set vector-effect
|
||||
elem.set('vector-effect', 'non-scaling-stroke')
|
||||
|
||||
def scale_svg_file(input_path: str, output_path: str):
|
||||
@@ -99,7 +99,7 @@ def scale_svg_file(input_path: str, output_path: str):
|
||||
if width > height:
|
||||
scale = 1000.0 / width
|
||||
new_width = 1000.0
|
||||
new_height = round(height * scale)
|
||||
new_height = round(height * scale,3)
|
||||
print(f"Scaling base: Width (larger dimension)")
|
||||
else:
|
||||
scale = 1000.0 / height
|
||||
@@ -110,8 +110,8 @@ def scale_svg_file(input_path: str, output_path: str):
|
||||
print(f"Scale factor: {scale:.6f}")
|
||||
print(f"New dimensions: {new_width:.3f}px × {new_height:.3f}px")
|
||||
print(f"ViewBox: 0 0 {new_width:.3f} {new_height:.3f}")
|
||||
# normalize_stroke_widths2(root, scale)
|
||||
apply_non_scaling_stroke(root)
|
||||
normalize_stroke_widths2(root, scale)
|
||||
#apply_non_scaling_stroke(root)
|
||||
#
|
||||
# Update SVG attributes
|
||||
root.set('viewBox', f'0 0 {new_width:.3f} {new_height:.3f}')
|
||||
+1
-1
@@ -155,6 +155,6 @@ def batch_process_svgs(input_dir: str, output_dir: str):
|
||||
|
||||
if __name__ == '__main__':
|
||||
input_dir = os.environ.get('RD_CONF_WORK')
|
||||
output_dir = os.environ.get('RD_CONF_OUTPUT')
|
||||
output_dir = os.environ.get('RD_CONF_OUTPUT_OFWEICHEN')
|
||||
# Example usage:
|
||||
batch_process_svgs(input_dir, output_dir)
|
||||
@@ -0,0 +1,114 @@
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
from shutil import copyfile
|
||||
|
||||
def process_svg_files(svg_folder, json_file_path):
|
||||
"""Process SVG files with '_M_' pattern to create '_P_' versions"""
|
||||
|
||||
# Load JSON data file
|
||||
try:
|
||||
with open(json_file_path, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
print("JSON data loaded successfully")
|
||||
except Exception as e:
|
||||
print(f"Error loading JSON file: {e}")
|
||||
return
|
||||
|
||||
# Process each SVG file in the directory
|
||||
for filename in os.listdir(svg_folder):
|
||||
if not filename.lower().endswith('.svg'):
|
||||
continue
|
||||
|
||||
# Skip files that already contain '_P_' pattern
|
||||
if '_P_' in filename:
|
||||
print(f"Skipping already processed file: {filename}")
|
||||
continue
|
||||
|
||||
# Only process files containing '_M_' pattern
|
||||
if '_M_' not in filename:
|
||||
print(f"Skipping non-target file (no '_M_' pattern): {filename}")
|
||||
continue
|
||||
|
||||
print(f"\nProcessing target file: {filename}")
|
||||
|
||||
# Extract SIVASNR from filename
|
||||
match = re.search(r'_M_(\d+)\.svg$', filename)
|
||||
if not match:
|
||||
print(f"Warning: Could not extract SIVASNR from filename: {filename}")
|
||||
continue
|
||||
|
||||
sivasnr = match.group(1)
|
||||
print(f"Extracted SIVASNR: {sivasnr}")
|
||||
|
||||
# Find matching item in JSON data
|
||||
matched_item = next((item for item in json_data
|
||||
if "Sivasnr" in item and str(item["Sivasnr"]) == sivasnr), None)
|
||||
|
||||
if not matched_item:
|
||||
print(f"No matching SIVASNR found in JSON - skipping: {sivasnr}")
|
||||
continue
|
||||
|
||||
profil_typ = matched_item.get("ProfilTyp", "")
|
||||
if not profil_typ:
|
||||
print(f"No ProfilTyp field found - skipping: {sivasnr}")
|
||||
continue
|
||||
|
||||
print(f"Found ProfilTyp: {profil_typ}")
|
||||
|
||||
# Find similar item (replace M with P)
|
||||
similar_profil_typ = profil_typ.replace(" MIT M", " MIT P")
|
||||
print(f"Searching for similar ProfilTyp: {similar_profil_typ}")
|
||||
|
||||
similar_item = next((item for item in json_data
|
||||
if item.get("ProfilTyp", "") == similar_profil_typ), None)
|
||||
|
||||
if not similar_item:
|
||||
print(f"No similar item found - skipping: {similar_profil_typ}")
|
||||
continue
|
||||
|
||||
similar_sivasnr = similar_item.get("Sivasnr")
|
||||
print(f"Found similar item SIVASNR: {similar_sivasnr}")
|
||||
|
||||
# Create new filename
|
||||
new_filename = filename.replace(f"_M_{sivasnr}", f"_P_{similar_sivasnr}")
|
||||
new_filepath = os.path.join(svg_folder, new_filename)
|
||||
print(f"Creating new file: {new_filename}")
|
||||
|
||||
try:
|
||||
# Copy and modify file
|
||||
copyfile(os.path.join(svg_folder, filename), new_filepath)
|
||||
|
||||
# Read and modify SVG content
|
||||
with open(new_filepath, 'r', encoding='utf-8') as f:
|
||||
svg_content = f.read()
|
||||
|
||||
modified_content = svg_content.replace('stroke="#ffe31b"', 'stroke="#1bff38"')
|
||||
|
||||
# Write modified content
|
||||
with open(new_filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(modified_content)
|
||||
|
||||
# Verify replacement
|
||||
if '#ffe31b' in modified_content:
|
||||
print("Warning: Original color still exists in output file")
|
||||
else:
|
||||
print("Color replacement successful")
|
||||
|
||||
print(f"Successfully created modified version: {new_filename}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error processing file: {e}")
|
||||
# Clean up if file creation failed
|
||||
if os.path.exists(new_filepath):
|
||||
os.remove(new_filepath)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Configure paths (update these with your actual paths)
|
||||
svg_folder = os.environ.get('RD_CONF_OUTPUT_OFWEICHEN')
|
||||
json_path = os.environ.get("JSON_PATH", "JSON")
|
||||
input_filename = os.path.join(json_path, "omniflo_weichen_output.json")
|
||||
process_svg_files(svg_folder, input_filename)
|
||||
print("Processing complete")
|
||||
@@ -0,0 +1,194 @@
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
from xml.etree import ElementTree as ET
|
||||
from xml.dom import minidom
|
||||
|
||||
def extract_sivasnr(filename):
|
||||
"""Extract numeric ID from filename"""
|
||||
match = re.search(r'(\d+)\.svg$', filename)
|
||||
return match.group(1) if match else None
|
||||
|
||||
def should_skip_stroke_width(element_attrib):
|
||||
"""Check if element should skip stroke-width setting"""
|
||||
# Check style attribute
|
||||
if 'style' in element_attrib:
|
||||
style = element_attrib['style'].lower()
|
||||
if 'stroke:none' in style and 'fill:none' in style:
|
||||
return True
|
||||
|
||||
# Check separate stroke and fill attributes
|
||||
stroke = element_attrib.get('stroke', '').lower()
|
||||
fill = element_attrib.get('fill', '').lower()
|
||||
return stroke == 'none' and fill == 'none'
|
||||
|
||||
def create_xml_structure(svg_root):
|
||||
"""Create target XML structure preserving all elements"""
|
||||
# Create base structure
|
||||
new_root = ET.Element("svg", xmlns="http://www.w3.org/2000/svg")
|
||||
g_layer = ET.SubElement(new_root, "g", transform="rotate(0)")
|
||||
|
||||
# Add inner SVG container
|
||||
inner_svg = ET.SubElement(g_layer, "svg", {
|
||||
"viewBox": svg_root.attrib.get("viewBox", "0 0 1000 1000"),
|
||||
"preserveAspectRatio": "none",
|
||||
"position": "absolute",
|
||||
"overflow": "visible"
|
||||
})
|
||||
|
||||
# Transfer all content
|
||||
for elem in svg_root:
|
||||
if elem.tag.endswith("}g"):
|
||||
# Process group with namespace
|
||||
new_g = ET.SubElement(inner_svg, "g", attrib={
|
||||
k: v for k, v in elem.attrib.items()
|
||||
if not k.startswith("xmlns")
|
||||
})
|
||||
|
||||
# Process all elements within group
|
||||
for child in elem:
|
||||
child_tag = child.tag.split("}")[-1] # Remove namespace
|
||||
child_attrib = {}
|
||||
|
||||
# Preserve all original attributes (except namespace)
|
||||
for k, v in child.attrib.items():
|
||||
if not k.startswith("xmlns"):
|
||||
child_attrib[k] = v
|
||||
|
||||
# Only add stroke-width if not stroke:none;fill:none
|
||||
if not should_skip_stroke_width(child.attrib):
|
||||
child_attrib["stroke-width"] = "1px"
|
||||
|
||||
# Create element with preserved attributes
|
||||
ET.SubElement(new_g, child_tag, attrib=child_attrib)
|
||||
|
||||
else:
|
||||
# Process standalone elements (path, circle, etc.)
|
||||
elem_tag = elem.tag.split("}")[-1] # Remove namespace
|
||||
elem_attrib = {}
|
||||
|
||||
# Preserve all original attributes (except namespace)
|
||||
for k, v in elem.attrib.items():
|
||||
if not k.startswith("xmlns"):
|
||||
elem_attrib[k] = v
|
||||
|
||||
# Only add stroke-width if not stroke:none;fill:none
|
||||
if not should_skip_stroke_width(elem.attrib):
|
||||
elem_attrib["stroke-width"] = "1px"
|
||||
|
||||
ET.SubElement(inner_svg, elem_tag, attrib=elem_attrib)
|
||||
|
||||
return new_root
|
||||
|
||||
def format_xml(element):
|
||||
"""Generate formatted XML string"""
|
||||
# Generate XML with declaration
|
||||
xml_str = ET.tostring(element, encoding="UTF-8", xml_declaration=True)
|
||||
|
||||
# Pretty format with 2-space indent
|
||||
dom = minidom.parseString(xml_str)
|
||||
pretty_xml = dom.toprettyxml(indent=" ", encoding="UTF-8").decode("UTF-8")
|
||||
|
||||
# Remove extra empty lines (preserve structure)
|
||||
lines = []
|
||||
for line in pretty_xml.split("\n"):
|
||||
if line.strip() or line.lstrip().startswith("</"):
|
||||
lines.append(line)
|
||||
return "\n".join(lines)
|
||||
|
||||
def convert_svg_to_xml(svg_path, output_dir):
|
||||
"""Convert SVG to target XML format"""
|
||||
sivasnr = extract_sivasnr(os.path.basename(svg_path))
|
||||
if not sivasnr:
|
||||
raise ValueError(f"Invalid filename format: {os.path.basename(svg_path)}")
|
||||
|
||||
# Parse original SVG
|
||||
try:
|
||||
tree = ET.parse(svg_path)
|
||||
svg_root = tree.getroot()
|
||||
except Exception as e:
|
||||
raise ValueError(f"SVG parsing error: {str(e)}")
|
||||
|
||||
# Build new structure
|
||||
new_xml = create_xml_structure(svg_root)
|
||||
formatted_xml = format_xml(new_xml)
|
||||
|
||||
# Ensure output directory exists
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
output_path = os.path.join(output_dir, f"{sivasnr}.xml")
|
||||
|
||||
# Write file (UTF-8 encoding)
|
||||
with open(output_path, "w", encoding="UTF-8") as f:
|
||||
f.write(formatted_xml)
|
||||
|
||||
return f"SSG/shapes/svg/{sivasnr}.xml"
|
||||
|
||||
def update_txt_file(txt_path, xml_rel_path):
|
||||
"""Update path in TXT file"""
|
||||
try:
|
||||
with open(txt_path, "r", encoding="UTF-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
if "srcSVG" not in data:
|
||||
raise ValueError("Missing srcSVG field")
|
||||
|
||||
data["srcSVG"] = xml_rel_path
|
||||
|
||||
with open(txt_path, "w", encoding="UTF-8") as f:
|
||||
json.dump(data, f, indent=4, ensure_ascii=False)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Update failed {os.path.basename(txt_path)}: {str(e)}")
|
||||
return False
|
||||
|
||||
def process_files(svg_dir, txt_dir, output_dir):
|
||||
"""Batch process files"""
|
||||
if not all(map(os.path.exists, [svg_dir, txt_dir])):
|
||||
raise FileNotFoundError("Input directory not found")
|
||||
|
||||
results = {"success": 0, "failed": 0}
|
||||
|
||||
for svg_file in os.listdir(svg_dir):
|
||||
if not svg_file.endswith(".svg"):
|
||||
continue
|
||||
|
||||
svg_path = os.path.join(svg_dir, svg_file)
|
||||
sivasnr = extract_sivasnr(svg_file)
|
||||
|
||||
if not sivasnr:
|
||||
print(f"Skipping invalid file: {svg_file}")
|
||||
results["failed"] += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
# Convert file
|
||||
xml_rel_path = convert_svg_to_xml(svg_path, output_dir)
|
||||
|
||||
# Update TXT
|
||||
txt_path = os.path.join(txt_dir, f"{sivasnr}.txt")
|
||||
if not os.path.exists(txt_path):
|
||||
raise FileNotFoundError(f"Corresponding TXT file not found: {sivasnr}.txt")
|
||||
|
||||
if update_txt_file(txt_path, xml_rel_path):
|
||||
print(f"Success: {svg_file} → {sivasnr}.xml")
|
||||
results["success"] += 1
|
||||
else:
|
||||
results["failed"] += 1
|
||||
|
||||
except Exception as e:
|
||||
print(f"Processing failed {svg_file}: {str(e)}")
|
||||
results["failed"] += 1
|
||||
|
||||
# Output report
|
||||
print(f"\nProcessing complete: {results['success']} succeeded, {results['failed']} failed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Configuration - modify these paths as needed
|
||||
SVG_INPUT_FOLDER = os.environ.get('RD_CONF_OUTPUT_OFWEICHEN') # Folder containing SVG files
|
||||
SVG_OUTPUT_FOLDER = os.environ.get("SVG_PATH","svg")
|
||||
PRORPS_FOLDER = os.environ.get("PROPS_PATH", "props") # Folder containing txt files
|
||||
|
||||
# Start processing
|
||||
process_files(SVG_INPUT_FOLDER, PRORPS_FOLDER, SVG_OUTPUT_FOLDER)
|
||||
print("\nProcessing complete.")
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user