civil-tools-v 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CivilTools/DXFGenerator/BasicDXF.py +3 -0
- CivilTools/DXFGenerator/__init__.py +0 -0
- CivilTools/FigureGenerator/BasicPNGPlotter.py +43 -0
- CivilTools/FigureGenerator/BasicPltPlotter.py +3 -0
- CivilTools/FigureGenerator/StairCalculationSheetPNGPlotter.py +16 -0
- CivilTools/FigureGenerator/__init__.py +0 -0
- CivilTools/ReportGenerator/BasicGenerator.py +267 -0
- CivilTools/ReportGenerator/DocParagraph.py +17 -0
- CivilTools/ReportGenerator/DocPicture.py +9 -0
- CivilTools/ReportGenerator/DocTable.py +41 -0
- CivilTools/ReportGenerator/SeismicReport.py +220 -0
- CivilTools/ReportGenerator/SeismicReportTemplate.py +240 -0
- CivilTools/ReportGenerator/StairCalculationReport.py +465 -0
- CivilTools/ReportGenerator/UtilFunctions.py +225 -0
- CivilTools/ReportGenerator/__init__.py +7 -0
- CivilTools/YDBLoader/BuildingDefine/Beam/Beam.py +26 -0
- CivilTools/YDBLoader/BuildingDefine/Beam/__init__.py +1 -0
- CivilTools/YDBLoader/BuildingDefine/Column/Column.py +16 -0
- CivilTools/YDBLoader/BuildingDefine/Column/__init__.py +1 -0
- CivilTools/YDBLoader/BuildingDefine/ComponentType.py +10 -0
- CivilTools/YDBLoader/BuildingDefine/Geometry/Grid.py +21 -0
- CivilTools/YDBLoader/BuildingDefine/Geometry/Joint.py +25 -0
- CivilTools/YDBLoader/BuildingDefine/Geometry/StandFloor.py +2 -0
- CivilTools/YDBLoader/BuildingDefine/Geometry/__init__.py +3 -0
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/BasicResult.py +45 -0
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/SeismicResult.py +128 -0
- CivilTools/YDBLoader/BuildingDefine/GlobalResult/__init__.py +2 -0
- CivilTools/YDBLoader/BuildingDefine/Section/Section.py +49 -0
- CivilTools/YDBLoader/BuildingDefine/Section/ShapeEnum.py +42 -0
- CivilTools/YDBLoader/BuildingDefine/Section/__init__.py +2 -0
- CivilTools/YDBLoader/BuildingDefine/Slab/Slab.py +2 -0
- CivilTools/YDBLoader/BuildingDefine/Slab/__init__.py +1 -0
- CivilTools/YDBLoader/BuildingDefine/StairPart/LoadDefine.py +38 -0
- CivilTools/YDBLoader/BuildingDefine/StairPart/StairComponent.py +95 -0
- CivilTools/YDBLoader/BuildingDefine/StairPart/StairPart.py +206 -0
- CivilTools/YDBLoader/BuildingDefine/StairPart/__init__.py +3 -0
- CivilTools/YDBLoader/BuildingDefine/__init__.py +9 -0
- CivilTools/YDBLoader/SQLiteConnector/Connector.py +80 -0
- CivilTools/YDBLoader/SQLiteConnector/RowDataFactory.py +45 -0
- CivilTools/YDBLoader/SQLiteConnector/YDBTableName.py +96 -0
- CivilTools/YDBLoader/SQLiteConnector/__init__.py +3 -0
- CivilTools/YDBLoader/YDBLoader.py +224 -0
- CivilTools/YDBLoader/YDBType.py +5 -0
- CivilTools/YDBLoader/__init__.py +4 -0
- CivilTools/__init__.py +1 -0
- civil_tools_v-0.0.1.dist-info/LICENSE +21 -0
- civil_tools_v-0.0.1.dist-info/METADATA +98 -0
- civil_tools_v-0.0.1.dist-info/RECORD +50 -0
- civil_tools_v-0.0.1.dist-info/WHEEL +5 -0
- civil_tools_v-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,206 @@
|
|
1
|
+
import math
|
2
|
+
from .StairComponent import Component
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
class Position:
|
6
|
+
@property
|
7
|
+
def lower_elevation(self):
|
8
|
+
return min(self.left_elevation, self.right_elevation)
|
9
|
+
@property
|
10
|
+
def higher_elevation(self):
|
11
|
+
return max(self.left_elevation, self.right_elevation)
|
12
|
+
@property
|
13
|
+
def total_height(self):
|
14
|
+
return self.higher_elevation - self.lower_elevation
|
15
|
+
@property
|
16
|
+
def left_plat_length(self):
|
17
|
+
return self.left_x2 - self.left_x1
|
18
|
+
@property
|
19
|
+
def right_plat_length(self):
|
20
|
+
return self.right_x2 - self.right_x1
|
21
|
+
@property
|
22
|
+
def main_plat_length(self):
|
23
|
+
return self.right_x1 - self.left_x2
|
24
|
+
|
25
|
+
def __init__(self, left_elevation, right_elevation, left_x1,left_x2
|
26
|
+
, right_x1, right_x2):
|
27
|
+
self.left_elevation = left_elevation
|
28
|
+
self.right_elevation = right_elevation
|
29
|
+
self.left_x1 = left_x1
|
30
|
+
self.left_x2 = left_x2
|
31
|
+
self.right_x1 = right_x1
|
32
|
+
self.right_x2 = right_x2
|
33
|
+
|
34
|
+
class StairBeam:
|
35
|
+
|
36
|
+
def __init__(self,width, height, offset):
|
37
|
+
self.width = width
|
38
|
+
self.height = height
|
39
|
+
self.offset = offset
|
40
|
+
|
41
|
+
|
42
|
+
class StairPart:
|
43
|
+
|
44
|
+
@property
|
45
|
+
def stair_type(self):
|
46
|
+
left_extend = self.beam_list[1].offset + self.beam_list[1].width/2
|
47
|
+
right_extend = self.beam_list[2].offset + self.beam_list[2].width/2
|
48
|
+
if left_extend>=self.STAIR_EXTEND_LIMIT:
|
49
|
+
if right_extend >= self.STAIR_EXTEND_LIMIT:
|
50
|
+
return "DT"
|
51
|
+
else:
|
52
|
+
return "BT"
|
53
|
+
else:
|
54
|
+
if right_extend >= self.STAIR_EXTEND_LIMIT:
|
55
|
+
return "CT"
|
56
|
+
else:
|
57
|
+
return "AT"
|
58
|
+
|
59
|
+
@property
|
60
|
+
def stair_elevation_range(self):
|
61
|
+
return f"{self.position.lower_elevation/1000:.3f}~{self.position.higher_elevation/1000:.3f}"
|
62
|
+
|
63
|
+
@property
|
64
|
+
def total_height(self):
|
65
|
+
return abs(self.position.left_elevation - self.position.right_elevation)
|
66
|
+
|
67
|
+
@property
|
68
|
+
def equivlent_main_slab_thick(self):
|
69
|
+
slope = math.atan(self.position.total_height / self.position.main_plat_length)
|
70
|
+
thick_1 = self.main_thick / math.cos(slope)
|
71
|
+
thick_2 = self.position.total_height / self.step_num / 2
|
72
|
+
return thick_1 + thick_2
|
73
|
+
|
74
|
+
@property
|
75
|
+
def total_horizental_length(self):
|
76
|
+
length = self.position.right_x1 - self.position.left_x2
|
77
|
+
length += self.beam_list[1].offset + self.beam_list[1].width/2
|
78
|
+
length += self.beam_list[2].offset + self.beam_list[2].width/2
|
79
|
+
return length
|
80
|
+
@property
|
81
|
+
def left_extend_length(self):
|
82
|
+
if self.stair_type =="AT" or self.stair_type == "CT":
|
83
|
+
return 0
|
84
|
+
else:
|
85
|
+
return self.beam_list[1].offset + self.beam_list[1].width/2
|
86
|
+
|
87
|
+
@property
|
88
|
+
def right_extend_length(self):
|
89
|
+
if self.stair_type =="AT" or self.stair_type == "BT":
|
90
|
+
return 0
|
91
|
+
else:
|
92
|
+
return self.beam_list[2].offset + self.beam_list[2].width/2
|
93
|
+
|
94
|
+
@property
|
95
|
+
def stair_length_list(self):
|
96
|
+
return [self.left_extend_length,self.total_horizental_length - self.left_extend_length - self.right_extend_length,self.right_extend_length]
|
97
|
+
|
98
|
+
@property
|
99
|
+
def up_real_rebar_str(self):
|
100
|
+
return f"E{self.up_d:d}@{self.up_dis:d}"
|
101
|
+
|
102
|
+
@property
|
103
|
+
def up_real_rebar_area(self):
|
104
|
+
return f"{(self.up_d*self.up_d * math.pi/4/self.up_dis):.3f}"
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
def get_calculate_moments(self)->List[float]:
|
111
|
+
if self.stair_type == "AT":
|
112
|
+
return [0,0,self.components[0].m_2,0,0]
|
113
|
+
elif self.stair_type == "BT":
|
114
|
+
return [0,self.components[0].m_2,self.components[1].m_2,0,0]
|
115
|
+
elif self.stair_type == "CT":
|
116
|
+
return [0,0,self.components[0].m_2,self.components[1].m_2,0]
|
117
|
+
elif self.stair_type == "DT":
|
118
|
+
return [0,self.components[0].m_2,self.components[1].m_2,self.components[2].m_2,0]
|
119
|
+
return [0,10,20,10,0]
|
120
|
+
|
121
|
+
def get_calculate_shears(self)->List[float]:
|
122
|
+
if self.stair_type == "AT":
|
123
|
+
return [0,0,self.components[0].v1,self.components[0].v2,self.components[1].v1,self.components[1].v2,0,0]
|
124
|
+
elif self.stair_type == "BT":
|
125
|
+
return [self.components[0].v1,self.components[0].v2,self.components[1].v1,self.components[1].v2,self.components[2].v1,self.components[2].v2,0,0]
|
126
|
+
elif self.stair_type == "CT":
|
127
|
+
return [0,0,self.components[0].v1,self.components[0].v2,self.components[1].v1,self.components[1].v2,self.components[2].v1,self.components[2].v2]
|
128
|
+
elif self.stair_type == "DT":
|
129
|
+
return [self.components[0].v1,self.components[0].v2,self.components[1].v1,self.components[1].v2,self.components[2].v1,self.components[2].v2,self.components[3].v1,self.components[3].v2,]
|
130
|
+
return [0,0,0,10,20,10,0,0]
|
131
|
+
|
132
|
+
def get_left_slab_table_moments(self):
|
133
|
+
moments = self.get_calculate_moments()
|
134
|
+
return [0,moments[1]*0.25,moments[1]]
|
135
|
+
|
136
|
+
def get_main_table_moments(self):
|
137
|
+
moments = self.get_calculate_moments()
|
138
|
+
return [moments[1],moments[2],moments[3]]
|
139
|
+
|
140
|
+
def get_right_slab_table_moments(self):
|
141
|
+
moments = self.get_calculate_moments()
|
142
|
+
return [moments[3],moments[3]*0.25,0]
|
143
|
+
|
144
|
+
|
145
|
+
def get_left_slab_table_shears(self):
|
146
|
+
shears = self.get_calculate_shears()
|
147
|
+
return [shears[0],(shears[0]+shears[1])/2,shears[1]]
|
148
|
+
|
149
|
+
def get_main_table_shears(self):
|
150
|
+
shears = self.get_calculate_shears()
|
151
|
+
return [shears[2],(shears[2]+shears[5])/2,shears[5]]
|
152
|
+
|
153
|
+
def get_right_slab_table_shears(self):
|
154
|
+
shears = self.get_calculate_shears()
|
155
|
+
return [shears[6],(shears[6]+shears[7])/2,shears[7]]
|
156
|
+
|
157
|
+
def get_shear_validate(self, which_side,ft,cover_thick):
|
158
|
+
if which_side == "left":
|
159
|
+
shears = self.get_left_slab_table_shears()
|
160
|
+
shear_limit = 0.7*1*ft*(self.left_thick - cover_thick)*1000/1000
|
161
|
+
elif which_side == "right":
|
162
|
+
shears = self.get_right_slab_table_shears()
|
163
|
+
shear_limit = 0.7*1*ft*(self.right_thick - cover_thick)*1000/1000
|
164
|
+
else:
|
165
|
+
shears = self.get_main_table_shears()
|
166
|
+
shear_limit = 0.7*1*ft*(self.main_thick - cover_thick)*1000/1000
|
167
|
+
max_shear = max([abs(i) for i in shears])
|
168
|
+
if max_shear<=shear_limit:
|
169
|
+
shear_context = f"Vmax={max_shear:.2f}kN < 0.7βhftbh0={shear_limit:.2f}kN,抗剪截面满足要求!"
|
170
|
+
else:
|
171
|
+
shear_context = f"Vmax={max_shear:.2f}kN > 0.7βhftbh0={shear_limit:.2f}kN,抗剪截面不满足要求!"
|
172
|
+
|
173
|
+
return shear_context
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
def init_default_data(self):
|
178
|
+
self.stair_width = 1500
|
179
|
+
self.stair_well_width = 100
|
180
|
+
self.beam_list = [StairBeam(300,500,0),StairBeam(300,500, 0),StairBeam(300,500,0),StairBeam(300,500,0)]
|
181
|
+
self.set_thickness(140,140,140)
|
182
|
+
self.set_real_rebar(10,150,10,150)
|
183
|
+
|
184
|
+
def __init__(self, position:Position,step_num):
|
185
|
+
self.position = position
|
186
|
+
self.step_num = step_num
|
187
|
+
self.init_default_data()
|
188
|
+
|
189
|
+
self.STAIR_EXTEND_LIMIT = 200
|
190
|
+
|
191
|
+
def set_thickness(self, left_thick, main_thick,right_thick):
|
192
|
+
self.left_thick = left_thick
|
193
|
+
self.main_thick = main_thick
|
194
|
+
self.right_thick = right_thick
|
195
|
+
|
196
|
+
def set_beam_offset(self, i,offset):
|
197
|
+
self.beam_list[i].offset = offset
|
198
|
+
|
199
|
+
def set_real_rebar(self, up_d,up_dis,down_d,down_dis):
|
200
|
+
self.up_d = up_d
|
201
|
+
self.up_dis = up_dis
|
202
|
+
self.down_d = down_d
|
203
|
+
self.down_dis = down_dis
|
204
|
+
|
205
|
+
def set_calculate_result(self, components:List[Component]):
|
206
|
+
self.components = components
|
@@ -0,0 +1,9 @@
|
|
1
|
+
from .Beam import Beam
|
2
|
+
from .Section import Section
|
3
|
+
from .Geometry import Joint,Grid,StandFloor
|
4
|
+
from .Column import Column
|
5
|
+
from .Slab import Slab
|
6
|
+
|
7
|
+
from .ComponentType import ComponentType
|
8
|
+
from .GlobalResult import SingleMassResult, MassResult, Period, SinglePeriod
|
9
|
+
from .GlobalResult import ValuePeer, FloorSeismicResult, SeismicResult
|
@@ -0,0 +1,80 @@
|
|
1
|
+
from typing import List
|
2
|
+
import sqlite3
|
3
|
+
import os
|
4
|
+
|
5
|
+
class Connector:
|
6
|
+
|
7
|
+
def __init__(self, file_path=None):
|
8
|
+
self.set_db_file(file_path)
|
9
|
+
self.connection = None
|
10
|
+
self.cursor = None
|
11
|
+
|
12
|
+
def set_db_file(self, file_path):
|
13
|
+
if file_path != None and not os.path.exists(file_path):
|
14
|
+
raise AttributeError("The file_path is not existed, please check your file path. ")
|
15
|
+
self.__file_path = file_path
|
16
|
+
|
17
|
+
def connect(self):
|
18
|
+
"""
|
19
|
+
建立与 SQLite 数据库的连接
|
20
|
+
"""
|
21
|
+
if self.__file_path == None:
|
22
|
+
raise AttributeError("The file_path is None, you should set db file path before connect. Try the method [set_db_file]. ")
|
23
|
+
try:
|
24
|
+
self.connection = sqlite3.connect(self.__file_path)
|
25
|
+
self.cursor = self.connection.cursor()
|
26
|
+
except sqlite3.Error as e:
|
27
|
+
print(f"连接数据库时出错: {e}")
|
28
|
+
|
29
|
+
def extract_table(self, table_name):
|
30
|
+
"""
|
31
|
+
从指定的表中提取数据
|
32
|
+
:param table_name: 要提取数据的表名
|
33
|
+
:return: 表中的数据列表
|
34
|
+
"""
|
35
|
+
if self.cursor is None:
|
36
|
+
self.connect()
|
37
|
+
try:
|
38
|
+
self.cursor.execute(f"SELECT * FROM {table_name}")
|
39
|
+
rows = self.cursor.fetchall()
|
40
|
+
return rows
|
41
|
+
except sqlite3.Error as e:
|
42
|
+
print(f"从表 {table_name} 提取数据时出错: {e}")
|
43
|
+
return []
|
44
|
+
|
45
|
+
def extract_table_by_columns(self, table_name, column_list:List[str]):
|
46
|
+
"""
|
47
|
+
从指定的表中提取数据
|
48
|
+
:param table_name: 要提取数据的表名
|
49
|
+
:param column_list: 要提取的列名集合
|
50
|
+
:return: 表中的数据列表
|
51
|
+
"""
|
52
|
+
if self.cursor is None:
|
53
|
+
self.connect()
|
54
|
+
try:
|
55
|
+
column_list_sql = ",".join(column_list)
|
56
|
+
self.cursor.execute(f"SELECT {column_list_sql} FROM {table_name}")
|
57
|
+
rows = self.cursor.fetchall()
|
58
|
+
return rows
|
59
|
+
except sqlite3.Error as e:
|
60
|
+
print(f"从表 {table_name} 提取数据时出错: {e}")
|
61
|
+
return []
|
62
|
+
|
63
|
+
def is_table_in_db(self, table_name:str):
|
64
|
+
|
65
|
+
if self.cursor is None:
|
66
|
+
self.connect()
|
67
|
+
try:
|
68
|
+
self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,))
|
69
|
+
result = self.cursor.fetchone()
|
70
|
+
return result
|
71
|
+
except sqlite3.Error as e:
|
72
|
+
print(f"从表 {table_name} 提取数据时出错: {e}")
|
73
|
+
return []
|
74
|
+
|
75
|
+
def close(self):
|
76
|
+
"""
|
77
|
+
关闭数据库连接
|
78
|
+
"""
|
79
|
+
if self.connection:
|
80
|
+
self.connection.close()
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
class RowDataFactory:
|
4
|
+
'''
|
5
|
+
This Class is used to extract data form row_data
|
6
|
+
'''
|
7
|
+
@classmethod
|
8
|
+
def extract_int(cls,row_data:List,index:int):
|
9
|
+
RowDataFactory.__list_index_check(row_data,index)
|
10
|
+
return RowDataFactory.convert_to_int(row_data[index])
|
11
|
+
|
12
|
+
@classmethod
|
13
|
+
def extract_float(cls,row_data:List,index:int):
|
14
|
+
RowDataFactory.__list_index_check(row_data,index)
|
15
|
+
return RowDataFactory.convert_to_float(row_data[index])
|
16
|
+
|
17
|
+
@classmethod
|
18
|
+
def extract_list(cls, row_data:List,index:int):
|
19
|
+
RowDataFactory.__list_index_check(row_data,index)
|
20
|
+
try:
|
21
|
+
result = list(row_data[index].split(','))
|
22
|
+
except SyntaxError:
|
23
|
+
raise TypeError(f"Value: {row_data[index]} cannot be converted to list.")
|
24
|
+
return result
|
25
|
+
|
26
|
+
@classmethod
|
27
|
+
def convert_to_float(cls,string:"str"):
|
28
|
+
try:
|
29
|
+
result = (float)(string)
|
30
|
+
except SyntaxError:
|
31
|
+
raise TypeError(f"Value: {string} cannot be converted to float.")
|
32
|
+
return result
|
33
|
+
|
34
|
+
@classmethod
|
35
|
+
def convert_to_int(cls,string:"str"):
|
36
|
+
try:
|
37
|
+
result = (int)(string)
|
38
|
+
except SyntaxError:
|
39
|
+
raise TypeError(f"Value: {string} cannot be converted to int.")
|
40
|
+
return result
|
41
|
+
|
42
|
+
@classmethod
|
43
|
+
def __list_index_check(cls,row_data:List,index:int):
|
44
|
+
if len(row_data)<=index:
|
45
|
+
raise IndexError("Index out of the range.")
|
@@ -0,0 +1,96 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
ID = "ID"
|
3
|
+
STD_FLR_ID = "StdFlrID"
|
4
|
+
JOINT_ID = "JtID"
|
5
|
+
JOINT_ID_1 = "Jt1ID"
|
6
|
+
JOINT_ID_2 = "Jt2ID"
|
7
|
+
GRID_ID = "GridID"
|
8
|
+
SECTION_ID = "SectID"
|
9
|
+
ECC = "Ecc"
|
10
|
+
ECC_X = "EccX"
|
11
|
+
ECC_Y = "EccY"
|
12
|
+
ROTATION = "Rotation"
|
13
|
+
|
14
|
+
|
15
|
+
FLOOR_NUM = "FlrNo"
|
16
|
+
TOWER_NUM = "TowNo"
|
17
|
+
|
18
|
+
|
19
|
+
class YDBTableName():
|
20
|
+
JOINT_TABLE_NAME = "tblJoint"
|
21
|
+
JOINT_TABLE_USEFUL_COLUMNS = [ID,"X","Y",STD_FLR_ID]
|
22
|
+
|
23
|
+
GRID_TABLE_NAME = "tblGrid"
|
24
|
+
GRID_TABLE_USEFUL_COLUMNS = [ID,JOINT_ID_1,JOINT_ID_2]
|
25
|
+
"""
|
26
|
+
0-ID ,
|
27
|
+
1-Joint1_ID ,
|
28
|
+
2-Joint2_ID ,
|
29
|
+
"""
|
30
|
+
|
31
|
+
COLUMN_SECTION_TABLE_NAME = "tblColSect"
|
32
|
+
BEAM_SECTION_TABLE_NAME = "tblBeamSect"
|
33
|
+
SECTION_TABLE_USEFUL_COLUMNS = [ID,"Mat","Kind","ShapeVal"]
|
34
|
+
|
35
|
+
COLUMN_TABLE_NAME = "tblColSeg"
|
36
|
+
COLUMN_TABLE_USEFUL_COLUMNS = [ID,JOINT_ID,SECTION_ID,ECC_X,ECC_Y,ROTATION]
|
37
|
+
"""
|
38
|
+
0-ID ,
|
39
|
+
1-Joint_ID ,
|
40
|
+
2-Section_ID ,
|
41
|
+
3-EccX ,
|
42
|
+
4-EccY ,
|
43
|
+
5-Rotation
|
44
|
+
"""
|
45
|
+
|
46
|
+
BEAM_TABLE_NAME = "tblBeamSeg"
|
47
|
+
BEAM_TABLE_USEFUL_COLUMNS = [ID,GRID_ID,SECTION_ID,ECC,"HDiff1","HDiff2"]
|
48
|
+
"""
|
49
|
+
0-ID ,
|
50
|
+
1-Grid_ID ,
|
51
|
+
2-Section_ID ,
|
52
|
+
3-Ecc ,
|
53
|
+
4-HDiff1 ,
|
54
|
+
5-HDiff2
|
55
|
+
"""
|
56
|
+
|
57
|
+
RESULT_PERIOD_TABLE = "calEigenInf"
|
58
|
+
RESULT_PERIOD_USEFUL_COLUMNS = ["ModuleID","EigenNo","Period","Angle","CoeffInf","mInf"]
|
59
|
+
"""
|
60
|
+
0-moduleID
|
61
|
+
1-EigenNo
|
62
|
+
2-Period Time
|
63
|
+
3-Angle
|
64
|
+
4-CoeffInf [unknown, xpart_ratio, ypart_ratio, zpart_ratio,
|
65
|
+
the sum of then should be 1]
|
66
|
+
5-MassInfo [unknown, xmass_participate, ymass_par, zmass_par,
|
67
|
+
the sum of all xmass_par should larger than 0.9]
|
68
|
+
"""
|
69
|
+
|
70
|
+
RESULT_MASS_TABLE = "preFlrTowProp"
|
71
|
+
RESULT_MASS_USEFUL_COLUMNS = [FLOOR_NUM,TOWER_NUM,"MassInf"]
|
72
|
+
"""
|
73
|
+
0-floor_num ,
|
74
|
+
1-tower_num ,
|
75
|
+
2-mass_info, list of string, [unknown, dead_load, live_load, plus_load],
|
76
|
+
"""
|
77
|
+
|
78
|
+
RESULT_FLOOR_DATA_TABLE = "dsnStatFlrData"
|
79
|
+
"""包含了大多数楼层计算结果,包括风、地震的各类外力、承载力、刚度等"""
|
80
|
+
RESULT_FLOOR_DATA_USEFUL_COLUMNS_SEISMIC = [
|
81
|
+
FLOOR_NUM,TOWER_NUM,"FlrFXInf","FlrFYInf", # 0 1 2 3
|
82
|
+
"FlrVXInf","FlrVYInf","FlrMXInf","FlrMYInf", # 4 5 6 7
|
83
|
+
]
|
84
|
+
"""
|
85
|
+
0-floor_num ,
|
86
|
+
1-tower_num ,
|
87
|
+
2-X方向地震外力,
|
88
|
+
3-Y方向地震外力,
|
89
|
+
4-X方向地震层间剪力,
|
90
|
+
5-Y方向地震层间剪力,
|
91
|
+
6-X方向地震倾覆力矩,
|
92
|
+
7-Y方向地震倾覆力矩,
|
93
|
+
"""
|
94
|
+
|
95
|
+
|
96
|
+
|
@@ -0,0 +1,224 @@
|
|
1
|
+
from .BuildingDefine import Beam,Column,Joint,ComponentType,Grid
|
2
|
+
from .BuildingDefine import SinglePeriod, Period, MassResult,SingleMassResult
|
3
|
+
from .BuildingDefine import ValuePeer, FloorSeismicResult , SeismicResult
|
4
|
+
from .BuildingDefine.Section import Section,ShapeEnum
|
5
|
+
from .SQLiteConnector import Connector,YDBTableName,RowDataFactory
|
6
|
+
from .YDBType import YDBType
|
7
|
+
import os
|
8
|
+
from typing import List, Dict
|
9
|
+
|
10
|
+
class YDBLoader:
|
11
|
+
|
12
|
+
def __init__(self, file_name:str = None, ydb_type:YDBType = None):
|
13
|
+
# default type is ModelType
|
14
|
+
if not file_name.endswith(".ydb"):
|
15
|
+
raise ValueError("Plase use file ends with .ybd!")
|
16
|
+
self.connector = Connector(file_name)
|
17
|
+
self.ydb_type = self.__check_ydb_type()
|
18
|
+
|
19
|
+
def get_columns(self)->List[Column]:
|
20
|
+
columns = []
|
21
|
+
sections = self.__get_sections(ComponentType.Column)
|
22
|
+
row_data = self.connector.extract_table_by_columns(
|
23
|
+
YDBTableName.COLUMN_TABLE_NAME,
|
24
|
+
YDBTableName.COLUMN_TABLE_USEFUL_COLUMNS
|
25
|
+
)
|
26
|
+
for temp_column in row_data:
|
27
|
+
temp_col_id = RowDataFactory.extract_int(temp_column,0)
|
28
|
+
joint_id = RowDataFactory.extract_int(temp_column,1)
|
29
|
+
sect_id = RowDataFactory.extract_int(temp_column,2)
|
30
|
+
joint = self.__find_joint_by_id(joint_id)
|
31
|
+
sect = [s for s in sections if s.id == sect_id][0]
|
32
|
+
new_column = Column(temp_col_id,joint,sect)
|
33
|
+
columns.append(new_column)
|
34
|
+
return columns
|
35
|
+
|
36
|
+
def get_beams(self)->List[Beam]:
|
37
|
+
beams = []
|
38
|
+
sections = self.__get_sections(ComponentType.Beam)
|
39
|
+
row_data = self.connector.extract_table_by_columns(
|
40
|
+
YDBTableName.BEAM_TABLE_NAME,
|
41
|
+
YDBTableName.BEAM_TABLE_USEFUL_COLUMNS
|
42
|
+
)
|
43
|
+
for temp_beam in row_data:
|
44
|
+
temp_beam_id = RowDataFactory.extract_int(temp_beam,0)
|
45
|
+
grid_id = RowDataFactory.extract_int(temp_beam,1)
|
46
|
+
grid = self.__find_grid_by_id(grid_id)
|
47
|
+
sect_id = RowDataFactory.extract_int(temp_beam,2)
|
48
|
+
sect = [s for s in sections if s.id == sect_id][0]
|
49
|
+
new_beam = Beam(temp_beam_id,grid.start_joint,grid.end_joint,sect)
|
50
|
+
beams.append(new_beam)
|
51
|
+
return beams
|
52
|
+
|
53
|
+
def __get_sections(self,comp_type:ComponentType):
|
54
|
+
table_name = ""
|
55
|
+
table_columns = []
|
56
|
+
table_names_for_different_comptype = {
|
57
|
+
ComponentType.Column:
|
58
|
+
[YDBTableName.COLUMN_SECTION_TABLE_NAME,
|
59
|
+
YDBTableName.SECTION_TABLE_USEFUL_COLUMNS],
|
60
|
+
ComponentType.Beam:
|
61
|
+
[YDBTableName.BEAM_SECTION_TABLE_NAME,
|
62
|
+
YDBTableName.SECTION_TABLE_USEFUL_COLUMNS],
|
63
|
+
}
|
64
|
+
if (comp_type not in table_names_for_different_comptype.keys()):
|
65
|
+
raise ValueError(f"{comp_type.name} is not suppported yet.")
|
66
|
+
# 这里根据不同的构件类型,进行不同的截面数据获取
|
67
|
+
table_name = table_names_for_different_comptype[comp_type][0]
|
68
|
+
table_columns = table_names_for_different_comptype[comp_type][1]
|
69
|
+
row_data = self.connector.extract_table_by_columns(table_name,table_columns)
|
70
|
+
sections = []
|
71
|
+
for temp_section in row_data:
|
72
|
+
temp_section_id = RowDataFactory.extract_int(temp_section,0)
|
73
|
+
# 这里的mat暂时没用到
|
74
|
+
mat = RowDataFactory.extract_int(temp_section,1)
|
75
|
+
kind = RowDataFactory.extract_int(temp_section,2)
|
76
|
+
shape_val = RowDataFactory.extract_list(temp_section,3)[1:]
|
77
|
+
new_section = Section(temp_section_id,ShapeEnum.ConvertToShapeEnum(kind),shape_val,mat)
|
78
|
+
sections.append(new_section)
|
79
|
+
return sections
|
80
|
+
|
81
|
+
def __get_joints(self)->Dict[int,Joint]:
|
82
|
+
if hasattr(self, 'joint_list'):
|
83
|
+
return self.joint_list
|
84
|
+
table_name = YDBTableName.JOINT_TABLE_NAME
|
85
|
+
useful_columns = YDBTableName.JOINT_TABLE_USEFUL_COLUMNS
|
86
|
+
row_data = self.connector.extract_table_by_columns(table_name,useful_columns)
|
87
|
+
joint_list = {}
|
88
|
+
for temp_joint in row_data:
|
89
|
+
temp_joint_id = RowDataFactory.extract_int(temp_joint,0)
|
90
|
+
x = RowDataFactory.extract_float(temp_joint,1)
|
91
|
+
y = RowDataFactory.extract_float(temp_joint,2)
|
92
|
+
std_flr_id = RowDataFactory.extract_int(temp_joint,3)
|
93
|
+
new_joint = Joint(temp_joint_id,x,y,std_flr_id)
|
94
|
+
joint_list[temp_joint_id] = new_joint
|
95
|
+
self.joint_list = joint_list
|
96
|
+
return self.joint_list
|
97
|
+
|
98
|
+
def __get_grids(self)->Dict[int,Grid]:
|
99
|
+
if hasattr(self, 'grid_list'):
|
100
|
+
return self.grid_list
|
101
|
+
table_name = YDBTableName.GRID_TABLE_NAME
|
102
|
+
useful_columns = YDBTableName.GRID_TABLE_USEFUL_COLUMNS
|
103
|
+
row_data = self.connector.extract_table_by_columns(table_name,useful_columns)
|
104
|
+
grid_list = {}
|
105
|
+
for temp_grid in row_data:
|
106
|
+
temp_grid_id = RowDataFactory.extract_int(temp_grid,0)
|
107
|
+
start_joint_id = RowDataFactory.extract_int(temp_grid,1)
|
108
|
+
end_joint_id = RowDataFactory.extract_int(temp_grid,2)
|
109
|
+
s_joint = self.__find_joint_by_id(start_joint_id)
|
110
|
+
e_joint = self.__find_joint_by_id(end_joint_id)
|
111
|
+
grid = Grid(temp_grid_id,s_joint, e_joint)
|
112
|
+
grid_list[temp_grid_id] = grid
|
113
|
+
self.grid_list = grid_list
|
114
|
+
return self.grid_list
|
115
|
+
|
116
|
+
def __check_ydb_type(self)->YDBType:
|
117
|
+
if self.connector.is_table_in_db(YDBTableName.JOINT_TABLE_NAME):
|
118
|
+
return YDBType.ModelYDB
|
119
|
+
if self.connector.is_table_in_db(YDBTableName.RESULT_PERIOD_TABLE):
|
120
|
+
return YDBType.ResultYDB
|
121
|
+
raise ValueError("This ydb database is not Model YDB neither Result YDB. Please use correct ydb file.")
|
122
|
+
|
123
|
+
def __find_joint_by_id(self,joint_id:int)->Joint:
|
124
|
+
joint_list = self.__get_joints()
|
125
|
+
try:
|
126
|
+
return joint_list[joint_id]
|
127
|
+
except KeyError:
|
128
|
+
raise ValueError(f"No Joint's ID is {joint_id}.")
|
129
|
+
|
130
|
+
def __find_grid_by_id(self,grid_id:int)->Grid:
|
131
|
+
grid_list = self.__get_grids()
|
132
|
+
try:
|
133
|
+
return grid_list[grid_id]
|
134
|
+
except KeyError:
|
135
|
+
raise ValueError(f"No Joint's ID is {grid_id}.")
|
136
|
+
|
137
|
+
def __check_result_model(self, extracting_data_type):
|
138
|
+
if self.ydb_type != YDBType.ResultYDB:
|
139
|
+
raise TypeError("This model is not ResultYDB file, "+
|
140
|
+
f"dont have {extracting_data_type} result, please retry.")
|
141
|
+
|
142
|
+
def get_mass_result(self)->MassResult:
|
143
|
+
self.__check_result_model("mass")
|
144
|
+
table_name = YDBTableName.RESULT_MASS_TABLE
|
145
|
+
useful_columns = YDBTableName.RESULT_MASS_USEFUL_COLUMNS
|
146
|
+
row_data = self.connector.extract_table_by_columns(table_name,useful_columns)
|
147
|
+
mass_list = []
|
148
|
+
for temp_mass in row_data:
|
149
|
+
floor_num = RowDataFactory.convert_to_int(temp_mass,0)
|
150
|
+
tower_num = RowDataFactory.convert_to_int(temp_mass,1)
|
151
|
+
mass_info = RowDataFactory.extract_list(temp_mass,2)
|
152
|
+
dead_load = RowDataFactory.convert_to_float(mass_info[1])
|
153
|
+
live_load = RowDataFactory.convert_to_float(mass_info[2])
|
154
|
+
# TODO: 需要计算slab的结果
|
155
|
+
slab_area = 10
|
156
|
+
single_mass = SingleMassResult(floor_num,tower_num,dead_load,live_load,slab_area)
|
157
|
+
mass_list.append(single_mass)
|
158
|
+
return MassResult(mass_list)
|
159
|
+
|
160
|
+
def get_period_result(self)->Period:
|
161
|
+
self.__check_result_model("period")
|
162
|
+
table_name = YDBTableName.RESULT_PERIOD_TABLE
|
163
|
+
useful_columns = YDBTableName.RESULT_PERIOD_USEFUL_COLUMNS
|
164
|
+
row_data = self.connector.extract_table_by_columns(table_name,useful_columns)
|
165
|
+
periods = []
|
166
|
+
for temp_period in row_data:
|
167
|
+
module_id = RowDataFactory.extract_int(temp_period,0)
|
168
|
+
if module_id !=1:
|
169
|
+
continue
|
170
|
+
period_index = RowDataFactory.extract_int(temp_period,1)
|
171
|
+
time = RowDataFactory.extract_float(temp_period,2)
|
172
|
+
angle = RowDataFactory.extract_float(temp_period,3)
|
173
|
+
coeff = RowDataFactory.extract_list(temp_period,4)
|
174
|
+
mass_participate = RowDataFactory.extract_list(temp_period,5)
|
175
|
+
period = SinglePeriod(period_index,time,angle
|
176
|
+
,RowDataFactory.convert_to_float(coeff[1])
|
177
|
+
,RowDataFactory.convert_to_float(coeff[2])
|
178
|
+
,RowDataFactory.convert_to_float(coeff[-1])
|
179
|
+
,RowDataFactory.convert_to_float(mass_participate[1])
|
180
|
+
,RowDataFactory.convert_to_float(mass_participate[2])
|
181
|
+
,RowDataFactory.convert_to_float(mass_participate[-1])
|
182
|
+
)
|
183
|
+
periods.append(period)
|
184
|
+
return Period(periods)
|
185
|
+
|
186
|
+
def get_seismic_result(self)->SeismicResult:
|
187
|
+
self.__check_result_model("seismic")
|
188
|
+
table_name = YDBTableName.RESULT_FLOOR_DATA_TABLE
|
189
|
+
useful_columns = YDBTableName.RESULT_FLOOR_DATA_USEFUL_COLUMNS_SEISMIC
|
190
|
+
row_data = self.connector.extract_table_by_columns(table_name,useful_columns)
|
191
|
+
floor_result_list = []
|
192
|
+
for temp_floor in row_data:
|
193
|
+
floor_num = RowDataFactory.extract_int(temp_floor,0)
|
194
|
+
tower_num = RowDataFactory.extract_int(temp_floor,1)
|
195
|
+
force_x = RowDataFactory.convert_to_float(
|
196
|
+
RowDataFactory.extract_list(temp_floor,2)[1])
|
197
|
+
force_y = RowDataFactory.convert_to_float(
|
198
|
+
RowDataFactory.extract_list(temp_floor,3)[1])
|
199
|
+
shear_x = RowDataFactory.convert_to_float(
|
200
|
+
RowDataFactory.extract_list(temp_floor,4)[1])
|
201
|
+
shear_y = RowDataFactory.convert_to_float(
|
202
|
+
RowDataFactory.extract_list(temp_floor,5)[1])
|
203
|
+
moment_x = RowDataFactory.convert_to_float(
|
204
|
+
RowDataFactory.extract_list(temp_floor,6)[1])
|
205
|
+
moment_y = RowDataFactory.convert_to_float(
|
206
|
+
RowDataFactory.extract_list(temp_floor,7)[1])
|
207
|
+
force = ValuePeer(force_x,force_y)
|
208
|
+
shear = ValuePeer(shear_x, shear_y)
|
209
|
+
moment = ValuePeer(moment_x,moment_y)
|
210
|
+
|
211
|
+
temp_floor_result = FloorSeismicResult(floor_num,tower_num,force,shear,moment)
|
212
|
+
floor_result_list.append(temp_floor_result)
|
213
|
+
|
214
|
+
return SeismicResult(floor_result_list)
|
215
|
+
|
216
|
+
|
217
|
+
if __name__ == "__main__":
|
218
|
+
file_path = "testfiles/dtlmodel1.ydb"
|
219
|
+
loader = YDBLoader(file_path)
|
220
|
+
columns = loader.get_columns()
|
221
|
+
|
222
|
+
for col in columns:
|
223
|
+
print(col.section,col.joint)
|
224
|
+
|
CivilTools/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
from . import YDBLoader, ReportGenerator,FigureGenerator,DXFGenerator
|