Neuer Schalter für drawdxf. Anpassung der config aufrufe in routing und getpositions
This commit is contained in:
Vendored
+6
-2
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user