data_process_ui/app/script/create_linear_feature.py

168 lines
4.7 KiB
Python
Raw Normal View History

2026-01-12 09:21:42 +08:00
# 生成线元要素表
import copy
import numpy
#直曲表
sheet_align = sheet("alignment_table")
#线元数据表
sheet_linear = sheet("linear_feature")
#生成线元数据
sheet_linear.clear_content()
row1 = 3
row2 = 0
epsilon = 0.0005
sheet_linear[row2, 0].value = sheet_align[row1, 3].value
sheet_linear[row2, 6].value = sheet_align[row1 + 1, 20].value
sheet_linear[row2, 7].value = sheet_align[row1, 1].value
sheet_linear[row2, 8].value = sheet_align[row1, 2].value
row1 += 1
row2 += 1
while not sheet_align[row1, 6].empty():
sheet_linear[row2, 0].value = sheet_align[row1, 13].value
if abs(sheet_linear[row2, 0].value - sheet_linear[row2 - 1, 0].value) > epsilon:
sheet_linear[row2, 2].value = 0
sheet_linear[row2, 3].value = 0
row2 += 1
sheet_linear[row2, 0].value = sheet_align[row1, 14].value
if abs(sheet_linear[row2, 0].value - sheet_linear[row2 - 1, 0].value) > epsilon:
sheet_linear[row2, 2].value = 0
sheet_linear[row2, 3].value = sheet_align[row1, 6].value * sheet_align[row1, 21].value
row2 += 1
sheet_linear[row2, 0].value = sheet_align[row1, 16].value
if abs(sheet_linear[row2, 0].value - sheet_linear[row2 - 1, 0].value) > epsilon:
sheet_linear[row2, 2].value = sheet_align[row1, 6].value * sheet_align[row1, 21].value
sheet_linear[row2, 3].value = sheet_linear[row2, 2].value
row2 += 1
sheet_linear[row2, 0].value = sheet_align[row1, 17].value
if abs(sheet_linear[row2, 0].value - sheet_linear[row2 - 1, 0].value) > epsilon:
sheet_linear[row2, 2].value = sheet_align[row1, 6].value * sheet_align[row1, 21].value
sheet_linear[row2, 3].value = 0
row2 += 1
row1 += 1
sheet_linear[row2, 0].value = sheet_align[row1, 3].value
sheet_linear[row2, 2].value = 0
sheet_linear[row2, 3].value = 0
#线元要素计算
def calc_linear_type(x, y):
#0-圆曲线1-直线2-缓和曲线
epsilon = 0.00001
if abs(x - y) >= epsilon:
return 2
if abs(x) < epsilon:
return 1
return 0
# 定义桩点
class stake_point:
def __init__(
self, chainage = 0, x = 0, y = 0, z = 0,
alpha = 0, beta = 0, rho = 0
):
self.chainage = chainage #里程
self.x = x #x坐标
self.y = y #y坐标
self.z = z #高程
self.alpha = alpha #切线方位角
self.beta = beta #
self.rho = rho #曲率
# 缓和曲线
# 起点里程、曲率、坐标、切线方位角以及终点里程、曲率确定一条缓和曲线
class curve:
def __init__(self, start = None, end = None):
if start is None:
self.start = stake_point()
else:
self.start = copy.copy(start) #起始桩点
if end is None:
self.end = stake_point()
else:
self.end = copy.copy(end) #终止桩点
# 求缓和曲线曲率变化参数
def get_ratio(self):
return math.sqrt((self.end.chainage - self.start.chainage) / abs(self.end.rho - self.start.rho))
# 求里程为chainage的一点处的曲率、坐标及切线方位角采用Gauss-Legendre公式计算
def get_point(self, chainage):
l = chainage - self.start.chainage
ll = self.end.chainage - self.start.chainage
if abs(ll) < 0.001:
return copy.copy(self.start)
sp = stake_point(chainage = chainage)
# 求点的切线方位角及曲率
sp.rho = self.start.rho + (self.end.rho - self.start.rho) * l / ll # 曲率线性变化
sp.alpha = self.start.alpha + (self.start.rho + sp.rho) * l / 2
sp.alpha %= 2 * math.pi
f = np.zeros((2, 4), dtype = np.float64)
f[0, 0] = 0.0694318442
f[0, 1] = 0.3300094782
f[0, 2] = 1 - f[0, 1]
f[0, 3] = 1 - f[0, 0]
f[1, 0] = 0.1739274226
f[1, 1] = 0.3260725774
f[1, 2] = f[1, 1]
f[1, 3] = f[1, 0]
s1 = 0
s2 = 0
a0 = self.start.alpha
c0 = self.start.rho
c1 = self.end.rho
h = (c1 - c0) * l * l / (2 * ll)
for i in range(4):
s1 = s1 + f[1, i] * math.cos(a0 + c0 * l * f[0, i] + h * f[0, i] * f[0, i])
s2 = s2 + f[1, i] * math.sin(a0 + c0 * l * f[0, i] + h * f[0, i] * f[0, i])
sp.x = self.start.x + l * s1
sp.y = self.start.y + l * s2
return sp
row = 1
with sheet_linear:
while not cell(row, 0).empty():
cell(row, 1).value = cell(row, 0).value - cell(row - 1, 0).value
if cell(row, 2).value != 0:
cell(row, 4).value = 1 / cell(row, 2).value
if cell(row, 3).value != 0:
cell(row, 5).value = 1 / cell(row, 3).value
cell(row, 9).value = calc_linear_type(cell(row, 2).value, cell(row, 3).value)
cv = curve()
cv.start.chainage = cell(row - 1, 0).value
cv.start.rho = (cell(row, 4).value or 0)
cv.start.alpha = cell(row - 1, 6).value
cv.start.x = cell(row - 1, 7).value
cv.start.y = cell(row - 1, 8).value
cv.end.chainage = cell(row, 0).value
cv.end.rho = (cell(row, 5).value or 0)
if cell(row, 9).value == 2:
cell(row, 10).value = cv.get_ratio()
sp = cv.get_point(cv.end.chainage)
cell(row, 6).value = sp.alpha
cell(row, 7).value = sp.x
cell(row, 8).value = sp.y
row += 1
sheet_linear.fit_content()