Compare commits

...

3 Commits

5 changed files with 147 additions and 49 deletions
+6 -2
View File
@@ -84,7 +84,7 @@
]
},
{
"name": "draw cable dxf from easy.json to a new dxf",
"name": "draw cable dxf with copied layers from easy_todraw.json",
"type": "debugpy",
"request": "launch",
"program": "${file}",
@@ -93,7 +93,11 @@
"--filename",
"easy_todraw.json",
"--new",
"easy_cables"
"easy_cables.dxf",
"--copy_layer",
"easy_layer_copy.dxf",
"--origin",
"easy.dxf"
]
},
{
+6
View File
@@ -21,6 +21,12 @@ UNTERVERTEILER
[GetPos-Layer_Tunnel]
Busverteiler-Kennzeichnung
[GetPos-Layer_Equipment]
0-0-ILS_Eingang
0-0_A-Gruppe
MOTOR
# Maße des zur genauen Bestimmung der Mitte
# [GetPos-Geom-Unterverteiler]
# Breite = 320
+128 -40
View File
@@ -9,6 +9,8 @@ from datetime import datetime
from openpyxl import Workbook
import math
from collections import defaultdict
import configparser
@@ -40,54 +42,78 @@ def add_polyline(msp, points:Polyline, dxf_attribs):
pline = msp.add_lwpolyline(points=pts, dxfattribs=dxf_attribs)
pline.rgb = (255, 128, 0)
def new_dxf(json_file, out_path, dxf_file=False):
def new_dxf(plines, out_path):
""" creates a new dxf file with a polyline inside which is created by the given json file
"""
print("creating dxf ..")
anlage = model_from_json(json_file)
if dxf_file:
# bestehende DXF-Datei laden
doc = ezdxf.readfile(dxf_file)
else:
# neue Zeichnung im DXF format of AutoCAD 2010
doc = ezdxf.new('R2018', setup=True)
doc = ezdxf.new('R2018', setup=True)
create_cables(plines, doc)
# 2. Layer mit Zeitstempel erstellen (z.B. "Layer_2025-05-07_14-30")
timestamp = datetime.now().strftime("Kabel_%Y-%m-%d_%H-%M")
if timestamp not in doc.layers:
doc.layers.add(name=timestamp, color=7)
doc.saveas(out_path)
print("done")
# add new entities to the modelspace
msp = doc.modelspace()
# # Beispiel für Text und Polyline
# add_text(msp)
dxfattribs={"layer": timestamp}
for pl in anlage.kabel:
add_polyline(msp, pl, dxfattribs)
def modify_original_dxf(plines, originaldxf):
""" adds new layer to original .dxf-file that contains cables
"""
print("adding cables to original .dxf")
doc = ezdxf.readfile(originaldxf)
create_cables(plines, doc)
doc.saveas(out_path)
print("done")
def copy_layers_into_new(originaldxf, outpath):
""" creates a new dxf file with a racks, sensors, subdists from original file including cable paths
"""
print("copying layers from original .dxf into new .dxf")
quelle = ezdxf.readfile(originaldxf)
ziel = ezdxf.readfile(outpath)
copy_layers_into_dxf_by_filter(quelle, ziel)
create_cables(plines, quelle)
ziel.saveas(out_path)
print("done")
def create_cables(plines, doc):
msp = doc.modelspace()
# # Beispiel für Text und Polyline
# add_text(msp)
# Layer mit Zeitstempel erstellen (z.B. "Layer_2025-05-07_14-30")
timestamp = datetime.now().strftime("Kabel_%Y-%m-%d_%H-%M")
if timestamp not in doc.layers:
doc.layers.add(name=timestamp, color=7)
dxfattribs={"layer": timestamp}
for pl in plines.kabel:
add_polyline(msp, pl, dxfattribs)
def model_from_json(json_file):
with open(json_file, encoding='utf-8') as fh:
data = json.load(fh)
anlage = from_dict(
plines = from_dict(
data_class=Polylines,
data=data
)
return anlage
return plines
def export_excel(json_file, out_path):
# Hier für Excel Export
print("creating excel file ..")
anlage = model_from_json(json_file)
write_excel_from_json(anlage, out_path)
plines = model_from_json(json_file)
write_excel_from_json(plines, out_path)
print("done")
def write_excel_from_json(anlage:Polylines, outpath:str):
def write_excel_from_json(plines:Polylines, outpath:str):
wb = Workbook()
length_summary = defaultdict(int)
@@ -96,7 +122,7 @@ def write_excel_from_json(anlage:Polylines, outpath:str):
ws1.title = "Kabellängen"
ws1.append(["Kabel-ID", "Länge aus Json (m)", "Gerundete Länge (m)"])
for pl in anlage.kabel:
for pl in plines.kabel:
length = pl.length /1000 # Umrechnung von mm in m
rounded_len = math.ceil(length/10)*10
length_summary[rounded_len] +=1
@@ -122,43 +148,105 @@ def check_file_in_work(work_dir, filename):
mypath = filename
return (mypath, fexists)
def copy_layers_into_dxf_by_filter(dxf_source: ezdxf.document.Drawing, dxf_target:ezdxf.document.Drawing):
msp_source = dxf_source.modelspace()
msp_target = dxf_target.modelspace()
subdist_layers = list(config.items('GetPos-Layer_Distributors'))
rack_layers = list(config.items('GetPos-Layer_Racks'))
equipment_layers = list(config.items('GetPos-Layer_Equipment'))
tunnel_layers = list(config.items('GetPos-Layer_Tunnel'))
layernames = list()
layernames.extend(subdist_layers)
layernames.extend(rack_layers)
layernames.extend(equipment_layers)
layernames.extend(tunnel_layers)
for (layername,v) in layernames:
if layername not in dxf_source.layers:
continue
# Falls der Layer noch nicht im Zieldokument existiert, neu anlegen
if layername not in dxf_target.layers:
quelle_layer = dxf_source.layers.get(layername)
dxf_target.layers.add(
name=layername,
color=quelle_layer.color,
linetype=quelle_layer.dxf.linetype,
lineweight=quelle_layer.dxf.lineweight
)
# Alle Entities auf diesem Layer kopieren
for entity in msp_source.query(f"*[layer=='{layername}']"):
msp_target.add_entity(entity.copy())
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='draws a dxf file with the given cable coordinates', prog='drawdxf')
parser.add_argument('-f', '--filename', action='store', required=True, help='this json file contains all cables and its coordinates which should be drawn. Saved with an unique timestamp', metavar='myfile.json')
parser.add_argument('-d', '--dxf', action='store', help='this dxf drawing will be copied and the new layer with the cables will be added', metavar='myfile.dxf')
parser.add_argument('-n', '--new', action='store', help='create a new dxf file with cables in it. Name is basename and a timestamp')
parser.add_argument('-d', '--dxf', action='store', help='this dxf drawing will be copied and the new layer with the cables will be added. Original file must be added with --origin', metavar='myfile.dxf')
parser.add_argument('-c', '--copy_layer', action='store', help='copy layers of racks, sensors, distributors into a new .dxf-file. File also contains cable paths. Original file must be added with --origin', metavar='original.dxf')
parser.add_argument('-n', '--new', action='store', help='create a new dxf file only with cables in it. Name is basename and a timestamp')
parser.add_argument('-x', '--excel', action='store', help='create a xlsx file with cables data', metavar='allCables.xls')
parser.add_argument('-o', '--origin', action='store', help='name of original .dxf file used by -d and -a', metavar='original.dxf')
args = parser.parse_args()
config_dir = os.environ.get("PROJECT_CFG")
work_dir = os.fspath(os.environ.get('PROJECT_WORK'))
jfile = args.filename
(json_path, jexists) = check_file_in_work(work_dir, jfile)
json_file = args.filename
(json_path, jexists) = check_file_in_work(work_dir, json_file)
if not jexists:
print("file %s does not exit", jfile)
print(f"file {json_file} does not exist")
parser.print_help()
exit()
plines = model_from_json(json_path)
config = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config.optionxform = lambda option: option # preserve case for letters
config.read(os.path.join(config_dir, "allgemein.cfg"))
dxf_file = args.dxf
if args.dxf or args.copy_layer:
if not args.origin:
parser.print_help()
exit()
else:
(origin_path, dexists) = check_file_in_work(work_dir, args.origin)
if args.dxf:
# falls ein neuer Layer hinzu gefügt werden soll
dxf_file = args.dxf
(dxf_path, dexists) = check_file_in_work(work_dir, dxf_file)
if not dexists:
print("file %s does not exit", dxf_file)
print(f"file {dxf_file} does not exist")
parser.print_help()
exit()
out_path = dxf_path
res_pos = new_dxf(json_path, out_path, dxf_file=dxf_path)
else:
# erzeuge eine neue dxf Datei mit aktuellen Zeitstempel im Namen
#basename = os.path.splitext(dxf_path)[0]
#timestamp = datetime.now().strftime(basename+"_%Y%m%d-%H%M%S.dxf")
#timestamp = datetime.now().strftime("%Y%m%d-%H%M%S.dxf")
res_pos = new_dxf(plines, dxf_path)
if args.copy_layer:
out_path = os.path.join(work_dir, args.copy_layer)
res_pos = new_dxf(plines, out_path)
copy_layers_into_new(origin_path, out_path)
if args.new:
# erzeuge dxf Datei nur mit Kabeln
out_path = os.path.join(work_dir, args.new)
res_pos = new_dxf(json_path, out_path)
res_pos = new_dxf(plines, out_path)
if args.excel:
excel_path = os.path.join(work_dir, args.excel)
export_excel(json_path, excel_path)
+6 -6
View File
@@ -70,8 +70,8 @@ def get_input_positions(msp: ezdxf.document.Drawing.modelspace):
pos = attrib.dxf.insert #Position Ecke unten links von "x"-Marker auslesen
# Hoehe und Breite von "x" addieren, um Mittelpunkt zu finden
breite_marker = config.getfloat("Sensor_Marker", "Breite")
hoehe_marker = config.getfloat("Sensor_Marker", "Hoehe")
breite_marker = config.getfloat("GetPos-Geom-Sensor", "Breite")
hoehe_marker = config.getfloat("GetPos-Geom-Sensor", "Hoehe")
pos_midx = pos.x + breite_marker*0.5
pos_midy = pos.y + hoehe_marker*0.5
@@ -143,7 +143,7 @@ def get_subdistributor_positions(msp, dist2sensors):
ret = dict()
# Alle Texte auf Layer "xy"
all_distributors = dist2sensors.keys()
all_layers = config.items('Layer_Busverteiler')
all_layers = config.items('GetPos-Layer_Distributors')
for (layer,v) in all_layers:
for distname in all_distributors:
selectstr = f'MTEXT[layer=="{layer}"]'
@@ -165,7 +165,7 @@ def get_tunnel_positions(msp):
allTunnels = dict()
tunnel_length = dict()
# Alle Text mit "Tunnel" als Inhalt auf Layer "xy"
all_layers = config.items('Layer_Tunnel')
all_layers = config.items('GetPos-Layer_Tunnel')
for (layer,v) in all_layers:
selectstr = f'MTEXT[layer=="{layer}"]'
for text in msp.query(selectstr):
@@ -209,7 +209,7 @@ def get_rack_positions(msp):
ret = dict()
rack_counter = 1 #Zaehler für Rack Nummerierung
all_layers = list(config.items('Layer_Pritschen'))
all_layers = list(config.items('GetPos-Layer_Racks'))
for (layer,v) in all_layers:
selectstr = f'LWPOLYLINE[layer=="{layer}"]'
for e in msp.query(selectstr):
@@ -286,7 +286,7 @@ if __name__ == '__main__':
config = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config.optionxform = lambda option: option # preserve case for letters
config.read(os.path.join(config_dir, "getpositions.cfg"))
config.read(os.path.join(config_dir, "allgemein.cfg"))
output_results = dict()
if args.sensors:
+1 -1
View File
@@ -166,7 +166,7 @@ if __name__ == "__main__":
config = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config.optionxform = lambda option: option # preserve case for letters
config.read(os.path.join(config_dir, "routing.cfg"))
config.read(os.path.join(config_dir, "allgemein.cfg"))
# virtuelle Anlage erstellen