Files
kabellaengen/lib/drawdxf.py
T

165 lines
5.1 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import argparse
import ezdxf
import json
import os.path
from dataclasses import dataclass, asdict, fields
from dacite import from_dict
from typing import List
from datetime import datetime
from openpyxl import Workbook
import math
from collections import defaultdict
@dataclass
class Point:
x: float
y: float
@dataclass
class Polyline:
id: str
coords: List[Point]
length: float
def to_tuple(self):
ret = list()
for p in self.coords:
ret.append( (p.x,p.y) )
return ret
@dataclass
class Polylines:
kabel: List[Polyline]
def add_polyline(msp, points:Polyline, dxf_attribs):
pts = points.to_tuple()
pline = msp.add_lwpolyline(points=pts, dxfattribs=dxf_attribs)
pline.rgb = (255, 128, 0)
def new_dxf(json_file, out_path, dxf_file=False):
""" 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)
# 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)
# 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)
doc.saveas(out_path)
print("done")
def model_from_json(json_file):
with open(json_file, encoding='utf-8') as fh:
data = json.load(fh)
anlage = from_dict(
data_class=Polylines,
data=data
)
return anlage
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)
print("done")
def write_excel_from_json(anlage:Polylines, outpath:str):
wb = Workbook()
length_summary = defaultdict(int)
#Worksheet 1 - Kabellängen
ws1 = wb.active
ws1.title = "Kabellängen"
ws1.append(["Kabel-ID", "Länge aus Json (m)", "Gerundete Länge (m)"])
for pl in anlage.kabel:
length = pl.length /1000 # Umrechnung von mm in m
rounded_len = math.ceil(length/10)*10
length_summary[rounded_len] +=1
ws1.append([pl.id, length, int(rounded_len)])
# Worksheet 2 - Zusammengefasste Längen
ws2 = wb.create_sheet("Längenübersicht")
ws2.append(["Gerundete Länge (m)", "Anzahl Kabel"])
for rlength in sorted(length_summary):
ws2.append([int(rlength), length_summary[rlength]])
wb.save(outpath)
def check_file_in_work(work_dir, filename):
fexists = True
if not os.path.exists(filename):
mypath = os.path.join(work_dir, filename)
if not os.path.exists(mypath):
fexists = False
else:
mypath = filename
return (mypath, fexists)
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('-x', '--excel', action='store', help='create a xlsx file with cables data', metavar='allCables.xls')
args = parser.parse_args()
work_dir = os.fspath(os.environ.get('PROJECT_WORK'))
jfile = args.filename
(json_path, jexists) = check_file_in_work(work_dir, jfile)
if not jexists:
print("file %s does not exit", jfile)
parser.print_help()
exit()
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)
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")
out_path = os.path.join(work_dir, args.new)
res_pos = new_dxf(json_path, out_path)
if args.excel:
excel_path = os.path.join(work_dir, args.excel)
export_excel(json_path, excel_path)