Compare commits
3 Commits
22767d11d3
...
e7612c15fa
| Author | SHA1 | Date | |
|---|---|---|---|
| e7612c15fa | |||
| 2d09cecbc9 | |||
| 7772981870 |
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",
|
||||
"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"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user