Neuer Schalter für drawdxf. Anpassung der config aufrufe in routing und getpositions

This commit is contained in:
2025-05-28 16:51:22 +02:00
parent 22767d11d3
commit 7772981870
4 changed files with 140 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", "type": "debugpy",
"request": "launch", "request": "launch",
"program": "${file}", "program": "${file}",
@@ -93,7 +93,11 @@
"--filename", "--filename",
"easy_todraw.json", "easy_todraw.json",
"--new", "--new",
"easy_cables" "easy_cables.dxf",
"--copy_layer",
"easy_layer_copy.dxf",
"--origin",
"easy.dxf"
] ]
}, },
{ {
+124 -37
View File
@@ -9,6 +9,8 @@ from datetime import datetime
from openpyxl import Workbook from openpyxl import Workbook
import math import math
from collections import defaultdict 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 = msp.add_lwpolyline(points=pts, dxfattribs=dxf_attribs)
pline.rgb = (255, 128, 0) 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 """ creates a new dxf file with a polyline inside which is created by the given json file
""" """
print("creating dxf ..") print("creating dxf ..")
anlage = model_from_json(json_file)
if dxf_file: doc = ezdxf.new('R2018', setup=True)
# bestehende DXF-Datei laden create_cables(plines, doc)
doc = ezdxf.readfile(dxf_file)
else:
# neue Zeichnung im DXF format of AutoCAD 2010
doc = ezdxf.new('R2018', setup=True)
# 2. Layer mit Zeitstempel erstellen (z.B. "Layer_2025-05-07_14-30") doc.saveas(out_path)
print("done")
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") timestamp = datetime.now().strftime("Kabel_%Y-%m-%d_%H-%M")
if timestamp not in doc.layers: if timestamp not in doc.layers:
doc.layers.add(name=timestamp, color=7) doc.layers.add(name=timestamp, color=7)
# add new entities to the modelspace
msp = doc.modelspace()
# # Beispiel für Text und Polyline
# add_text(msp)
dxfattribs={"layer": timestamp} dxfattribs={"layer": timestamp}
for pl in anlage.kabel: for pl in plines.kabel:
add_polyline(msp, pl, dxfattribs) add_polyline(msp, pl, dxfattribs)
doc.saveas(out_path)
print("done")
def model_from_json(json_file): def model_from_json(json_file):
with open(json_file, encoding='utf-8') as fh: with open(json_file, encoding='utf-8') as fh:
data = json.load(fh) data = json.load(fh)
anlage = from_dict( plines = from_dict(
data_class=Polylines, data_class=Polylines,
data=data data=data
) )
return anlage return plines
def export_excel(json_file, out_path): def export_excel(json_file, out_path):
# Hier für Excel Export # Hier für Excel Export
print("creating excel file ..") print("creating excel file ..")
anlage = model_from_json(json_file) plines = model_from_json(json_file)
write_excel_from_json(anlage, out_path) write_excel_from_json(plines, out_path)
print("done") print("done")
def write_excel_from_json(anlage:Polylines, outpath:str): def write_excel_from_json(plines:Polylines, outpath:str):
wb = Workbook() wb = Workbook()
length_summary = defaultdict(int) length_summary = defaultdict(int)
@@ -96,7 +122,7 @@ def write_excel_from_json(anlage:Polylines, outpath:str):
ws1.title = "Kabellängen" ws1.title = "Kabellängen"
ws1.append(["Kabel-ID", "Länge aus Json (m)", "Gerundete Länge (m)"]) 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 length = pl.length /1000 # Umrechnung von mm in m
rounded_len = math.ceil(length/10)*10 rounded_len = math.ceil(length/10)*10
length_summary[rounded_len] +=1 length_summary[rounded_len] +=1
@@ -113,6 +139,9 @@ def write_excel_from_json(anlage:Polylines, outpath:str):
def check_file_in_work(work_dir, filename): def check_file_in_work(work_dir, filename):
print("workdir", work_dir)
print("filename:", filename)
fexists = True fexists = True
if not os.path.exists(filename): if not os.path.exists(filename):
mypath = os.path.join(work_dir, filename) mypath = os.path.join(work_dir, filename)
@@ -122,43 +151,101 @@ def check_file_in_work(work_dir, filename):
mypath = filename mypath = filename
return (mypath, fexists) 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'))
layernames = list()
layernames.extend(subdist_layers)
layernames.extend(rack_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__': if __name__ == '__main__':
parser = argparse.ArgumentParser(description='draws a dxf file with the given cable coordinates', prog='drawdxf') 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('-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('-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('-n', '--new', action='store', help='create a new dxf file with cables in it. Name is basename and a timestamp') 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('-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() args = parser.parse_args()
config_dir = os.environ.get("PROJECT_CFG")
work_dir = os.fspath(os.environ.get('PROJECT_WORK')) work_dir = os.fspath(os.environ.get('PROJECT_WORK'))
jfile = args.filename json_file = args.filename
(json_path, jexists) = check_file_in_work(work_dir, jfile) (json_path, jexists) = check_file_in_work(work_dir, json_file)
if not jexists: if not jexists:
print("file %s does not exit", jfile) print(f"file {json_file} does not exist")
parser.print_help() parser.print_help()
exit() exit()
print(json_path)
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: 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) (dxf_path, dexists) = check_file_in_work(work_dir, dxf_file)
if not dexists: if not dexists:
print("file %s does not exit", dxf_file) print(f"file {dxf_file} does not exist")
parser.print_help() parser.print_help()
exit() exit()
out_path = dxf_path out_path = dxf_path
res_pos = new_dxf(json_path, out_path, dxf_file=dxf_path) res_pos = new_dxf(plines, dxf_path)
else:
# erzeuge eine neue dxf Datei mit aktuellen Zeitstempel im Namen if args.copy_layer:
#basename = os.path.splitext(dxf_path)[0]
#timestamp = datetime.now().strftime(basename+"_%Y%m%d-%H%M%S.dxf") out_path = os.path.join(work_dir, args.copy_layer)
#timestamp = datetime.now().strftime("%Y%m%d-%H%M%S.dxf") 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) 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: if args.excel:
excel_path = os.path.join(work_dir, args.excel) excel_path = os.path.join(work_dir, args.excel)
export_excel(json_path, excel_path) 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 pos = attrib.dxf.insert #Position Ecke unten links von "x"-Marker auslesen
# Hoehe und Breite von "x" addieren, um Mittelpunkt zu finden # Hoehe und Breite von "x" addieren, um Mittelpunkt zu finden
breite_marker = config.getfloat("Sensor_Marker", "Breite") breite_marker = config.getfloat("GetPos-Geom-Sensor", "Breite")
hoehe_marker = config.getfloat("Sensor_Marker", "Hoehe") hoehe_marker = config.getfloat("GetPos-Geom-Sensor", "Hoehe")
pos_midx = pos.x + breite_marker*0.5 pos_midx = pos.x + breite_marker*0.5
pos_midy = pos.y + hoehe_marker*0.5 pos_midy = pos.y + hoehe_marker*0.5
@@ -143,7 +143,7 @@ def get_subdistributor_positions(msp, dist2sensors):
ret = dict() ret = dict()
# Alle Texte auf Layer "xy" # Alle Texte auf Layer "xy"
all_distributors = dist2sensors.keys() all_distributors = dist2sensors.keys()
all_layers = config.items('Layer_Busverteiler') all_layers = config.items('GetPos-Layer_Distributors')
for (layer,v) in all_layers: for (layer,v) in all_layers:
for distname in all_distributors: for distname in all_distributors:
selectstr = f'MTEXT[layer=="{layer}"]' selectstr = f'MTEXT[layer=="{layer}"]'
@@ -165,7 +165,7 @@ def get_tunnel_positions(msp):
allTunnels = dict() allTunnels = dict()
tunnel_length = dict() tunnel_length = dict()
# Alle Text mit "Tunnel" als Inhalt auf Layer "xy" # 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: for (layer,v) in all_layers:
selectstr = f'MTEXT[layer=="{layer}"]' selectstr = f'MTEXT[layer=="{layer}"]'
for text in msp.query(selectstr): for text in msp.query(selectstr):
@@ -209,7 +209,7 @@ def get_rack_positions(msp):
ret = dict() ret = dict()
rack_counter = 1 #Zaehler für Rack Nummerierung 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: for (layer,v) in all_layers:
selectstr = f'LWPOLYLINE[layer=="{layer}"]' selectstr = f'LWPOLYLINE[layer=="{layer}"]'
for e in msp.query(selectstr): for e in msp.query(selectstr):
@@ -286,7 +286,7 @@ if __name__ == '__main__':
config = configparser.ConfigParser(allow_no_value=True, delimiters=("=")) config = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config.optionxform = lambda option: option # preserve case for letters 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() output_results = dict()
if args.sensors: if args.sensors:
+1 -1
View File
@@ -166,7 +166,7 @@ if __name__ == "__main__":
config = configparser.ConfigParser(allow_no_value=True, delimiters=("=")) config = configparser.ConfigParser(allow_no_value=True, delimiters=("="))
config.optionxform = lambda option: option # preserve case for letters 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 # virtuelle Anlage erstellen