完成了自动生成排位数据文件的功能

This commit is contained in:
n3040 2022-01-18 14:14:00 +08:00
parent bece894a0c
commit 7ad5ad4c70
6 changed files with 282 additions and 65 deletions

105
dem.py
View File

@ -1,15 +1,21 @@
import math
import os
import shutil
import tomli
import ezdxf
from ezdxf.tools.standards import linetypes
from osgeo import gdal
import numpy as np
import pandas as pd
from pw import DFile, ControlFile
import dem_utils
ezdxf.options.set(
"odafc-addon",
"win_exec_path",
"d:/ProgramFiles/ODAFileConverter/ODAFileConverter.exe",
)
from ezdxf.addons.odafc import export_dwg
class Dem:
def __init__(self, toml_path):
@ -18,6 +24,7 @@ class Dem:
self._toml_dict = toml_dict
dem_file_path = toml_dict["parameter"]["dem_file_path"]
self._dataset = gdal.Open(dem_file_path)
self._dem_resolution = self._dataset.GetGeoTransform()[1]
def get_dem_info(self, if_print=False):
"""Get the information of DEM data.
@ -46,6 +53,7 @@ class Dem:
def write_dxf(self):
excel_pfs = self._read_path_file()
segments = []
for foo in range(len(excel_pfs) - 1):
start_point_name: str = excel_pfs.iloc[foo, 0]
end_point_name: str = excel_pfs.iloc[foo + 1, 0]
@ -59,34 +67,34 @@ class Dem:
left_elevation = self.get_elevation(line_coordination[:, 0:2])
center_elevation = self.get_elevation(line_coordination[:, 2:4])
right_elevation = self.get_elevation(line_coordination[:, 4:6])
doc = ezdxf.new(dxfversion="R2010")
dm_doc = ezdxf.new(dxfversion="R2004")
# 设置线形
# for name, desc, pattern in linetypes():
# if name not in doc.linetypes:
# doc.linetypes.add(
# if name not in dm_doc.linetypes:
# dm_doc.linetypes.add(
# name=name,
# pattern=pattern,
# description=desc,
# )
msp = doc.modelspace()
dm_msp = dm_doc.modelspace()
x_axis = [0]
cord_0 = line_coordination[0, 2:4] # 取中线的
for cord in line_coordination[1:, 2:4]:
x_axis.append(dem_utils.distance(cord, cord_0))
msp.add_polyline2d(
dm_msp.add_polyline2d(
[
(x_axis[i] / 5, left_elevation[i] * 2)
for i in range(len(left_elevation))
],
dxfattribs={"color": 1},
) # 红色
msp.add_polyline2d(
dm_msp.add_polyline2d(
[
(x_axis[i] / 5, center_elevation[i] * 2)
for i in range(len(center_elevation))
]
)
msp.add_polyline2d(
dm_msp.add_polyline2d(
[
(x_axis[i] / 5, right_elevation[i] * 2)
for i in range(len(right_elevation))
@ -96,10 +104,66 @@ class Dem:
toml_dict = self._toml_dict
out_dxf_file_dir = toml_dict["parameter"]["out_dxf_file_dir"]
os.makedirs(out_dxf_file_dir, exist_ok=True)
dem_prefix = toml_dict["parameter"]["dem_prefix"]
doc.saveas(
f"{out_dxf_file_dir}/{dem_prefix}{start_point_name}_{end_point_name}.dxf"
# dm_doc.saveas(
# f"{out_dxf_file_dir}/D{400+int(start_point_name[1:])}.dxf"
# ) # 写断面文件
export_dwg(
dm_doc,
f"{out_dxf_file_dir}/D{100+int(start_point_name[1:])}.dwg",
replace=True,
) # 写断面文件
# 写Z文件
with open(
f"{out_dxf_file_dir}/ZD{100+int(start_point_name[1:])}", "w"
) as z_file:
z_file.write("0 ")
z_file.write(f"{center_elevation[0]*2} ")
z_file.write("0 ")
z_file.write("0 ")
z_file.write(f"{center_elevation[0]*2-50}")
# TODO:写平面文件
# plate_doc = ezdxf.new(dxfversion="R2010")
# plate_msp = plate_doc.modelspace()
# plate_msp.add_polyline2d(
# line_coordination[:, 0:2],
# dxfattribs={"color": 1},
# ) # 红色
# plate_msp.add_polyline2d(
# line_coordination[:, 2:4],
# )
# plate_msp.add_polyline2d(
# line_coordination[:, 4:6],
# dxfattribs={"color": 5},
# ) # 蓝色
# plate_doc.saveas(f"{out_dxf_file_dir}/plate.dxf")
mileage = [0]
start_point = line_coordination[0, 2:4]
for bar in line_coordination[1:, 2:4]:
mileage.append(round(dem_utils.distance(start_point, bar)))
mileage = np.array(mileage)
start_num = 4000 + int(start_point_name[1:])
segments.append(start_num)
end_num = 4000 + int(end_point_name[1:])
if foo == len(excel_pfs) - 2:
segments.append(end_num)
d_file = DFile(
start_num,
end_num,
mileage,
center_elevation,
left_elevation,
right_elevation,
)
d_file.save(out_dxf_file_dir)
self._copy_db_file()
tower_start_num = toml_dict["parameter"]["tower_number_start"]
control_file_template_path = toml_dict["parameter"][
"control_file_template_path"
]
c_file = ControlFile(
segments, tower_start_num, control_file_template_path, out_dxf_file_dir
)
c_file.save()
def get_elevation(self, site_x_y):
"""Get the elevation of given locations from DEM in GCS.
@ -192,14 +256,15 @@ class Dem:
+ equation_c[3]
)
site_ele[i] = point_z
print(f"row:{Yline} col:{Xpixel} elev:{site_ele[i]}")
# print(f"row:{Yline} col:{Xpixel} elev:{site_ele[i]}")
return site_ele
def to_line_coordination(self, point_x_s, point_y_s, point_x_e, point_y_e):
path_length = (
(point_x_s - point_x_e) ** 2 + (point_y_s - point_y_e) ** 2
) ** 0.5
n = round(path_length / 1)
dem_resolution = self._dem_resolution # dem的精度
n = round(path_length / dem_resolution)
center_point_x = np.linspace(point_x_s, point_x_e, n, endpoint=True)
center_point_y = np.linspace(point_y_s, point_y_e, n, endpoint=True)
# 计算左右边线
@ -234,3 +299,13 @@ class Dem:
path_file = toml_dict["parameter"]["path_file"]
excel_pds = pd.read_excel(path_file)
return excel_pds
def _copy_db_file(self):
toml_dict = self._toml_dict
db_file_dir = toml_dict["parameter"]["db_file_dir"]
out_dxf_file_dir = toml_dict["parameter"]["out_dxf_file_dir"]
shutil.copy(f"{db_file_dir}/Tower.db", f"{out_dxf_file_dir}/Tower.db")
shutil.copy(f"{db_file_dir}/ATMOS.db", f"{out_dxf_file_dir}/ATMOS.db")
shutil.copy(f"{db_file_dir}/Fit.db", f"{out_dxf_file_dir}/Fit.db")
shutil.copy(f"{db_file_dir}/RULE.db", f"{out_dxf_file_dir}/RULE.db")
shutil.copy(f"{db_file_dir}/WIRE.db", f"{out_dxf_file_dir}/WIRE.db")

View File

@ -1,7 +1,5 @@
if __name__ == "__main__":
import transformer.exporter as exporter
exporter.main()
print("PyCharm")

72
pw.py Normal file
View File

@ -0,0 +1,72 @@
import numpy as np
# D文件
class DFile:
def __init__(
self, start_num, end_num, mileage: np.ndarray, center_z, left_z, right_z
):
self.start_num = start_num
self.end_num = end_num
self._mileage = mileage
self._center_z = center_z
self._left_z = left_z
self._right_z = right_z
pass
def save(self, out_dir):
start_num = self.start_num
end_num = self.end_num
mileage = self._mileage
center_z = self._center_z
left_z = self._left_z
right_z = self._right_z
mat = np.zeros((mileage.size, 5))
mat[0, 0] = start_num
mat[-1, 0] = end_num
mat[:, 1] = mileage
mat[:, 2] = center_z
mat[:, 3] = left_z
mat[:, 4] = right_z
with open(f"{out_dir}/D{100+start_num-4000}.txt", "w") as d_file:
for foo in mat:
d_file.write(f"{foo[0]:.0f}\t")
d_file.write(f"{foo[1]:.0f}\t")
d_file.write(f"{foo[2]}\t")
d_file.write(f"{foo[3]}\t")
d_file.write(f"{foo[4]}\t")
d_file.write("\n")
with open(f"{out_dir}/X{100+start_num-4000}.txt", "w") as x_file:
x_file.write("dm\n")
x_file.write(f"{mileage.size}\n")
x_file.write("0\n")
x_file.write(f"{mileage.size*3}\n")
x_file.write("1\n")
x_file.write("0\n")
x_file.write("0\n")
pass
class ControlFile:
def __init__(self, segments, tower_start_number, c_file_template_path, out_dir):
self._c_file_template_path = c_file_template_path
self._out_dir = out_dir
self._segments = segments
self._tower_start_number = tower_start_number
pass
def save(self):
c_file_template_path = self._c_file_template_path
out_dir = self._out_dir
segments = self._segments
tower_start_number = self._tower_start_number
with open(c_file_template_path) as c_file_template:
c_template = c_file_template.read()
c_template=c_template.replace("{SEGMENT_N}", str(len(segments)))
c_template=c_template.replace("{TOWER_NUM_START}", f'{tower_start_number}')
c_template=c_template.replace("{SEGMENT}", "\n".join([str(seg-4000+100) for seg in segments]))
c_template=c_template.replace("{SEGMENT_S}", f"{segments[0]-4000+100}")
c_template=c_template.replace("{SEGMENT_E}", f"{segments[-1]-4000+100}")
c_template=c_template.replace("{CONTROL_FILE}", f"S{segments[0]-4000+100}")
with open(f"{out_dir}/C{segments[0]-4000+100}.dat", "w") as c_file:
c_file.write(c_template)

View File

@ -12,8 +12,9 @@ class Projector:
EPSG_WGS_84 = "epsg:4326"
EPSG_Xian_1980_105E = "epsg:4507"
EPSG_CGCS_2000_105E = "epsg:4507"
EPSG_CGCS_2000_108E = "epsg:4545"
EPSG_Xian_1980_114E = "epsg:2383"
# _transformer_84_yx = Transformer.from_crs("epsg:4326", "epsg:4507")
# _transformer_yx_84 = Transformer.from_crs("epsg:4507", "epsg:4326")

View File

@ -16,17 +16,15 @@ def prettify(elem):
def main():
df = pd.read_excel("成果表-0120.xlsx")
needed_df = df.iloc[:120, :3]
trans = transformer.Projector(
transformer.EPSG_CGCS_2000_108E, transformer.EPSG_WGS_84
)
y_array = needed_df["北坐标(m)"].to_numpy()
x_array = needed_df["东坐标(m)"].to_numpy()
df = pd.read_excel("杆塔成果表(左侧)-复测.xls")
needed_df = df.iloc[:85, :]
trans = transformer.Projector(transformer.EPSG_Xian_1980_114E, transformer.EPSG_WGS_84)
y_array = needed_df["北坐标"].to_numpy()
x_array = needed_df["东坐标"].to_numpy()
yx_array = np.array([y_array, x_array]).transpose()
wgs_84_point = np.array([trans.transform(y, x) for y, x in yx_array])
name_lat_lon_df = pd.DataFrame(
{"桩号": needed_df["点号"], "纬度": wgs_84_point[:, 0], "经度": wgs_84_point[:, 1]}
{"桩号": needed_df["杆塔"], "纬度": wgs_84_point[:, 0], "经度": wgs_84_point[:, 1]}
)
ET.register_namespace("", "http://www.opengis.net/kml/2.2")
ns = {
@ -61,5 +59,5 @@ def main():
"{lon},{lat},{elevation}".format(lon=foo[1], lat=foo[0], elevation=foo[2])
for foo in line_coordination_list
)
with open("out.kml", "w", encoding="utf-8") as f:
with open("周口.kml", "w", encoding="utf-8") as f:
f.write(prettify(xml_root).decode("utf-8"))

View File

@ -4,14 +4,84 @@ import ezdxf
from data_types import WGS84Point
import transformer
import numpy as np
from functools import singledispatch
from typing import Tuple
def generate_wgs_84_point(point_start: WGS84Point, point_end: WGS84Point, n_point):
_transformer_84_yx = transformer.Projector("epsg:4326", "epsg:4507")
class Plane:
# dem文件坐标系统
def __init__(self, dem_system, plane_system, dem_path):
self._dem_path = dem_path
self._dem_system = dem_system
self._start_84_point = None
self._end_84_point = None
self._plane_system = plane_system
self._transformer_84_to_dem_ = transformer.Projector(
transformer.EPSG_WGS_84, dem_system
)
self._transformer_dem_to_84 = transformer.Projector(
dem_system, transformer.EPSG_WGS_84
)
@singledispatch
def set_line(self, start: WGS84Point, end: WGS84Point):
self._start_84_point = start
self._end_84_point = end
pass
# def set_line_xy(self, start: Tuple[float], end: Tuple[float]):
@set_line.register(tuple)
def set_line_yx(self, start: Tuple[float, float], end: Tuple[float, float]):
_transformer = self._transformer_dem_to_84
start_wgs_84 = self._transformer_dem_to_84.transform(*start)
end_wgs_84 = self._transformer_dem_to_84.transform(*end)
self._start_84_point = WGS84Point(start_wgs_84[0], start_wgs_84[1], 0)
self._end_84_point = WGS84Point(end_wgs_84[0], end_wgs_84[1], 0)
pass
def get_elevation(self, n):
point_start = self._start_84_point
point_end = self._end_84_point
all_wgs_84_point = self._generate_wgs_84_point(point_start, point_end, n)
# 转换为DEM的坐标
transformer_dem_to_84 = self._transformer_84_to_dem_
all_dem_point = np.array(
[
transformer_dem_to_84.transform(y_lat, x_lon)
for y_lat, x_lon in all_wgs_84_point[:, [0, 1]]
]
)
dem_gcs = dem.Dem(self._dem_path)
elevation_in_line = dem_gcs.get_elevation(all_dem_point)
return np.array(elevation_in_line)
# 计算档距
def cal_span(self):
start = self._start_84_point
end = self._end_84_point
_transformer_84_yx = transformer.Projector(
transformer.EPSG_WGS_84, transformer.EPSG_Xian_1980_114E
)
start_point = np.array(
_transformer_84_yx.transform(start.latitude, start.longitude)
)
end_point = np.array(_transformer_84_yx.transform(end.latitude, end.longitude))
return int(np.round(np.sum((start_point - end_point) ** 2) ** 0.5))
def _generate_wgs_84_point(
self, point_start: WGS84Point, point_end: WGS84Point, n_point
):
plane_system = self._plane_system
_transformer_84_yx = transformer.Projector(
transformer.EPSG_WGS_84, plane_system
)
start_y, start_x = _transformer_84_yx.transform(
point_start.latitude, point_start.longitude
)
end_y, end_x = _transformer_84_yx.transform(point_end.latitude, point_end.longitude)
end_y, end_x = _transformer_84_yx.transform(
point_end.latitude, point_end.longitude
)
# 插入点
x_linspace = np.linspace(start_x, end_x, n_point)
y_linspace = np.linspace(start_y, end_y, n_point)
@ -19,9 +89,14 @@ def generate_wgs_84_point(point_start: WGS84Point, point_end: WGS84Point, n_poin
point_start.elevation, point_end.elevation, n_point
)
yxz_point = np.array([y_linspace, x_linspace, elevation_linspace]).transpose()
_transformer_yx_84 = transformer.Projector("epsg:4507", "epsg:4326")
_transformer_yx_84 = transformer.Projector(
plane_system, transformer.EPSG_WGS_84
)
wgs_84_point = np.array(
[np.array(_transformer_yx_84.transform(y, x)) for y, x, _elevation in yxz_point]
[
np.array(_transformer_yx_84.transform(y, x))
for y, x, _elevation in yxz_point
]
)
return wgs_84_point
@ -40,28 +115,26 @@ def draw_dxf(elevation_in_line, interval, dxf_path):
/ 5
) # 平滑用
func = interpolate.interp1d(points[0, :], points[1, :], kind="cubic")
msp.add_polyline2d([(x + 10, func(x)) for x in new_x_axis])
# msp.add_polyline2d([(x + 10, func(x)) for x in new_x_axis])
msp.add_polyline2d([(x + 10, y) for x, y in points.transpose()])
doc.saveas(dxf_path)
# 计算档距
def cal_span(start: WGS84Point, end: WGS84Point):
_transformer_84_yx = transformer.Projector("epsg:4326", "epsg:4507")
start_point = np.array(
_transformer_84_yx.transform(start.latitude, start.longitude)
)
end_point = np.array(_transformer_84_yx.transform(end.latitude, end.longitude))
return np.round(np.sum((start_point - end_point) ** 2) ** 0.5)
def main():
dem_gcs = dem.Dem(r"d:\宁夏自治区.tif")
dem_gcs.get_dem_info(if_print=False)
start_point = WGS84Point(36.74138039, 105.58954375, 1670)
end_point = WGS84Point(36.72869989, 105.61023855, 1718)
span = int(cal_span(start_point, end_point))
_plane = Plane(
transformer.EPSG_Xian_1980_114E, transformer.EPSG_Xian_1980_114E, r"d:\307.tif"
)
# start_point = WGS84Point(33.24643289, 114.58574497, 28)
# end_point = WGS84Point(33.22873308, 114.57951634, 28)
_plane.set_line_yx((3680231.27, 554470.91), (3678264.93, 553901.32))
span = _plane.cal_span()
print("档距 {span}".format(span=span))
wgs_84_point_in_line = generate_wgs_84_point(start_point, end_point, span)
elevation_in_line = dem_gcs.get_elevation(wgs_84_point_in_line)
draw_dxf(elevation_in_line, 1, "a.dxf")
elevation_in_line = _plane.get_elevation(int(span / 5))
# dem_gcs = dem.Dem()
# dem_gcs.get_dem_info(if_print=False)
#
# span = int(cal_span(start_point, end_point))
# print("档距 {span}".format(span=span))
# wgs_84_point_in_line = generate_wgs_84_point(start_point, end_point, span)
# elevation_in_line = dem_gcs.get_elevation(wgs_84_point_in_line)
draw_dxf(elevation_in_line, 5, "a.dxf")