Compare commits

...

11 Commits

Author SHA1 Message Date
n3040
eabb62f8f5 提交Makefile和ui文件 2023-01-27 11:52:16 +08:00
n3040
475ce6c367 修复了第一个塔不是耐张塔时计算累加高差和档距的bug。 2023-01-26 03:43:36 +08:00
n3040
034ba492c7 1.考虑中间有耐张塔时画后侧耐张串时没有重新计算张力的问题。
2.完成了考虑中间有耐张塔的情况。
2023-01-26 03:07:57 +08:00
n3040
2109957df1 准备解决中间有耐张段的情况。 2023-01-26 02:03:23 +08:00
n3040
ce1ff065d1 1.添加注意事项。
2.判断dwg文件是否存在。
3.添加了error。
2022-08-26 17:30:42 +08:00
n3040
64973f9df5 1.杆塔换成了青色。 2022-08-13 17:06:36 +08:00
n3040
2c0c013b73 1.塔呼高可以有小数。 2022-08-06 23:08:32 +08:00
n3040
0dc1f3e153 1.修复画代表档距不正确的一个bug。
2.基本能用于孤立档。
2022-07-29 12:34:44 +08:00
n3040
462599b41d 1.增加了画代表档距。 2022-07-28 19:58:35 +08:00
n3040
bd43894598 1.修复了耐张段代表档距更新的bug。 2022-07-27 22:55:44 +08:00
n3040
8ae1499114 1.增加了画档距的功能。 2022-07-26 18:22:28 +08:00
6 changed files with 539 additions and 154 deletions

2
Makefile Normal file
View File

@@ -0,0 +1,2 @@
generate_ui:
pyuic6 ui/mainwindow.ui -o ui/mainwindow.py

580
PWFile.py
View File

@@ -1,11 +1,9 @@
import math
import os.path import os.path
from collections import OrderedDict from collections import OrderedDict
import re import re
import attrs import attrs
import pandas as pd import pandas as pd
from attrs import define
from tkinter.messagebox import NO
import xlwings as xw import xlwings as xw
from Apyautocad import Apyautocad, APoint from Apyautocad import Apyautocad, APoint
import os import os
@@ -13,6 +11,17 @@ import numpy as np
from time import sleep from time import sleep
from attrs import define from attrs import define
from typing import List from typing import List
import error
from array import array
def get_layer_if_not_exist_create_it(doc, layer_name):
layers = doc.Layers
for foo in range(layers.Count):
layer = layers.Item(foo)
if layer.Name == layer_name:
return layer
return layers.Add(layer_name)
@define @define
@@ -21,14 +30,14 @@ class SEntry:
tower_height: float = 0 tower_height: float = 0
tower_type: str = "" tower_type: str = ""
mileage_in_s: int = 0 mileage_in_s: int = 0
back_k: float = 0 back_k: float = 0 # 杆塔后侧的k值
forth_k: float = 0 forth_k: float = 0 # 杆塔前侧的k值
altitude_off: float = 0 # 中心桩高差 altitude_off: float = 0 # 中心桩高差
foundation_low: float = 0 # 基降 foundation_low: float = 0 # 基降
fitting: str = "" # 金具 fitting: str = "" # 金具
is_tension_tower: bool = False is_tension_tower: bool = False # 是否为耐张塔
back_representive_span: float = 0 # 代表档距 back_representive_span: float = 0 # 后侧代表档距
forth_representive_span: float = 0 # 代表档距 forth_representive_span: float = 0 # 前侧代表档距
class SFile: class SFile:
@@ -51,7 +60,7 @@ class SFile:
if "首端转角号" in norm_line: if "首端转角号" in norm_line:
new_k = float(norm_line.split(":")[-1].replace("E", "e")) # 模板系数 new_k = float(norm_line.split(":")[-1].replace("E", "e")) # 模板系数
new_reprtv_span = float( new_reprtv_span = float(
re.findall("代表档距 : (\d+) 模板系数", norm_line)[0] re.findall(r"代表档距 : {2}(\d+) {3}模板系数", norm_line)[0]
) # 代表档距 ) # 代表档距
continue continue
if "塔号" in norm_line: if "塔号" in norm_line:
@@ -59,11 +68,16 @@ class SFile:
if last_tower_name != "": if last_tower_name != "":
tower_dic[last_tower_name].is_tension_tower = True tower_dic[last_tower_name].is_tension_tower = True
continue continue
norm_entry = re.sub("\s+", ",", norm_line) norm_entry = re.sub(r"\s+", ",", norm_line)
sep_entry = norm_entry.split(",") sep_entry = norm_entry.split(",")
tower_name = sep_entry[0] tower_name = sep_entry[0]
if tower_name in tower_dic: if tower_name in tower_dic:
tower_dic[tower_name].forth_k = new_k # 更新耐张塔前侧k值。 tower_dic[tower_name].forth_k = new_k # 更新耐张塔前侧k值。
tower_dic[
tower_name
].forth_representive_span = new_reprtv_span # 更新耐张塔前侧代表档距。
last_k = tower_dic[tower_name].forth_k
last_reprtv_span = tower_dic[tower_name].forth_representive_span
continue continue
s_entry = SEntry() s_entry = SEntry()
s_entry.tower_name = tower_name s_entry.tower_name = tower_name
@@ -87,7 +101,7 @@ class SFile:
@define @define
class Fitting: class Fitting: # 金具
fitting_length_dic = {} fitting_length_dic = {}
def __init__(self, fitting_file_path): def __init__(self, fitting_file_path):
@@ -111,6 +125,8 @@ class ColorEnume:
wire_color_rgb = [122, 219, 245] wire_color_rgb = [122, 219, 245]
tree_color_rgb = [240, 226, 81] tree_color_rgb = [240, 226, 81]
ground_color_rgb = [82, 79, 254] ground_color_rgb = [82, 79, 254]
span_text_color_rgb = [140, 245, 236]
representive_span_text_color_rgb = [255, 172, 75]
# 读取Z文件找到Z断面第一个点的坐标 # 读取Z文件找到Z断面第一个点的坐标
@@ -134,7 +150,7 @@ def deduce_fit_db_from_cad_path(cad_file_path):
return os.path.join(dwg_file_name[0], "Fit.db") return os.path.join(dwg_file_name[0], "Fit.db")
def curve_fun(x, span, k, gaocha): def curve_fun(x, span, k, gaocha): # 弧垂公式
return x * gaocha / span - x * (span - x) * k return x * gaocha / span - x * (span - x) * k
@@ -143,11 +159,8 @@ def np2d_to_array(np2d): # 把2维numpy数组转换成cad可以用的数组
return t[0] return t[0]
@define
class StringImpactExcel: class StringImpactExcel:
def __init__(self) -> None:
# self._wb=None
pass
def read(self, wb, gaocha, span, tension): def read(self, wb, gaocha, span, tension):
pos代表档距 = "F13" pos代表档距 = "F13"
pos档距 = "L13" pos档距 = "L13"
@@ -159,7 +172,6 @@ class StringImpactExcel:
sheet.range(pos档距).value = span sheet.range(pos档距).value = span
sheet.range(pos张力).value = tension sheet.range(pos张力).value = tension
string_length = sheet.range(pos总串长).value string_length = sheet.range(pos总串长).value
# print(sheet.range("V25:V46").value)
x = np.linspace(string_length, span, int(span / 5), endpoint=True) x = np.linspace(string_length, span, int(span / 5), endpoint=True)
x[0] = sheet.range("E23").value x[0] = sheet.range("E23").value
x[1] = sheet.range("E24").value x[1] = sheet.range("E24").value
@@ -170,59 +182,112 @@ class StringImpactExcel:
return (x, y) return (x, y)
def set_true_color(object, r, g, b): def set_true_color(object, r_or_rgb_list, g=0, b=0):
true_color = object.TrueColor true_color = object.TrueColor
true_color.SetRGB(r, g, b) if type(r_or_rgb_list) == List or type(r_or_rgb_list) == list:
true_color.SetRGB(*r_or_rgb_list)
else:
true_color.SetRGB(r_or_rgb_list, g, b)
object.TrueColor = true_color object.TrueColor = true_color
@define
class StringImpactExcelRecord:
from_tower_name: str = ""
fo_tower_name: str = ""
representive_span: float = 0 # 代表档距
span: float = 0
tension: float = 0
gaocha: float = 0
@define @define
class StringImpactPlate: class StringImpactPlate:
_dwg_file_path: str _dwg_file_path: str
_s_file_path: str _s_file_path: str
_draw_start_tower_name: str _draw_start_tower_name: str
_draw_end_tower_name: str
_continouse_tension_excel: str _continouse_tension_excel: str
_string_impact_curve_excel: str _string_impact_curve_excel: str
_cad: None _cad: None
excel_record_list: List = [] # 记录对excel的操作
def _find_target_tower_index(self, start_tower_name: str, tower_dict): def _find_target_tower_index(
self, start_tower_name: str, end_tower_name, tower_dict
):
# 从 start_tower_name开始寻找一个耐张段
index = [] index = []
tower_key_list = list(tower_dict.keys()) tower_key_list = list(tower_dict.keys())
index.append(tower_key_list.index(start_tower_name)) try:
can_start_find = False index_of_first_tower = tower_key_list.index(start_tower_name)
for tower_key in tower_key_list: if (
# index.append(start_tower_name.index(foo)) tower_dict[tower_key_list[index_of_first_tower]].is_tension_tower
tower_info = tower_dict[tower_key] == True
if tower_info.tower_name == start_tower_name: ):
can_start_find = True index.append(index_of_first_tower)
continue except ValueError: # 没找到第一个塔,就直接返回
if can_start_find and tower_info.is_tension_tower == True: return index
found_tower_name = tower_info.tower_name try:
index.append(tower_key_list.index(found_tower_name)) index_of_last_tower = tower_key_list.index(end_tower_name)
break # 开始补充第一个和最后一个直接的耐张塔
for index_of_tension_tower in range(
index_of_first_tower + 1, index_of_last_tower
):
if (
tower_dict[tower_key_list[index_of_tension_tower]].is_tension_tower
== True
):
index.append(index_of_tension_tower)
if tower_dict[tower_key_list[index_of_last_tower]].is_tension_tower == True:
index.append(index_of_last_tower)
except ValueError: # 没找到最后一个塔,就只画一个耐张段
for index_of_tension_tower in range(
index_of_first_tower + 1, len(tower_key_list)
):
if (
tower_dict[tower_key_list[index_of_tension_tower]].is_tension_tower
== True
):
index.append(index_of_tension_tower)
break
# can_start_find = False
# for tower_key in tower_key_list:
# tower_info = tower_dict[tower_key]
# if tower_info.tower_name == start_tower_name:
# can_start_find = True
# continue
# if can_start_find and tower_info.is_tension_tower == True:
# found_tower_name = tower_info.tower_name
# index.append(tower_key_list.index(found_tower_name))
# break
return index return index
def _plot(self, cad, plot_x, plot_y): def _plot(self, cad, plot_x, plot_y):
custom_layer = get_layer_if_not_exist_create_it(cad.doc, "123custom_layer")
plot_vector = np2d_to_array(np.hstack((plot_x, plot_y))) plot_vector = np2d_to_array(np.hstack((plot_x, plot_y)))
added_curve = cad.model.AddPolyLine(plot_vector) added_curve = cad.model.AddPolyLine(plot_vector)
added_curve.Layer = custom_layer.Name
set_true_color(added_curve, *ColorEnume.wire_color_rgb) set_true_color(added_curve, *ColorEnume.wire_color_rgb)
plot_ground_y = plot_y - 18 * 2 # TODO 应该读规程的
plot_ground_y = plot_y - 16 * 2
plot_ground_vector = np2d_to_array(np.hstack((plot_x, plot_ground_y))) plot_ground_vector = np2d_to_array(np.hstack((plot_x, plot_ground_y)))
added_ground_curve = cad.model.AddPolyLine(plot_ground_vector) added_ground_curve = cad.model.AddPolyLine(plot_ground_vector)
added_ground_curve.Layer = custom_layer.Name
set_true_color(added_ground_curve, *ColorEnume.ground_color_rgb) set_true_color(added_ground_curve, *ColorEnume.ground_color_rgb)
plot_tree_y = plot_y - 13.5 * 2 plot_tree_y = plot_y - 13.5 * 2
plot_tree_vector = np2d_to_array(np.hstack((plot_x, plot_tree_y))) plot_tree_vector = np2d_to_array(np.hstack((plot_x, plot_tree_y)))
added_tree_curve = cad.model.AddPolyLine(plot_tree_vector) added_tree_curve = cad.model.AddPolyLine(plot_tree_vector)
added_tree_curve.Layer = custom_layer.Name
set_true_color(added_tree_curve, *ColorEnume.tree_color_rgb) set_true_color(added_tree_curve, *ColorEnume.tree_color_rgb)
def _draw_action(self, excel_app, cad): def _draw_action(self, excel_app, cad):
# 计算代表档距 # TODO 计算代表档距
s_file = SFile() s_file = SFile()
s_file.open(self._s_file_path) s_file.open(self._s_file_path)
tower_dict = s_file.tower_dic tower_dict = s_file.tower_dic
tower_key_list = list(tower_dict.keys()) tower_key_list = list(tower_dict.keys())
draw_tower_index = self._find_target_tower_index( draw_tower_indexes = self._find_target_tower_index(
self._draw_start_tower_name, tower_dict self._draw_start_tower_name, self._draw_end_tower_name, tower_dict
) )
fitting_file_path = deduce_fit_db_from_cad_path(self._dwg_file_path) fitting_file_path = deduce_fit_db_from_cad_path(self._dwg_file_path)
fitting = Fitting(fitting_file_path) fitting = Fitting(fitting_file_path)
@@ -233,82 +298,227 @@ class StringImpactPlate:
wb_string_impact = excel_app.books.open(self._string_impact_curve_excel) wb_string_impact = excel_app.books.open(self._string_impact_curve_excel)
stringImpactExcel = StringImpactExcel() stringImpactExcel = StringImpactExcel()
sleep(1) sleep(1)
draw_first_tower_key = tower_key_list[draw_tower_index[0]] for draw_tower_index in draw_tower_indexes:
first_tower_info = tower_dict[draw_first_tower_key] draw_tower_key = tower_key_list[draw_tower_index]
forth_reprtv_span = first_tower_info.forth_representive_span tower_info: SEntry = tower_dict[draw_tower_key]
continouse_sheet.range("B69").value = forth_reprtv_span if draw_tower_index < tower_key_list.index(
high_temperature_tension = continouse_sheet.range("L69").value self._draw_end_tower_name
forth_tower_info = tower_dict[tower_key_list[draw_tower_index[0] + 1]] ): # 不是最后一个,或者只有第一个。
gaocha_of_first_tower = ( # 画前侧
( forth_reprtv_span = tower_info.forth_representive_span
forth_tower_info.tower_height continouse_sheet.range("B69").value = forth_reprtv_span
- forth_tower_info.foundation_low high_temperature_tension = continouse_sheet.range("L69").value
- fitting.fitting_length_dic[forth_tower_info.fitting] forth_tower_info: SEntry = tower_dict[
) tower_key_list[draw_tower_index + 1]
- (first_tower_info.tower_height - first_tower_info.foundation_low) ]
+ forth_tower_info.altitude_off if forth_tower_info.is_tension_tower:
) forth_tower_fitting_length = 0
span_of_first_tower = ( else:
forth_tower_info.mileage_in_s - first_tower_info.mileage_in_s forth_tower_fitting_length = fitting.fitting_length_dic[
) forth_tower_info.fitting
(x, y) = stringImpactExcel.read( ]
wb_string_impact, gaocha_of_tower = (
gaocha_of_first_tower, (
span_of_first_tower, forth_tower_info.tower_height
high_temperature_tension, - forth_tower_info.foundation_low
) - forth_tower_fitting_length
# TODO: 没有考虑断面中间有耐张塔的情况 )
plot_x = (plate_origin[0] + x / 5).reshape(len(x), 1) - (tower_info.tower_height - tower_info.foundation_low)
plot_y = ( + forth_tower_info.altitude_off
plate_origin[1] )
+ (first_tower_info.tower_height - first_tower_info.foundation_low + y) * 2 span_of_tower = forth_tower_info.mileage_in_s - tower_info.mileage_in_s
).reshape(len(x), 1) (x, y) = stringImpactExcel.read(
self._plot(cad, plot_x, plot_y) wb_string_impact,
# 画右侧耐张塔的弧垂 gaocha_of_tower,
draw_last_tower_key = tower_key_list[draw_tower_index[-1]] span_of_tower,
last_tower_info = tower_dict[draw_last_tower_key] high_temperature_tension,
back_reprtv_span = last_tower_info.back_representive_span )
back_tower_info = tower_dict[tower_key_list[draw_tower_index[-1] - 1]] plot_x = (
gaocha_of_last_tower = ( plate_origin[0]
( + (
back_tower_info.tower_height tower_dict[tower_key_list[draw_tower_index]].mileage_in_s
- back_tower_info.foundation_low - tower_dict[self._draw_start_tower_name].mileage_in_s
- fitting.fitting_length_dic[back_tower_info.fitting] )
) / 5
- (last_tower_info.tower_height - last_tower_info.foundation_low) + x / 5
- last_tower_info.altitude_off ).reshape(len(x), 1)
) accumulate_altitude_off = np.sum(
span_of_last_tower = last_tower_info.mileage_in_s - back_tower_info.mileage_in_s [
(x, y) = stringImpactExcel.read( tower_dict[tower_key_list[bar]].altitude_off
wb_string_impact, for bar in range(
gaocha_of_last_tower, tower_key_list.index(self._draw_start_tower_name) + 1, draw_tower_index + 1
span_of_last_tower, )
high_temperature_tension, ]
) )
plot_last_tower_x = ( plot_y = (
plate_origin[0] plate_origin[1]
+ ( + accumulate_altitude_off * 2
tower_dict[tower_key_list[draw_tower_index[-1]]].mileage_in_s + (tower_info.tower_height - tower_info.foundation_low + y) * 2
- tower_dict[tower_key_list[draw_tower_index[0]]].mileage_in_s ).reshape(len(x), 1)
) self._plot(cad, plot_x, plot_y)
/ 5 if draw_tower_index > tower_key_list.index(
- x / 5 # 从右往左画 self._draw_start_tower_name
).reshape(len(x), 1) ): # 不是第一个,或者只有最后一个
accumulate_altitude_off = np.sum( # 画后侧
[ back_reprtv_span = tower_info.back_representive_span
tower_dict[tower_key_list[bar]].altitude_off continouse_sheet.range("B69").value = back_reprtv_span
for bar in range(draw_tower_index[0] + 1, draw_tower_index[-1] + 1) high_temperature_tension = continouse_sheet.range("L69").value
] back_tower_info: SEntry = tower_dict[
) tower_key_list[draw_tower_index - 1]
plot_last_tower_y = ( ]
plate_origin[1] if back_tower_info.is_tension_tower:
+ accumulate_altitude_off * 2 back_tower_fitting_length = 0
+ (last_tower_info.tower_height - last_tower_info.foundation_low + y) * 2 else:
).reshape(len(x), 1) back_tower_fitting_length = fitting.fitting_length_dic[
plot_last_tower_vector = np2d_to_array( back_tower_info.fitting
np.hstack((plot_last_tower_x, plot_last_tower_y)) ]
) gaocha_of_tower = (
self._plot(cad, plot_last_tower_x, plot_last_tower_y) (
back_tower_info.tower_height
- back_tower_info.foundation_low
- back_tower_fitting_length
)
- (tower_info.tower_height - tower_info.foundation_low)
- tower_info.altitude_off
)
span_of_tower = tower_info.mileage_in_s - back_tower_info.mileage_in_s
(x, y) = stringImpactExcel.read(
wb_string_impact,
gaocha_of_tower,
span_of_tower,
high_temperature_tension,
)
plot_tower_x = (
plate_origin[0]
+ (
tower_dict[tower_key_list[draw_tower_index]].mileage_in_s
- tower_dict[self._draw_start_tower_name].mileage_in_s
)
/ 5
- x / 5 # 从右往左画
).reshape(len(x), 1)
accumulate_altitude_off = np.sum(
[
tower_dict[tower_key_list[bar]].altitude_off
for bar in range(
tower_key_list.index(self._draw_start_tower_name) + 1, draw_tower_index + 1
)
]
)
plot_tower_y = (
plate_origin[1]
+ accumulate_altitude_off * 2
+ (tower_info.tower_height - tower_info.foundation_low + y) * 2
).reshape(len(x), 1)
self._plot(cad, plot_tower_x, plot_tower_y)
# draw_first_tower_key = tower_key_list[draw_tower_indexes[0]]
# first_tower_info: SEntry = tower_dict[draw_first_tower_key]
# forth_reprtv_span = first_tower_info.forth_representive_span
# continouse_sheet.range("B69").value = forth_reprtv_span
# high_temperature_tension = continouse_sheet.range("L69").value
# if first_tower_info.is_tension_tower:
# forth_tower_info: SEntry = tower_dict[
# tower_key_list[draw_tower_indexes[0] + 1]
# ]
# if forth_tower_info.is_tension_tower:
# forth_tower_fitting_length = 0
# else:
# forth_tower_fitting_length = fitting.fitting_length_dic[
# forth_tower_info.fitting
# ]
# gaocha_of_first_tower = (
# (
# forth_tower_info.tower_height
# - forth_tower_info.foundation_low
# - forth_tower_fitting_length
# )
# - (first_tower_info.tower_height - first_tower_info.foundation_low)
# + forth_tower_info.altitude_off
# )
# span_of_first_tower = (
# forth_tower_info.mileage_in_s - first_tower_info.mileage_in_s
# )
# (x, y) = stringImpactExcel.read(
# wb_string_impact,
# gaocha_of_first_tower,
# span_of_first_tower,
# high_temperature_tension,
# )
# # TODO: 没有考虑断面中间有耐张塔的情况
# plot_x = (plate_origin[0] + x / 5).reshape(len(x), 1)
# plot_y = (
# plate_origin[1]
# + (first_tower_info.tower_height - first_tower_info.foundation_low + y)
# * 2
# ).reshape(len(x), 1)
# self._plot(cad, plot_x, plot_y)
# # 记录
# # TODO:记录还没有用
# record = StringImpactExcelRecord()
# record.from_tower_name = first_tower_info.tower_name
# record.fo_tower_name = forth_tower_info.tower_name
# record.span = span_of_first_tower
# record.representive_span = first_tower_info.forth_representive_span
# record.gaocha = gaocha_of_first_tower
# record.tension = high_temperature_tension
# self.excel_record_list.append(record)
# # 画右侧耐张塔的弧垂
# draw_last_tower_key = tower_key_list[draw_tower_indexes[-1]]
# last_tower_info: SEntry = tower_dict[draw_last_tower_key] # 最后一个塔位
# if last_tower_info.is_tension_tower:
# back_reprtv_span = last_tower_info.back_representive_span
# back_tower_info: SEntry = tower_dict[
# tower_key_list[draw_tower_indexes[-1] - 1]
# ]
# if back_tower_info.is_tension_tower:
# back_tower_fitting_length = 0
# else:
# back_tower_fitting_length = fitting.fitting_length_dic[
# back_tower_info.fitting
# ]
# gaocha_of_last_tower = (
# (
# back_tower_info.tower_height
# - back_tower_info.foundation_low
# - back_tower_fitting_length
# )
# - (last_tower_info.tower_height - last_tower_info.foundation_low)
# - last_tower_info.altitude_off
# )
# span_of_last_tower = (
# last_tower_info.mileage_in_s - back_tower_info.mileage_in_s
# )
# (x, y) = stringImpactExcel.read(
# wb_string_impact,
# gaocha_of_last_tower,
# span_of_last_tower,
# high_temperature_tension,
# )
# plot_last_tower_x = (
# plate_origin[0]
# + (
# tower_dict[tower_key_list[draw_tower_indexes[-1]]].mileage_in_s
# - tower_dict[tower_key_list[draw_tower_indexes[0]]].mileage_in_s
# )
# / 5
# - x / 5 # 从右往左画
# ).reshape(len(x), 1)
# accumulate_altitude_off = np.sum(
# [
# tower_dict[tower_key_list[bar]].altitude_off
# for bar in range(draw_tower_indexes[0] + 1, draw_tower_indexes[-1] + 1)
# ]
# )
# plot_last_tower_y = (
# plate_origin[1]
# + accumulate_altitude_off * 2
# + (last_tower_info.tower_height - last_tower_info.foundation_low + y)
# * 2
# ).reshape(len(x), 1)
# plot_last_tower_vector = np2d_to_array(
# np.hstack((plot_last_tower_x, plot_last_tower_y))
# )
# self._plot(cad, plot_last_tower_x, plot_last_tower_y)
def draw(self): def draw(self):
if self._cad: if self._cad:
@@ -339,12 +549,12 @@ class ContinuousPlate:
s_file.open(s_file_path) s_file.open(s_file_path)
dwg_file_path = self._dwg_file_path dwg_file_path = self._dwg_file_path
with Apyautocad( with Apyautocad(
create_if_not_exists=True, visible=False, auto_close=False create_if_not_exists=True, visible=True, auto_close=False
) as cad: ) as cad:
self.cad = cad self.cad = cad
# self._end_tower_name='sdfsd'
doc = cad.app.Documents.Open(dwg_file_path) doc = cad.app.Documents.Open(dwg_file_path)
sleep(1) sleep(1)
custom_layer = get_layer_if_not_exist_create_it(doc, "123custom_layer")
tower_dict = s_file.tower_dic tower_dict = s_file.tower_dic
z_file_path = deduce_zfile_from_cad_path(dwg_file_path) z_file_path = deduce_zfile_from_cad_path(dwg_file_path)
z_point = plane_z_origin(z_file_path) z_point = plane_z_origin(z_file_path)
@@ -381,46 +591,83 @@ class ContinuousPlate:
+ tower_info.mileage_in_s + tower_info.mileage_in_s
- last_tower_info.mileage_in_s - last_tower_info.mileage_in_s
) )
if is_first_tower: if draw_count == draw_count_limit - 1:
# 画代表档距
represented_span_text = f"{tower_info.back_representive_span:.0f}"
represented_span_text_point = np.array(
[(accu_mileage / 2) / 5 + 50, 1]
)
added_represented_span_text = cad.model.AddText(
represented_span_text,
APoint(*represented_span_text_point.tolist()),
3,
)
set_true_color(
added_represented_span_text,
ColorEnume.representive_span_text_color_rgb,
)
added_represented_span_text.Layer = custom_layer.Name
if is_first_tower: # 是否是开始画的第一个塔。
accu_altitude_off = 0 accu_altitude_off = 0
else: else:
accu_altitude_off = ( accu_altitude_off = (
accu_altitude_off + tower_info.altitude_off accu_altitude_off + tower_info.altitude_off
) # 中心桩高程 ) # 中心桩高程
tower_start = APoint( np_tower_start = first_tower_point + np.array(
*(
(
first_tower_point
+ np.array(
[
accu_mileage / 5,
(accu_altitude_off - foundation_low) * 2,
]
)
).tolist()
)
)
tower_height = tower_info.tower_height
np_tower_end = first_tower_point + np.array(
[ [
accu_mileage / 5, accu_mileage / 5,
(accu_altitude_off + tower_height - foundation_low) * 2, (accu_altitude_off - foundation_low) * 2,
] ]
) )
tower_end = APoint(*np_tower_end.tolist()) tower_height = tower_info.tower_height
if tower_info.is_tension_tower:
np_tower_end = first_tower_point + np.array(
[
accu_mileage / 5,
(accu_altitude_off + tower_height - foundation_low) * 2,
]
)
else:
np_tower_end = first_tower_point + np.array(
[
accu_mileage / 5,
(
accu_altitude_off
+ tower_height
- foundation_low
- fitting_length_dict[tower_info.fitting]
+ 3
)
* 2,
]
) # 直线塔杆高只比悬垂挂点高3米
# 画杆高 # 画杆高
cad.model.AddLine(tower_start, tower_end) tower_pole = cad.model.AddPolyLine(
np2d_to_array(np.vstack((np_tower_start, np_tower_end)))
)
tower_pole.Layer = custom_layer.Name
tower_pole.SetWidth(0, 0.8, 0.8)
set_true_color(tower_pole, 0, 255, 255)
# 画塔名和呼高 # 画塔名和呼高
cad.model.AddText( added_tower_name = cad.model.AddText(
f"{tower_info.tower_name}", f"{tower_info.tower_name}",
APoint(*(np_tower_end + np.array([-5, 13])).tolist()), APoint(*(np_tower_end + np.array([-5, 13])).tolist()),
5, 5,
) )
cad.model.AddText( added_tower_name.Layer = custom_layer.Name
f"{tower_info.tower_type}-{tower_info.tower_height}", if (
abs(math.floor(tower_info.tower_height) - tower_info.tower_height)
< 0.1
): # 考虑了半米呼高的情况
draw_tower_height_str = f"{tower_info.tower_height:.0f}"
else:
draw_tower_height_str = f"{tower_info.tower_height:.1f}"
added_hugao = cad.model.AddText(
f"{tower_info.tower_type}-{draw_tower_height_str}",
APoint(*(np_tower_end + np.array([-5, 5])).tolist()), APoint(*(np_tower_end + np.array([-5, 5])).tolist()),
5, 5,
) )
added_hugao.Layer = custom_layer.Name
draw_count += 1 draw_count += 1
# 画弧垂 # 画弧垂
if not is_first_tower: # 从第二基塔开始画 if not is_first_tower: # 从第二基塔开始画
@@ -466,7 +713,8 @@ class ContinuousPlate:
) )
draw_curve_x = draw_curve_x.reshape(len(draw_curve_x), 1) draw_curve_x = draw_curve_x.reshape(len(draw_curve_x), 1)
draw_curve_y = draw_curve_y.reshape(len(draw_curve_y), 1) draw_curve_y = draw_curve_y.reshape(len(draw_curve_y), 1)
draw_ground_curve_y = draw_curve_y - 18 * 2 # 切地线 # TODO 应该读规程的
draw_ground_curve_y = draw_curve_y - 16 * 2 # 切地线
draw_tree_curve_y = draw_curve_y - 13.5 * 2 # 切树线 draw_tree_curve_y = draw_curve_y - 13.5 * 2 # 切树线
draw_point = np.hstack( draw_point = np.hstack(
(draw_curve_x, draw_curve_y, np.zeros((len(draw_curve_x), 1))) (draw_curve_x, draw_curve_y, np.zeros((len(draw_curve_x), 1)))
@@ -488,44 +736,71 @@ class ContinuousPlate:
added_curve = cad.model.AddPolyLine( added_curve = cad.model.AddPolyLine(
draw_point.reshape(1, draw_curve_x.shape[0] * 3)[0] draw_point.reshape(1, draw_curve_x.shape[0] * 3)[0]
) )
added_curve.Layer = custom_layer.Name
set_true_color(added_curve, *ColorEnume.wire_color_rgb) set_true_color(added_curve, *ColorEnume.wire_color_rgb)
added_ground_curve = cad.model.AddPolyLine( added_ground_curve = cad.model.AddPolyLine(
draw_ground_curve_point.reshape( draw_ground_curve_point.reshape(
1, draw_ground_curve_y.shape[0] * 3 1, draw_ground_curve_y.shape[0] * 3
)[0] )[0]
) )
added_ground_curve.Layer = custom_layer.Name
set_true_color(added_ground_curve, *ColorEnume.ground_color_rgb) set_true_color(added_ground_curve, *ColorEnume.ground_color_rgb)
added_tree_curve = cad.model.AddPolyLine( added_tree_curve = cad.model.AddPolyLine(
draw_tree_curve_point.reshape( draw_tree_curve_point.reshape(
1, draw_tree_curve_y.shape[0] * 3 1, draw_tree_curve_y.shape[0] * 3
)[0] )[0]
) )
added_tree_curve.Layer = custom_layer.Name
set_true_color(added_tree_curve, *ColorEnume.tree_color_rgb) set_true_color(added_tree_curve, *ColorEnume.tree_color_rgb)
# 画档距
span_text_insert_point = np.array(
[(accu_mileage - span / 2) / 5 + 50, 6]
)
added_span_text = cad.model.AddText(
f"{span:.0f}", APoint(*span_text_insert_point.tolist()), 3
)
# 画档距分割线
add_span_splitter = cad.model.AddPolyLine(
array(
"d",
[
(accu_mileage) / 5 + 50,
5,
0,
(accu_mileage) / 5 + 50,
10,
0,
],
)
)
add_span_splitter.Layer = custom_layer.Name
set_true_color(added_span_text, *ColorEnume.span_text_color_rgb)
added_span_text.Layer = custom_layer.Name
is_first_tower = False is_first_tower = False
last_tower_info = tower_info last_tower_info = tower_info
def saveAs(self, save_to): def saveAs(self, save_to):
cad = self.cad cad = self.cad
doc = cad.doc
doc.SaveAs(save_to) doc.SaveAs(save_to)
@define @define
class ControlFile: class ControlFile:
_z_excel_file_path: bool = attrs.field(init=True, kw_only=False) _z_excel_file_path: str = attrs.field(init=True, kw_only=False)
_z_file_path: str = "" _z_file_path: str = ""
_dwg_file_path: str = "" _dwg_file_path: str = ""
_from_tower_name: str = "" _from_tower_name: str = ""
_end_tower_name: str = "" _end_tower_name: str = ""
_consider_string_weight: bool = False _consider_string_weight: bool = False
_excel_string_weight_path: str = "" _excel_string_weight_path: str = ""
_excel_continouse_path: str = "" _excel_continuous_path: str = ""
_s_file_path: str = "" _s_file_path: str = ""
_dir_prefix: str = "" _dir_prefix: str = ""
_z_file_name: str = "" _z_file_name: str = ""
_close_cad_document: bool = attrs.field(init=True, kw_only=False, default=True) _close_cad_document: bool = attrs.field(init=True, kw_only=False, default=True)
# def __init__(self, z_excel_file_path):
def __attrs_post_init__(self): def __attrs_post_init__(self):
# self._close_cad_document=close_cad_document
z_excel_file_path = self._z_excel_file_path z_excel_file_path = self._z_excel_file_path
excel_pf = pd.read_excel(z_excel_file_path) excel_pf = pd.read_excel(z_excel_file_path)
pf_dict = excel_pf.to_dict("records")[0] pf_dict = excel_pf.to_dict("records")[0]
@@ -538,7 +813,7 @@ class ControlFile:
if pf_dict["是否考虑耐张串影响"] == "": if pf_dict["是否考虑耐张串影响"] == "":
self._consider_string_weight = True self._consider_string_weight = True
self._excel_string_weight_path = pf_dict["计算耐张串影响用表格"] self._excel_string_weight_path = pf_dict["计算耐张串影响用表格"]
self._excel_continouse_path = pf_dict["计算连续档用表格"] self._excel_continuous_path = pf_dict["计算连续档用表格"]
self._z_file_path = os.path.join(dir_prefix, pf_dict["Z文件"]) self._z_file_path = os.path.join(dir_prefix, pf_dict["Z文件"])
self._dwg_file_path = os.path.join(dir_prefix, pf_dict["DWG文件"]) self._dwg_file_path = os.path.join(dir_prefix, pf_dict["DWG文件"])
self._s_file_path = os.path.join(dir_prefix, pf_dict["S文件"]) self._s_file_path = os.path.join(dir_prefix, pf_dict["S文件"])
@@ -547,23 +822,34 @@ class ControlFile:
return os.path.join(self._dir_prefix, "ZT" + self._z_file_name + ".dwg") return os.path.join(self._dir_prefix, "ZT" + self._z_file_name + ".dwg")
def draw(self): def draw(self):
continousePlate = ContinuousPlate( if not os.path.exists(self._dwg_file_path):
raise error.DWGFileNotExistError(self._dwg_file_path)
continuous_plate = ContinuousPlate(
self._dwg_file_path, self._dwg_file_path,
self._s_file_path, self._s_file_path,
self._from_tower_name, self._from_tower_name,
self._end_tower_name, self._end_tower_name,
) )
continousePlate.draw() continuous_plate.draw()
string_impact_plate = StringImpactPlate( string_impact_plate = StringImpactPlate(
self._dwg_file_path, self._dwg_file_path,
self._s_file_path, self._s_file_path,
self._from_tower_name, self._from_tower_name,
self._excel_continouse_path, self._end_tower_name,
self._excel_continuous_path,
self._excel_string_weight_path, self._excel_string_weight_path,
continousePlate.cad, continuous_plate.cad,
) )
string_impact_plate.draw() string_impact_plate.draw()
cad = continousePlate.cad cad = continuous_plate.cad
cad.doc.SaveAs(self.get_zt_dwg_file_path()) cad.doc.SaveAs(self.get_zt_dwg_file_path())
cad.doc.Utility.Prompt("断面已生成。\n")
# # 画完后再打开
# cad = None
# continousePlate = None
# with Apyautocad(
# create_if_not_exists=True, visible=True, auto_close=False
# ) as cad:
# cad.app.Documents.Open(self.get_zt_dwg_file_path())
if self._close_cad_document: if self._close_cad_document:
cad.doc.Close(False) cad.doc.Close(False)

7
error.py Normal file
View File

@@ -0,0 +1,7 @@
import attrs
@attrs.define
class DWGFileNotExistError(Exception):
not_exist_dwg_file_path: str
pass

47
gui.py
View File

@@ -1,16 +1,18 @@
import os.path import os.path
import error
from ui.mainwindow import Ui_mainWindow from ui.mainwindow import Ui_mainWindow
from PyQt6 import QtWidgets from PyQt6 import QtWidgets
from PyQt6.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QStatusBar from PyQt6.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QToolBar
from PyQt6.QtCore import QSettings, QFileInfo from PyQt6.QtCore import QSettings, QFileInfo, Qt
from PyQt6.QtGui import QAction
import datetime import datetime
from PWFile import ControlFile from PWFile import ControlFile
class MainWindow(QMainWindow, Ui_mainWindow): class MainWindow(QMainWindow, Ui_mainWindow):
def _test_if_file_occupied(self, file_path): @staticmethod
def _test_if_file_occupied(file_path):
if not os.path.exists(file_path): if not os.path.exists(file_path):
return False return False
try: try:
@@ -29,13 +31,24 @@ class MainWindow(QMainWindow, Ui_mainWindow):
)[0] )[0]
for z_control_file_path in z_control_file_paths: for z_control_file_path in z_control_file_paths:
if z_control_file_path != "": if z_control_file_path != "":
cf = ControlFile(z_control_file_path,close_cad_document=False) cf = ControlFile(
z_control_file_path,
close_cad_document=self.cBCloseCadDoc.isChecked(),
)
if self._test_if_file_occupied(cf.get_zt_dwg_file_path()): if self._test_if_file_occupied(cf.get_zt_dwg_file_path()):
QMessageBox.warning( QMessageBox.warning(
self, "注意", f"{cf.get_zt_dwg_file_path()}被占用,请先关闭。" self, "注意", f"{cf.get_zt_dwg_file_path()}被占用,请先关闭。"
) )
return return
cf.draw() try:
cf.draw()
except error.DWGFileNotExistError as dwg_not_exist_exception:
QMessageBox.warning(
self,
"错误",
f"DWG文件{dwg_not_exist_exception.not_exist_dwg_file_path}不存在。",
)
continue
self.statusBar().showMessage( self.statusBar().showMessage(
f"{datetime.datetime.now()} Finished.", 8000 f"{datetime.datetime.now()} Finished.", 8000
) )
@@ -43,10 +56,32 @@ class MainWindow(QMainWindow, Ui_mainWindow):
self._setting.setValue( self._setting.setValue(
"last_working_directory", file_info.absoluteDir().absolutePath() "last_working_directory", file_info.absoluteDir().absolutePath()
) )
zfile_name = file_info.baseName()
QMessageBox.information(self, "提示", zfile_name + "断面图已生成。")
def _cBCloseCadDocClicked(self):
self._setting.setValue("close_cad", self.cBCloseCadDoc.isChecked())
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.pBOpenControlZFile.clicked.connect(self.open_dialog) self.pBOpenControlZFile.clicked.connect(self.open_dialog)
self._setting = QSettings("NWEPDI", "Plate", self) self._setting = QSettings("NWEPDI", "Plate", self)
if not self._setting.value("close_cad"):
self.cBCloseCadDoc.setChecked(False)
else:
self.cBCloseCadDoc.setChecked(self._setting.value("close_cad", type=bool))
self.cBCloseCadDoc.clicked.connect(self._cBCloseCadDocClicked)
self._toolbar = QToolBar(self)
toolbar = self._toolbar
toolbar.setAllowedAreas(Qt.ToolBarArea.TopToolBarArea)
toolbar.setMovable(False)
about_action = QAction("注意事项", self)
about_action.triggered.connect(
lambda: QMessageBox.information(
self, "注意", "注意检查excel表格是否有电气科权限wps是否安装了vba。"
)
)
toolbar.addAction(about_action)
self.addToolBar(toolbar)
pass pass

View File

@@ -1,5 +1,6 @@
import sys import sys
# sys.path.append(r'd:/工程/金上线/code/')
sys.path.append(r'./../')
from PWFile import ControlFile from PWFile import ControlFile
from gui import MainWindow from gui import MainWindow
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication

54
ui/mainwindow.ui Normal file
View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>mainWindow</class>
<widget class="QDialog" name="mainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>生成断面</string>
</property>
<widget class="QPushButton" name="pBOpenControlZFile">
<property name="geometry">
<rect>
<x>120</x>
<y>100</y>
<width>131</width>
<height>71</height>
</rect>
</property>
<property name="text">
<string>打开Z控制文件</string>
</property>
</widget>
<widget class="QCheckBox" name="cBCloseCadDoc">
<property name="geometry">
<rect>
<x>40</x>
<y>40</y>
<width>211</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>生成断面图后自动关闭CAD文档</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>