2022-07-25 14:03:25 +08:00
|
|
|
|
import os.path
|
2022-07-24 16:47:21 +08:00
|
|
|
|
from collections import OrderedDict
|
|
|
|
|
|
import re
|
2022-07-25 22:02:45 +08:00
|
|
|
|
import attrs
|
2022-07-25 14:03:25 +08:00
|
|
|
|
import pandas as pd
|
2022-07-24 16:47:21 +08:00
|
|
|
|
from attrs import define
|
2022-07-25 14:03:25 +08:00
|
|
|
|
from tkinter.messagebox import NO
|
|
|
|
|
|
import xlwings as xw
|
|
|
|
|
|
from Apyautocad import Apyautocad, APoint
|
|
|
|
|
|
import os
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
from time import sleep
|
|
|
|
|
|
from attrs import define
|
|
|
|
|
|
from typing import List
|
2022-07-24 16:47:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@define
|
|
|
|
|
|
class SEntry:
|
|
|
|
|
|
tower_name: str = ""
|
|
|
|
|
|
tower_height: float = 0
|
|
|
|
|
|
tower_type: str = ""
|
|
|
|
|
|
mileage_in_s: int = 0
|
|
|
|
|
|
back_k: float = 0
|
|
|
|
|
|
forth_k: float = 0
|
2022-07-25 14:03:25 +08:00
|
|
|
|
altitude_off: float = 0 # 中心桩高差
|
2022-07-24 16:47:21 +08:00
|
|
|
|
foundation_low: float = 0 # 基降
|
|
|
|
|
|
fitting: str = "" # 金具
|
|
|
|
|
|
is_tension_tower: bool = False
|
2022-07-25 02:05:08 +08:00
|
|
|
|
back_representive_span: float = 0 # 代表档距
|
|
|
|
|
|
forth_representive_span: float = 0 # 代表档距
|
2022-07-24 16:47:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SFile:
|
|
|
|
|
|
def __init__(self) -> None:
|
|
|
|
|
|
self.tower_dic = None
|
|
|
|
|
|
|
|
|
|
|
|
def open(self, s_file_path):
|
|
|
|
|
|
self.tower_dic = OrderedDict()
|
|
|
|
|
|
tower_dic = self.tower_dic
|
|
|
|
|
|
with open(s_file_path, encoding="gbk") as s_file_obj:
|
|
|
|
|
|
new_k = 0
|
2022-07-25 02:05:08 +08:00
|
|
|
|
new_reprtv_span = 0
|
2022-07-24 16:47:21 +08:00
|
|
|
|
last_k = -1
|
2022-07-25 02:05:08 +08:00
|
|
|
|
last_reprtv_span = -1
|
2022-07-24 16:47:21 +08:00
|
|
|
|
last_tower_name = ""
|
|
|
|
|
|
for line in s_file_obj:
|
|
|
|
|
|
norm_line = line.strip()
|
|
|
|
|
|
if norm_line == "":
|
|
|
|
|
|
continue
|
|
|
|
|
|
if "首端转角号" in norm_line:
|
|
|
|
|
|
new_k = float(norm_line.split(":")[-1].replace("E", "e")) # 模板系数
|
2022-07-25 02:05:08 +08:00
|
|
|
|
new_reprtv_span = float(
|
|
|
|
|
|
re.findall("代表档距 : (\d+) 模板系数", norm_line)[0]
|
|
|
|
|
|
) # 代表档距
|
2022-07-24 16:47:21 +08:00
|
|
|
|
continue
|
|
|
|
|
|
if "塔号" in norm_line:
|
|
|
|
|
|
# next_is_tension_tower=True
|
|
|
|
|
|
if last_tower_name != "":
|
|
|
|
|
|
tower_dic[last_tower_name].is_tension_tower = True
|
|
|
|
|
|
continue
|
|
|
|
|
|
norm_entry = re.sub("\s+", ",", norm_line)
|
|
|
|
|
|
sep_entry = norm_entry.split(",")
|
|
|
|
|
|
tower_name = sep_entry[0]
|
|
|
|
|
|
if tower_name in tower_dic:
|
|
|
|
|
|
tower_dic[tower_name].forth_k = new_k # 更新耐张塔前侧k值。
|
2022-07-28 19:58:35 +08:00
|
|
|
|
tower_dic[
|
|
|
|
|
|
tower_name
|
|
|
|
|
|
].forth_representive_span = new_reprtv_span # 更新耐张塔前侧k值。
|
2022-07-27 22:55:44 +08:00
|
|
|
|
last_k = tower_dic[tower_name].forth_k
|
|
|
|
|
|
last_reprtv_span = tower_dic[tower_name].forth_representive_span
|
2022-07-24 16:47:21 +08:00
|
|
|
|
continue
|
|
|
|
|
|
s_entry = SEntry()
|
|
|
|
|
|
s_entry.tower_name = tower_name
|
|
|
|
|
|
last_tower_name = tower_name
|
|
|
|
|
|
s_entry.tower_type = sep_entry[6]
|
|
|
|
|
|
s_entry.tower_height = float(sep_entry[7])
|
|
|
|
|
|
s_entry.mileage_in_s = float(sep_entry[1])
|
|
|
|
|
|
s_entry.back_k = last_k
|
2022-07-25 02:05:08 +08:00
|
|
|
|
s_entry.back_representive_span = last_reprtv_span
|
2022-07-24 16:47:21 +08:00
|
|
|
|
s_entry.forth_k = new_k
|
2022-07-25 02:05:08 +08:00
|
|
|
|
s_entry.forth_representive_span = new_reprtv_span
|
2022-07-24 16:47:21 +08:00
|
|
|
|
s_entry.altitude_off = float(sep_entry[3])
|
|
|
|
|
|
s_entry.foundation_low = float(sep_entry[4])
|
|
|
|
|
|
s_entry.fitting = sep_entry[8]
|
|
|
|
|
|
last_k = s_entry.forth_k
|
2022-07-25 02:05:08 +08:00
|
|
|
|
last_reprtv_span = s_entry.forth_representive_span
|
2022-07-24 16:47:21 +08:00
|
|
|
|
tower_dic[tower_name] = s_entry
|
|
|
|
|
|
tower_dic[list(tower_dic.keys())[-1]].forth_k = -1
|
|
|
|
|
|
tower_dic[list(tower_dic.keys())[0]].is_tension_tower = True
|
|
|
|
|
|
tower_dic[list(tower_dic.keys())[-1]].is_tension_tower = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@define
|
|
|
|
|
|
class Fitting:
|
|
|
|
|
|
fitting_length_dic = {}
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, fitting_file_path):
|
|
|
|
|
|
content = []
|
|
|
|
|
|
with open(fitting_file_path) as fitting_file:
|
|
|
|
|
|
for line in fitting_file:
|
|
|
|
|
|
norm_line = line.strip()
|
|
|
|
|
|
if norm_line == "":
|
|
|
|
|
|
continue
|
|
|
|
|
|
norm_entry = re.sub("\s+", ",", norm_line)
|
|
|
|
|
|
content.append(norm_entry.split(","))
|
|
|
|
|
|
ite = iter(content[7:])
|
|
|
|
|
|
for fit in ite: # 跳过前面7行
|
|
|
|
|
|
fit_name = fit[0]
|
|
|
|
|
|
fit_parameter = next(ite)
|
|
|
|
|
|
self.fitting_length_dic[fit_name] = float(fit_parameter[2]) / 1000
|
2022-07-25 14:03:25 +08:00
|
|
|
|
|
|
|
|
|
|
|
2022-07-25 02:05:08 +08:00
|
|
|
|
@define
|
|
|
|
|
|
class ColorEnume:
|
2022-07-25 14:03:25 +08:00
|
|
|
|
wire_color_rgb = [122, 219, 245]
|
|
|
|
|
|
tree_color_rgb = [240, 226, 81]
|
|
|
|
|
|
ground_color_rgb = [82, 79, 254]
|
2022-07-27 22:55:44 +08:00
|
|
|
|
span_text_color_rgb = [140, 245, 236]
|
2022-07-28 19:58:35 +08:00
|
|
|
|
representive_span_text_color_rgb = [255, 172, 75]
|
2022-07-25 14:03:25 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 读取Z文件,找到Z断面第一个点的坐标
|
|
|
|
|
|
def plane_z_origin(z_file_path):
|
|
|
|
|
|
with open(z_file_path) as zfile:
|
|
|
|
|
|
content = zfile.read()
|
|
|
|
|
|
norm_content = re.sub("\s+", ",", content)
|
|
|
|
|
|
sep = norm_content.split(",")
|
|
|
|
|
|
return np.array([float(sep[0]), float(sep[1])])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deduce_zfile_from_cad_path(cad_file_path):
|
|
|
|
|
|
dwg_file_name = os.path.split(cad_file_path)
|
|
|
|
|
|
dwg_prefix = dwg_file_name[1].split(".")[0]
|
|
|
|
|
|
return os.path.join(dwg_file_name[0], f"Z{dwg_prefix}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deduce_fit_db_from_cad_path(cad_file_path):
|
|
|
|
|
|
dwg_file_name = os.path.split(cad_file_path)
|
|
|
|
|
|
dwg_prefix = dwg_file_name[1].split(".")[0]
|
|
|
|
|
|
return os.path.join(dwg_file_name[0], "Fit.db")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def curve_fun(x, span, k, gaocha):
|
|
|
|
|
|
return x * gaocha / span - x * (span - x) * k
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def np2d_to_array(np2d): # 把2维numpy数组转换成cad可以用的数组
|
|
|
|
|
|
t = np.hstack((np2d, np.zeros((np2d.shape[0], 1)))).reshape(1, np2d.shape[0] * 3)
|
|
|
|
|
|
return t[0]
|
|
|
|
|
|
|
2022-07-28 19:58:35 +08:00
|
|
|
|
|
2022-07-27 22:55:44 +08:00
|
|
|
|
@define
|
2022-07-25 14:03:25 +08:00
|
|
|
|
class StringImpactExcel:
|
|
|
|
|
|
def read(self, wb, gaocha, span, tension):
|
|
|
|
|
|
pos代表档距 = "F13"
|
|
|
|
|
|
pos档距 = "L13"
|
|
|
|
|
|
pos高差 = "R13"
|
|
|
|
|
|
pos张力 = "AB18"
|
|
|
|
|
|
pos总串长 = "C8"
|
|
|
|
|
|
sheet = wb.sheets["模板"]
|
|
|
|
|
|
sheet.range(pos高差).value = gaocha
|
|
|
|
|
|
sheet.range(pos档距).value = span
|
|
|
|
|
|
sheet.range(pos张力).value = tension
|
|
|
|
|
|
string_length = sheet.range(pos总串长).value
|
|
|
|
|
|
x = np.linspace(string_length, span, int(span / 5), endpoint=True)
|
|
|
|
|
|
x[0] = sheet.range("E23").value
|
|
|
|
|
|
x[1] = sheet.range("E24").value
|
|
|
|
|
|
sheet.range(f"E25:E{25+len(x)-3}").value = x[2:].reshape(len(x[2:]), 1)
|
|
|
|
|
|
y = (
|
|
|
|
|
|
np.array(sheet.range(f"V23:V{23+len(x)-1}").value) / 2
|
|
|
|
|
|
) # 表格是乘以了2的,为了和x保持一致,没有乘比例。
|
|
|
|
|
|
return (x, y)
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-28 19:58:35 +08:00
|
|
|
|
def set_true_color(object, r_or_rgb_list, g=0, b=0):
|
2022-07-25 14:03:25 +08:00
|
|
|
|
true_color = object.TrueColor
|
2022-07-28 19:58:35 +08:00
|
|
|
|
if type(r_or_rgb_list) == List or type(r_or_rgb_list)==list:
|
2022-07-26 18:22:28 +08:00
|
|
|
|
true_color.SetRGB(*r_or_rgb_list)
|
|
|
|
|
|
else:
|
|
|
|
|
|
true_color.SetRGB(r_or_rgb_list, g, b)
|
2022-07-25 14:03:25 +08:00
|
|
|
|
object.TrueColor = true_color
|
|
|
|
|
|
|
2022-07-28 19:58:35 +08:00
|
|
|
|
|
2022-07-27 22:55:44 +08:00
|
|
|
|
@define
|
|
|
|
|
|
class StringImpactExcelRecord:
|
2022-07-28 19:58:35 +08:00
|
|
|
|
from_tower_name: str = ""
|
|
|
|
|
|
fo_tower_name: str = ""
|
|
|
|
|
|
representive_span: float = 0 # 代表档距
|
|
|
|
|
|
span: float = 0
|
|
|
|
|
|
tension: float = 0
|
|
|
|
|
|
gaocha: float = 0
|
|
|
|
|
|
|
2022-07-25 14:03:25 +08:00
|
|
|
|
|
|
|
|
|
|
@define
|
|
|
|
|
|
class StringImpactPlate:
|
|
|
|
|
|
_dwg_file_path: str
|
|
|
|
|
|
_s_file_path: str
|
|
|
|
|
|
_draw_start_tower_name: str
|
|
|
|
|
|
_continouse_tension_excel: str
|
|
|
|
|
|
_string_impact_curve_excel: str
|
|
|
|
|
|
_cad: None
|
2022-07-28 19:58:35 +08:00
|
|
|
|
excel_record_list: List = [] # 记录对excel的操作
|
2022-07-25 14:03:25 +08:00
|
|
|
|
|
|
|
|
|
|
def _find_target_tower_index(self, start_tower_name: str, tower_dict):
|
2022-07-27 22:55:44 +08:00
|
|
|
|
# 从 start_tower_name开始,寻找一个耐张段
|
2022-07-25 14:03:25 +08:00
|
|
|
|
index = []
|
|
|
|
|
|
tower_key_list = list(tower_dict.keys())
|
|
|
|
|
|
index.append(tower_key_list.index(start_tower_name))
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
def _plot(self, cad, plot_x, plot_y):
|
|
|
|
|
|
plot_vector = np2d_to_array(np.hstack((plot_x, plot_y)))
|
|
|
|
|
|
added_curve = cad.model.AddPolyLine(plot_vector)
|
|
|
|
|
|
set_true_color(added_curve, *ColorEnume.wire_color_rgb)
|
|
|
|
|
|
plot_ground_y = plot_y - 18 * 2
|
|
|
|
|
|
plot_ground_vector = np2d_to_array(np.hstack((plot_x, plot_ground_y)))
|
|
|
|
|
|
added_ground_curve = cad.model.AddPolyLine(plot_ground_vector)
|
|
|
|
|
|
set_true_color(added_ground_curve, *ColorEnume.ground_color_rgb)
|
|
|
|
|
|
plot_tree_y = plot_y - 13.5 * 2
|
|
|
|
|
|
plot_tree_vector = np2d_to_array(np.hstack((plot_x, plot_tree_y)))
|
|
|
|
|
|
added_tree_curve = cad.model.AddPolyLine(plot_tree_vector)
|
|
|
|
|
|
set_true_color(added_tree_curve, *ColorEnume.tree_color_rgb)
|
|
|
|
|
|
|
|
|
|
|
|
def _draw_action(self, excel_app, cad):
|
|
|
|
|
|
# 计算代表档距
|
|
|
|
|
|
s_file = SFile()
|
|
|
|
|
|
s_file.open(self._s_file_path)
|
|
|
|
|
|
tower_dict = s_file.tower_dic
|
|
|
|
|
|
tower_key_list = list(tower_dict.keys())
|
|
|
|
|
|
draw_tower_index = self._find_target_tower_index(
|
|
|
|
|
|
self._draw_start_tower_name, tower_dict
|
|
|
|
|
|
)
|
|
|
|
|
|
fitting_file_path = deduce_fit_db_from_cad_path(self._dwg_file_path)
|
|
|
|
|
|
fitting = Fitting(fitting_file_path)
|
|
|
|
|
|
z_file_path = deduce_zfile_from_cad_path(self._dwg_file_path)
|
|
|
|
|
|
plate_origin = plane_z_origin(z_file_path)
|
|
|
|
|
|
continouse_wb = excel_app.books.open(self._continouse_tension_excel)
|
|
|
|
|
|
continouse_sheet = continouse_wb.sheets["模板"]
|
|
|
|
|
|
wb_string_impact = excel_app.books.open(self._string_impact_curve_excel)
|
|
|
|
|
|
stringImpactExcel = StringImpactExcel()
|
|
|
|
|
|
sleep(1)
|
|
|
|
|
|
draw_first_tower_key = tower_key_list[draw_tower_index[0]]
|
|
|
|
|
|
first_tower_info = 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
|
|
|
|
|
|
forth_tower_info = tower_dict[tower_key_list[draw_tower_index[0] + 1]]
|
|
|
|
|
|
gaocha_of_first_tower = (
|
|
|
|
|
|
(
|
|
|
|
|
|
forth_tower_info.tower_height
|
|
|
|
|
|
- forth_tower_info.foundation_low
|
|
|
|
|
|
- fitting.fitting_length_dic[forth_tower_info.fitting]
|
|
|
|
|
|
)
|
|
|
|
|
|
- (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)
|
2022-07-27 22:55:44 +08:00
|
|
|
|
# 记录
|
2022-07-28 19:58:35 +08:00
|
|
|
|
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
|
2022-07-27 22:55:44 +08:00
|
|
|
|
self.excel_record_list.append(record)
|
2022-07-25 14:03:25 +08:00
|
|
|
|
# 画右侧耐张塔的弧垂
|
|
|
|
|
|
draw_last_tower_key = tower_key_list[draw_tower_index[-1]]
|
2022-07-28 19:58:35 +08:00
|
|
|
|
last_tower_info = tower_dict[draw_last_tower_key] # 最后一个塔位
|
2022-07-25 14:03:25 +08:00
|
|
|
|
back_reprtv_span = last_tower_info.back_representive_span
|
|
|
|
|
|
back_tower_info = tower_dict[tower_key_list[draw_tower_index[-1] - 1]]
|
|
|
|
|
|
gaocha_of_last_tower = (
|
|
|
|
|
|
(
|
|
|
|
|
|
back_tower_info.tower_height
|
|
|
|
|
|
- back_tower_info.foundation_low
|
|
|
|
|
|
- fitting.fitting_length_dic[back_tower_info.fitting]
|
|
|
|
|
|
)
|
|
|
|
|
|
- (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_index[-1]]].mileage_in_s
|
|
|
|
|
|
- tower_dict[tower_key_list[draw_tower_index[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_index[0] + 1, draw_tower_index[-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):
|
|
|
|
|
|
if self._cad:
|
|
|
|
|
|
with xw.App(visible=False) as excel_app:
|
|
|
|
|
|
self._draw_action(excel_app, self._cad)
|
|
|
|
|
|
else:
|
|
|
|
|
|
with xw.App(visible=False) as excel_app, Apyautocad(
|
|
|
|
|
|
create_if_not_exists=True, visible=True, auto_close=True
|
|
|
|
|
|
) as cad:
|
|
|
|
|
|
cad.app.Documents.Open(self._dwg_file_path)
|
|
|
|
|
|
self._draw_action(excel_app, cad)
|
|
|
|
|
|
|
|
|
|
|
|
def saveAs(self, save_to):
|
|
|
|
|
|
self._cad.SaveAs(save_to)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@define
|
|
|
|
|
|
class ContinuousPlate:
|
|
|
|
|
|
_dwg_file_path: str
|
|
|
|
|
|
_s_file_path: str
|
|
|
|
|
|
_from_tower_name: str
|
|
|
|
|
|
_end_tower_name: str
|
|
|
|
|
|
cad: object = None
|
|
|
|
|
|
|
|
|
|
|
|
def draw(self):
|
|
|
|
|
|
s_file = SFile()
|
|
|
|
|
|
s_file_path = self._s_file_path
|
|
|
|
|
|
s_file.open(s_file_path)
|
|
|
|
|
|
dwg_file_path = self._dwg_file_path
|
|
|
|
|
|
with Apyautocad(
|
|
|
|
|
|
create_if_not_exists=True, visible=False, auto_close=False
|
|
|
|
|
|
) as cad:
|
|
|
|
|
|
self.cad = cad
|
|
|
|
|
|
doc = cad.app.Documents.Open(dwg_file_path)
|
|
|
|
|
|
sleep(1)
|
|
|
|
|
|
tower_dict = s_file.tower_dic
|
|
|
|
|
|
z_file_path = deduce_zfile_from_cad_path(dwg_file_path)
|
|
|
|
|
|
z_point = plane_z_origin(z_file_path)
|
|
|
|
|
|
fitting_file_path = deduce_fit_db_from_cad_path(dwg_file_path)
|
|
|
|
|
|
fitting = Fitting(fitting_file_path)
|
|
|
|
|
|
fitting_length_dict = fitting.fitting_length_dic
|
|
|
|
|
|
first_tower_point = z_point
|
|
|
|
|
|
last_tower_info = None # 上一个塔位信息
|
|
|
|
|
|
accu_mileage = 0 # 累计档距
|
|
|
|
|
|
accu_altitude_off = 0 # 累计高差
|
|
|
|
|
|
is_first_tower = True
|
|
|
|
|
|
can_start_draw = -1
|
|
|
|
|
|
start_tower_name = self._from_tower_name
|
|
|
|
|
|
tower_key_list = list(tower_dict.keys())
|
|
|
|
|
|
draw_count_limit = (
|
|
|
|
|
|
tower_key_list.index(self._end_tower_name)
|
|
|
|
|
|
- tower_key_list.index(self._from_tower_name)
|
|
|
|
|
|
+ 1
|
|
|
|
|
|
)
|
|
|
|
|
|
draw_count = 0
|
|
|
|
|
|
for tower in tower_dict:
|
|
|
|
|
|
tower_info = tower_dict[tower]
|
|
|
|
|
|
if tower_info.tower_name == start_tower_name:
|
|
|
|
|
|
can_start_draw = 0
|
|
|
|
|
|
elif can_start_draw != 0:
|
|
|
|
|
|
continue
|
|
|
|
|
|
if not last_tower_info:
|
|
|
|
|
|
last_tower_info = tower_info
|
2022-07-28 19:58:35 +08:00
|
|
|
|
if draw_count == draw_count_limit:
|
|
|
|
|
|
# 画代表档距
|
|
|
|
|
|
representive_span_text = f"{tower_info.back_representive_span:.0f}"
|
|
|
|
|
|
representive_span_text_point = np.array(
|
|
|
|
|
|
[(accu_mileage / 2) / 5 + 50, 1]
|
|
|
|
|
|
)
|
|
|
|
|
|
added_representive_span_text = cad.model.AddText(
|
|
|
|
|
|
representive_span_text,
|
|
|
|
|
|
APoint(*representive_span_text_point.tolist()),
|
|
|
|
|
|
3,
|
|
|
|
|
|
)
|
|
|
|
|
|
set_true_color(added_representive_span_text,ColorEnume.representive_span_text_color_rgb)
|
2022-07-25 14:03:25 +08:00
|
|
|
|
if draw_count > draw_count_limit - 1:
|
|
|
|
|
|
break
|
|
|
|
|
|
foundation_low = tower_info.foundation_low
|
|
|
|
|
|
accu_mileage = (
|
|
|
|
|
|
accu_mileage
|
|
|
|
|
|
+ tower_info.mileage_in_s
|
|
|
|
|
|
- last_tower_info.mileage_in_s
|
|
|
|
|
|
)
|
|
|
|
|
|
if is_first_tower:
|
2022-07-25 18:21:55 +08:00
|
|
|
|
accu_altitude_off = 0
|
2022-07-25 14:03:25 +08:00
|
|
|
|
else:
|
2022-07-25 18:21:55 +08:00
|
|
|
|
accu_altitude_off = (
|
|
|
|
|
|
accu_altitude_off + tower_info.altitude_off
|
|
|
|
|
|
) # 中心桩高程
|
2022-07-25 14:03:25 +08:00
|
|
|
|
tower_start = APoint(
|
|
|
|
|
|
*(
|
|
|
|
|
|
(
|
|
|
|
|
|
first_tower_point
|
|
|
|
|
|
+ np.array(
|
|
|
|
|
|
[
|
|
|
|
|
|
accu_mileage / 5,
|
|
|
|
|
|
(accu_altitude_off - foundation_low) * 2,
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
).tolist()
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
tower_height = tower_info.tower_height
|
2022-07-25 18:21:55 +08:00
|
|
|
|
np_tower_end = first_tower_point + np.array(
|
|
|
|
|
|
[
|
|
|
|
|
|
accu_mileage / 5,
|
|
|
|
|
|
(accu_altitude_off + tower_height - foundation_low) * 2,
|
|
|
|
|
|
]
|
2022-07-25 14:03:25 +08:00
|
|
|
|
)
|
2022-07-25 18:21:55 +08:00
|
|
|
|
tower_end = APoint(*np_tower_end.tolist())
|
2022-07-25 14:03:25 +08:00
|
|
|
|
# 画杆高
|
|
|
|
|
|
cad.model.AddLine(tower_start, tower_end)
|
2022-07-25 18:21:55 +08:00
|
|
|
|
# 画塔名和呼高
|
|
|
|
|
|
cad.model.AddText(
|
|
|
|
|
|
f"{tower_info.tower_name}",
|
|
|
|
|
|
APoint(*(np_tower_end + np.array([-5, 13])).tolist()),
|
|
|
|
|
|
5,
|
|
|
|
|
|
)
|
|
|
|
|
|
cad.model.AddText(
|
|
|
|
|
|
f"{tower_info.tower_type}-{tower_info.tower_height}",
|
|
|
|
|
|
APoint(*(np_tower_end + np.array([-5, 5])).tolist()),
|
|
|
|
|
|
5,
|
|
|
|
|
|
)
|
2022-07-25 14:03:25 +08:00
|
|
|
|
draw_count += 1
|
|
|
|
|
|
# 画弧垂
|
|
|
|
|
|
if not is_first_tower: # 从第二基塔开始画
|
|
|
|
|
|
draw_k = tower_info.back_k
|
|
|
|
|
|
span = tower_info.mileage_in_s - last_tower_info.mileage_in_s
|
|
|
|
|
|
last_tower_fiting = last_tower_info.fitting
|
|
|
|
|
|
last_tower_fitting_length = fitting_length_dict[last_tower_fiting]
|
|
|
|
|
|
if last_tower_info.is_tension_tower:
|
|
|
|
|
|
last_tower_fitting_length = 0
|
|
|
|
|
|
tower_fitting = tower_info.fitting
|
|
|
|
|
|
tower_fitting_length = fitting_length_dict[tower_fitting]
|
|
|
|
|
|
if tower_info.is_tension_tower:
|
|
|
|
|
|
tower_fitting_length = 0
|
|
|
|
|
|
last_tower_height = last_tower_info.tower_height
|
|
|
|
|
|
last_foundation_low = last_tower_info.foundation_low
|
|
|
|
|
|
# 挂点高差
|
|
|
|
|
|
fiting_altitude_off = (
|
|
|
|
|
|
tower_info.altitude_off
|
|
|
|
|
|
+ (tower_height - foundation_low - tower_fitting_length)
|
|
|
|
|
|
- (
|
|
|
|
|
|
last_tower_height
|
|
|
|
|
|
- last_foundation_low
|
|
|
|
|
|
- last_tower_fitting_length
|
|
|
|
|
|
)
|
|
|
|
|
|
) # 前侧高为正
|
|
|
|
|
|
# 画导线弧垂
|
|
|
|
|
|
x = np.linspace(0, span, int(span), endpoint=True)
|
|
|
|
|
|
curve = curve_fun(x, span, draw_k, fiting_altitude_off)
|
|
|
|
|
|
draw_curve_x = (first_tower_point[0]) + (
|
|
|
|
|
|
x + accu_mileage - span
|
|
|
|
|
|
) / 5
|
|
|
|
|
|
draw_curve_y = (
|
|
|
|
|
|
first_tower_point[1]
|
|
|
|
|
|
+ (
|
|
|
|
|
|
+curve
|
|
|
|
|
|
+ accu_altitude_off
|
|
|
|
|
|
- tower_info.altitude_off
|
|
|
|
|
|
- last_tower_info.foundation_low
|
|
|
|
|
|
+ last_tower_info.tower_height
|
|
|
|
|
|
- last_tower_fitting_length
|
|
|
|
|
|
)
|
|
|
|
|
|
* 2
|
|
|
|
|
|
)
|
|
|
|
|
|
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_ground_curve_y = draw_curve_y - 18 * 2 # 切地线
|
|
|
|
|
|
draw_tree_curve_y = draw_curve_y - 13.5 * 2 # 切树线
|
|
|
|
|
|
draw_point = np.hstack(
|
|
|
|
|
|
(draw_curve_x, draw_curve_y, np.zeros((len(draw_curve_x), 1)))
|
|
|
|
|
|
)
|
|
|
|
|
|
draw_ground_curve_point = np.hstack(
|
|
|
|
|
|
(
|
|
|
|
|
|
draw_curve_x,
|
|
|
|
|
|
draw_ground_curve_y,
|
|
|
|
|
|
np.zeros((len(draw_curve_x), 1)),
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
draw_tree_curve_point = np.hstack(
|
|
|
|
|
|
(
|
|
|
|
|
|
draw_curve_x,
|
|
|
|
|
|
draw_tree_curve_y,
|
|
|
|
|
|
np.zeros((len(draw_curve_x), 1)),
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
added_curve = cad.model.AddPolyLine(
|
|
|
|
|
|
draw_point.reshape(1, draw_curve_x.shape[0] * 3)[0]
|
|
|
|
|
|
)
|
|
|
|
|
|
set_true_color(added_curve, *ColorEnume.wire_color_rgb)
|
|
|
|
|
|
added_ground_curve = cad.model.AddPolyLine(
|
|
|
|
|
|
draw_ground_curve_point.reshape(
|
|
|
|
|
|
1, draw_ground_curve_y.shape[0] * 3
|
|
|
|
|
|
)[0]
|
|
|
|
|
|
)
|
|
|
|
|
|
set_true_color(added_ground_curve, *ColorEnume.ground_color_rgb)
|
|
|
|
|
|
added_tree_curve = cad.model.AddPolyLine(
|
|
|
|
|
|
draw_tree_curve_point.reshape(
|
|
|
|
|
|
1, draw_tree_curve_y.shape[0] * 3
|
|
|
|
|
|
)[0]
|
|
|
|
|
|
)
|
|
|
|
|
|
set_true_color(added_tree_curve, *ColorEnume.tree_color_rgb)
|
2022-07-27 22:55:44 +08:00
|
|
|
|
# 画档距
|
|
|
|
|
|
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
|
|
|
|
|
|
)
|
|
|
|
|
|
set_true_color(added_span_text, *ColorEnume.span_text_color_rgb)
|
2022-07-25 14:03:25 +08:00
|
|
|
|
is_first_tower = False
|
|
|
|
|
|
last_tower_info = tower_info
|
|
|
|
|
|
|
|
|
|
|
|
def saveAs(self, save_to):
|
|
|
|
|
|
cad = self.cad
|
|
|
|
|
|
doc.SaveAs(save_to)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@define
|
|
|
|
|
|
class ControlFile:
|
2022-07-25 22:02:45 +08:00
|
|
|
|
_z_excel_file_path: bool = attrs.field(init=True, kw_only=False)
|
2022-07-25 14:03:25 +08:00
|
|
|
|
_z_file_path: str = ""
|
|
|
|
|
|
_dwg_file_path: str = ""
|
|
|
|
|
|
_from_tower_name: str = ""
|
|
|
|
|
|
_end_tower_name: str = ""
|
|
|
|
|
|
_consider_string_weight: bool = False
|
|
|
|
|
|
_excel_string_weight_path: str = ""
|
|
|
|
|
|
_excel_continouse_path: str = ""
|
|
|
|
|
|
_s_file_path: str = ""
|
|
|
|
|
|
_dir_prefix: str = ""
|
|
|
|
|
|
_z_file_name: str = ""
|
2022-07-25 22:02:45 +08:00
|
|
|
|
_close_cad_document: bool = attrs.field(init=True, kw_only=False, default=True)
|
2022-07-27 22:55:44 +08:00
|
|
|
|
|
2022-07-25 22:02:45 +08:00
|
|
|
|
def __attrs_post_init__(self):
|
|
|
|
|
|
z_excel_file_path = self._z_excel_file_path
|
2022-07-25 14:03:25 +08:00
|
|
|
|
excel_pf = pd.read_excel(z_excel_file_path)
|
|
|
|
|
|
pf_dict = excel_pf.to_dict("records")[0]
|
|
|
|
|
|
z_excel_path = os.path.split(z_excel_file_path)
|
|
|
|
|
|
self._z_file_name = pf_dict["Z文件"]
|
|
|
|
|
|
dir_prefix = z_excel_path[0]
|
|
|
|
|
|
self._dir_prefix = dir_prefix
|
|
|
|
|
|
self._from_tower_name = pf_dict["起始塔号"]
|
|
|
|
|
|
self._end_tower_name = pf_dict["终止塔号"]
|
|
|
|
|
|
if pf_dict["是否考虑耐张串影响"] == "是":
|
|
|
|
|
|
self._consider_string_weight = True
|
|
|
|
|
|
self._excel_string_weight_path = pf_dict["计算耐张串影响用表格"]
|
|
|
|
|
|
self._excel_continouse_path = pf_dict["计算连续档用表格"]
|
|
|
|
|
|
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._s_file_path = os.path.join(dir_prefix, pf_dict["S文件"])
|
|
|
|
|
|
|
2022-07-25 22:02:45 +08:00
|
|
|
|
def get_zt_dwg_file_path(self): # 获得生成的dwg文件名路径
|
|
|
|
|
|
return os.path.join(self._dir_prefix, "ZT" + self._z_file_name + ".dwg")
|
|
|
|
|
|
|
2022-07-25 14:03:25 +08:00
|
|
|
|
def draw(self):
|
|
|
|
|
|
continousePlate = ContinuousPlate(
|
|
|
|
|
|
self._dwg_file_path,
|
|
|
|
|
|
self._s_file_path,
|
|
|
|
|
|
self._from_tower_name,
|
|
|
|
|
|
self._end_tower_name,
|
|
|
|
|
|
)
|
|
|
|
|
|
continousePlate.draw()
|
|
|
|
|
|
string_impact_plate = StringImpactPlate(
|
|
|
|
|
|
self._dwg_file_path,
|
|
|
|
|
|
self._s_file_path,
|
|
|
|
|
|
self._from_tower_name,
|
|
|
|
|
|
self._excel_continouse_path,
|
|
|
|
|
|
self._excel_string_weight_path,
|
|
|
|
|
|
continousePlate.cad,
|
|
|
|
|
|
)
|
|
|
|
|
|
string_impact_plate.draw()
|
|
|
|
|
|
cad = continousePlate.cad
|
2022-07-25 22:02:45 +08:00
|
|
|
|
cad.doc.SaveAs(self.get_zt_dwg_file_path())
|
|
|
|
|
|
if self._close_cad_document:
|
|
|
|
|
|
cad.doc.Close(False)
|