Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
A
auto_join_edge
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xuebingbing
auto_join_edge
Commits
c7cf5b29
Commit
c7cf5b29
authored
Sep 02, 2020
by
xuebingbing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
熊超的积累更新
parent
e0c51e5d
Pipeline
#501
failed with stages
Changes
8
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
299 additions
and
133 deletions
+299
-133
connect_mesh.py
connect_solution/connect_mesh.py
+0
-0
main.py
main.py
+54
-35
data_interpolation.py
math_tools/data_interpolation.py
+1
-29
douglas_peucker_2d.py
math_tools/douglas_peucker_2d.py
+16
-20
savitsky_golay_filter.py
math_tools/savitsky_golay_filter.py
+1
-1
smoothing_elevation.py
smoothing_elevation.py
+159
-0
common.py
util/common.py
+22
-2
geographic_tool.py
util/geographic_tool.py
+46
-46
No files found.
connect_solution/connect_mesh.py
View file @
c7cf5b29
This diff is collapsed.
Click to expand it.
main.py
View file @
c7cf5b29
...
...
@@ -7,6 +7,7 @@ import sys
import
os
from
osgeo
import
osr
,
ogr
,
gdal
import
csv
from
PyQt5.QtCore
import
*
from
util
import
const
from
connect_solution.connect_mesh
import
ConnectMeshByMeshList
...
...
@@ -77,7 +78,7 @@ def get_adjacent_mesh_box(mesh_id, box_layer, output_info1):
mesh_ids
=
[]
for
_
in
range
(
mesh_box_count
):
mesh_box_feature
=
box_layer
.
GetNextFeature
()
if
mesh_box_feature
is
None
or
mesh_box_feature
[
const
.
MESH_ID
]
==
mesh_id
:
if
mesh_box_feature
is
None
:
continue
mesh_ids
.
append
(
mesh_box_feature
[
const
.
MESH_ID
])
box_layer
.
SetSpatialFilter
(
None
)
# 消除空间过滤
...
...
@@ -85,8 +86,15 @@ def get_adjacent_mesh_box(mesh_id, box_layer, output_info1):
return
mesh_ids
def
get_current_time
():
data
=
QDateTime
.
currentDateTime
()
currTime
=
data
.
toString
(
"yyyy-MM-dd hh:mm:ss"
)
return
currTime
def
run
(
connect_postgresql
,
sheet_designation_path
,
mesh_box_path
,
output_document_path
):
# 参数依次为pg库连接字符串、图幅号文件路径,图幅框文件路径、输出文档路径
print
(
str
(
get_current_time
())
+
": 程序运行开始"
)
output_info1
,
output_info2
,
output_info3
=
[],
[],
[]
output_info
=
"*****"
+
'-'
*
13
+
"有关topo图层/图幅框图层没有字段的异常信息,大概率是上游数据的命名不符合规范的问题"
+
\
'-'
*
14
+
"*****"
...
...
@@ -99,47 +107,47 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume
output_info
=
"传入的数据库处理字符串不是PG库,请确认后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
hd_data_source
=
ogr
.
Open
(
connect_postgresql
,
1
)
if
hd_data_source
is
None
:
output_info
=
"根据连接字符串获取不到数据库,请确认后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
if
os
.
path
.
exists
(
sheet_designation_path
)
is
False
:
output_info
=
"根据输入的图幅号列表文件路径,找不到指定的文件,请确认后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
if
sheet_designation_path
[
-
3
:]
.
lower
()
!=
'txt'
:
output_info
=
"传入的图幅号列表文件的格式不是txt格式,运行结束"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
if
os
.
path
.
exists
(
mesh_box_path
)
is
False
:
output_info
=
"根据输入的图幅框文件路径没有获取到图幅框文件,请确认后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
if
mesh_box_path
[
-
4
:]
!=
'gpkg'
:
output_info
=
"传入的图幅框文件格式不是gpkg格式,请确认后重试"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
mesh_box_data_source
=
ogr
.
Open
(
mesh_box_path
,
1
)
if
mesh_box_data_source
is
None
:
output_info
=
"图幅框文件中没有任何数据,请确认后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
mesh_box_layer
=
mesh_box_data_source
.
GetLayerByName
(
const
.
MESH_BOX_LAYER_NAME
)
if
mesh_box_layer
is
None
:
output_info
=
"从输入的图幅框文件中无法获取图幅框图层,请查验后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
if
mesh_box_layer
.
FindFieldIndex
(
const
.
MESH_ID
,
False
)
==
-
1
:
output_info
=
"图幅框图层没有图幅号字段或者图幅号字段的字段名不符合规格文件的命名,程序自动改名"
output_info2
.
append
(
output_info
)
...
...
@@ -149,7 +157,7 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume
output_info
=
"图幅框的图幅号字段更改失败,请反馈给研发"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
else
:
field_name
=
ogr
.
FieldDefn
(
const
.
MESH_ID
,
ogr
.
OFTString
)
if
mesh_box_layer
.
AlterFieldDefn
(
field_index
,
field_name
,
ogr
.
ALTER_NAME_FLAG
)
==
ogr
.
OGRERR_NONE
:
...
...
@@ -163,28 +171,29 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume
output_info
=
"输入接边信息文档的路径不是有效的路径,请确认后重试"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
mesh_ids
=
get_mesh_list
(
sheet_designation_path
,
output_info1
)
if
len
(
mesh_ids
)
<
1
:
output_info
=
"传入的图幅号列表文件中没有图幅号,请查验后重试!"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
try
:
for
mesh_id
in
mesh_ids
:
new_mesh_ids
=
get_adjacent_mesh_box
(
mesh_id
,
mesh_box_layer
,
output_info1
)
if
not
new_mesh_ids
:
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
for
new_mesh_id
in
new_mesh_ids
:
if
not
RefreshTopoNext
()
.
run
(
hd_data_source
,
new_mesh_id
):
output_info
=
"调用上游程序,未能成功刷新图幅边界上topo点的前驱后继关系"
output_info1
.
append
(
output_info
)
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
return
return
1
print
(
"调用上游程序修改topo点成功"
)
except
Exception
as
e
:
output_info
=
"调用上游刷新topo程序时,出现异常,异常为:"
+
str
(
e
)
output_info1
.
append
(
output_info
)
...
...
@@ -194,39 +203,49 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume
hd_data_source
.
Destroy
()
if
mesh_box_data_source
:
mesh_box_data_source
.
Destroy
()
return
return
1
try
:
write_info
(
output_document_path
,
output_info1
,
output_info2
,
output_info3
)
ConnectMeshByMeshList
(
hd_data_source
,
mesh_box_layer
,
mesh_ids
,
output_document_path
)
.
main
()
print
(
"接边已全部运行完毕,请确认!"
)
print
(
str
(
get_current_time
())
+
": 接边已全部运行完毕,请确认!"
)
if
hd_data_source
:
hd_data_source
.
Destroy
()
if
mesh_box_data_source
:
mesh_box_data_source
.
Destroy
()
return
0
except
Exception
as
e
:
print
(
"接边程序出发异常,异常为:"
+
str
(
e
))
finally
:
if
hd_data_source
:
hd_data_source
.
Destroy
()
if
mesh_box_data_source
:
mesh_box_data_source
.
Destroy
()
return
1
if
__name__
==
'__main__'
:
# arg1 = r"PG:dbname='test12' host='localhost' port='5432' user='postgres' password='19931018'"
# # arg1 = r"PG:dbname='qgis_hb_sync' host='win-1.corp.roadlinks.cn' port='5432' user='postgres' password='juefx0123'"
# arg2 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_ids.txt"
# # arg3 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_grid.gpkg"
# arg3 = r"C:\Users\熊超\Desktop\new1\gps_grids.gpkg"
# arg4 = r"C:\Users\熊超\Desktop\edge_match_file"
# run(arg1, arg2, arg3, arg4)
arg1
,
arg2
,
arg3
,
arg4
=
None
,
None
,
None
,
None
try
:
arg1
=
sys
.
argv
[
1
]
# 数据库连接字符串
arg2
=
sys
.
argv
[
2
]
# 图幅号的txt文件
arg3
=
sys
.
argv
[
3
]
# 图幅框文件
arg4
=
sys
.
argv
[
4
]
# 接边报表路径
current_path
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
gdal_data
=
current_path
+
'
\\
proj'
osr
.
SetPROJSearchPath
(
gdal_data
)
except
Exception
as
e
:
print
(
"传入的参数有问题,程序发生异常,异常为:"
+
str
(
e
))
#arg1 = r"PG:dbname='qgismap' host='hb.roadlinks.cn' port='5432' user='qgis' password='qgis@123"
# arg2 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_ids.txt"
#arg4 = r"C:\Users\熊超\Desktop\edge_match_file"
#arg3 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_grid.gpkg"
arg1
=
r"PG:dbname='qgis_hb_sync' host='win-1.corp.roadlinks.cn' port='5432' user='postgres' password='juefx0123"
arg2
=
r"D:\data\meshids.txt"
arg3
=
r"D:\data\mesh_grid.gpkg"
arg4
=
r"D:\data\edge_match_file"
run
(
arg1
,
arg2
,
arg3
,
arg4
)
# arg1, arg2, arg3, arg4 = None, None, None, None
# try:
# arg1 = sys.argv[1] # 数据库连接字符串
# arg2 = sys.argv[2] # 图幅号的txt文件
# arg3 = sys.argv[3] # 图幅框文件
# arg4 = sys.argv[4] # 接边报表路径
# current_path = os.path.dirname(os.path.abspath(__file__))
# gdal_data = current_path + '\\proj'
# osr.SetPROJSearchPath(gdal_data)
# except Exception as e:
# print("传入的参数有问题,程序发生异常,异常为:" + str(e))
# sys.exit(1)
# sys.exit(run(arg1, arg2, arg3, arg4))
math_tools/data_interpolation.py
View file @
c7cf5b29
...
...
@@ -34,34 +34,6 @@ def interpolation_dataset_2d(dataset, interpolation_mount):
m
=
len
(
dataset
)
new_dataset
=
[]
for
i
in
range
(
m
-
1
):
new_dataset
+=
interpolation_between_two_point_3d
(
dataset
[
i
],
dataset
[
i
+
1
],
interpolation_mount
)
new_dataset
.
append
(
dataset
[
m
-
1
])
return
new_dataset
def
two_point_distance_3d
(
point1
,
point2
):
# 计算二元坐标的距离
return
math
.
sqrt
((
point2
[
0
]
-
point1
[
0
])
**
2
+
(
point2
[
1
]
-
point1
[
1
])
**
2
+
(
point2
[
2
]
-
point1
[
2
])
**
2
)
def
interpolation_between_two_point_3d
(
start_point
,
end_point
,
ratio
):
# 在起点与终点之间进行插值,ratio是插值的数量
distance
=
two_point_distance_3d
(
start_point
,
end_point
)
n
=
int
(
distance
*
ratio
)
# 插值的个数
dataset
=
[]
result
=
np
.
linspace
(
0
,
1
,
n
+
2
)[:
n
+
1
]
# 保留首,不保留尾
for
k
in
result
:
x
=
k
*
(
end_point
[
0
]
-
start_point
[
0
])
+
start_point
[
0
]
y
=
k
*
(
end_point
[
1
]
-
start_point
[
1
])
+
start_point
[
1
]
z
=
k
*
(
end_point
[
2
]
-
start_point
[
2
])
+
start_point
[
2
]
dataset
.
append
([
x
,
y
,
z
])
return
dataset
def
interpolation_dataset_3d
(
dataset
,
interpolation_mount
):
m
=
len
(
dataset
)
new_dataset
=
[]
for
i
in
range
(
m
-
1
):
new_dataset
+=
interpolation_between_two_point_3d
(
dataset
[
i
],
dataset
[
i
+
1
],
interpolation_mount
)
new_dataset
+=
interpolation_between_two_point_2d
(
dataset
[
i
],
dataset
[
i
+
1
],
interpolation_mount
)
new_dataset
.
append
(
dataset
[
m
-
1
])
return
new_dataset
math_tools/douglas_peucker_2d.py
View file @
c7cf5b29
...
...
@@ -13,14 +13,9 @@ def two_point_distance_2d(point1, point2):
return
math
.
sqrt
((
point2
[
0
]
-
point1
[
0
])
**
2
+
(
point2
[
1
]
-
point1
[
1
])
**
2
)
def
two_point_distance_3d
(
point1
,
point2
):
# 计算三元坐标点的距离
return
math
.
sqrt
((
point2
[
0
]
-
point1
[
0
])
**
2
+
(
point2
[
1
]
-
point1
[
1
])
**
2
+
(
point2
[
2
]
-
point1
[
2
])
**
2
)
def
interpolation_between_two_point
(
start_point
,
end_point
,
ratio
):
def
interpolation_between_two_point_2d
(
start_point
,
end_point
,
ratio
):
# 在起点与终点之间进行插值,ratio是插值的数量
distance
=
two_point_distance_
3
d
(
start_point
,
end_point
)
distance
=
two_point_distance_
2
d
(
start_point
,
end_point
)
n
=
int
(
distance
*
ratio
)
# 插值的个数
dataset
=
[]
result
=
np
.
linspace
(
0
,
1
,
n
+
2
)[:
n
+
1
]
# 保留首,不保留尾
...
...
@@ -36,10 +31,19 @@ def interpolation_between_two_point(start_point, end_point, ratio):
return
dataset
def
interpolation_dataset_2d
(
dataset
,
interpolation_mount
):
# 按照二维坐标插值
m
=
len
(
dataset
)
new_dataset
=
[]
for
i
in
range
(
m
-
1
):
new_dataset
+=
interpolation_between_two_point_2d
(
dataset
[
i
],
dataset
[
i
+
1
],
interpolation_mount
)
new_dataset
.
append
(
dataset
[
m
-
1
])
return
new_dataset
class
CalElevation
:
"""
使用局部加权计算新的插值点的高程值
通过高斯函数将距离映射为权重,带宽取距离之和除以一个常数
使用局部加权计算高程值,并且通过高斯函数将距离映射为权重
"""
def
__init__
(
self
,
m
,
n
):
...
...
@@ -68,7 +72,7 @@ class CalElevation:
def
get_elevation
(
self
,
ori_points
,
new_points
):
# new_points是需要计算高程的点集,ori_points是原始点集
new_dataset
=
interpolation_dataset
(
ori_points
,
self
.
n
)
new_dataset
=
interpolation_dataset
_2d
(
ori_points
,
self
.
n
)
ori_xy_list
=
[[
point
[
0
],
point
[
1
]]
for
point
in
new_dataset
]
tree
=
KDTree
(
np
.
array
(
ori_xy_list
),
leaf_size
=
20
)
# 二维kd数
for
i
in
range
(
1
,
len
(
new_points
)
-
1
):
...
...
@@ -86,15 +90,6 @@ class CalElevation:
return
new_points
def
interpolation_dataset
(
dataset
,
interpolation_mount
):
m
=
len
(
dataset
)
new_dataset
=
[]
for
i
in
range
(
m
-
1
):
new_dataset
+=
interpolation_between_two_point
(
dataset
[
i
],
dataset
[
i
+
1
],
interpolation_mount
)
new_dataset
.
append
(
dataset
[
m
-
1
])
return
new_dataset
class
ImprovedDouglasPeucker
(
object
):
"""
1. 抽稀后得结果不要两个点两个点得形式
...
...
@@ -141,6 +136,7 @@ class ImprovedDouglasPeucker(object):
self
.
returned_list
.
append
(
points
[
-
1
])
self
.
returned_list
.
append
(
points
[
0
])
else
:
# 在这里分段会产生一个重点,目的是不让最后产生的点集是两个点两个点的效果,最后需要去重才能得到正确的效果
sequence1
=
points
[:
index
+
1
]
sequence2
=
points
[
index
:]
sequences
=
[
sequence1
,
sequence2
]
...
...
@@ -180,5 +176,5 @@ class ImprovedDouglasPeucker(object):
self
.
dilute
(
self
.
not_dilute_list
.
pop
())
self
.
returned_list
=
self
.
returned_list
[::
-
1
]
# 在抽稀的过程中反向了
tmp_points
=
self
.
remove_duplicated_point
(
self
.
returned_list
)
new_points
=
interpolation_dataset
(
tmp_points
,
self
.
interpolation_count
)
new_points
=
interpolation_dataset
_2d
(
tmp_points
,
self
.
interpolation_count
)
return
CalElevation
(
self
.
m
,
self
.
n
)
.
get_elevation
(
points
,
new_points
)
math_tools/savitsky_golay_filter.py
View file @
c7cf5b29
...
...
@@ -257,7 +257,7 @@ class SavitzkyGolayFilter:
3. 对滤波后的数据进行抽稀和插值
"""
def
__init__
(
self
,
interpolation_count
=
0.125
):
def
__init__
(
self
):
self
.
trans
=
PosNegTrans
()
# 坐标系转移类
self
.
poly_fit
=
PolyFit
()
# 多项式拟合类
...
...
smoothing_elevation.py
0 → 100644
View file @
c7cf5b29
# _*_ coding: utf-8 _*_ #
# @Time: 2020/6/28 16:35
# @Author: XiongChao
# _*_ coding: utf-8 _*_ #
# @Time: 2020/6/28 10:03
# @Author: XiongChao
# 修改指定图层的高程以达到平滑的要求
from
osgeo
import
gdal
from
util.common
import
*
from
util.geographic_tool
import
*
gdal
.
SetConfigOption
(
"GDAL_FILENAME_IS_UTF8"
,
"YES"
)
# 支持中文路径
gdal
.
SetConfigOption
(
"SHAPE_ENCODING"
,
""
)
# 使属性表支持中文
ogr
.
RegisterAll
()
# 注册所有驱动
DEF_Z_RANGE_THRESHOLD
=
4
# 判断是否进行高程操作的阈值
DEF_SLOPE_THRESHOLD
=
np
.
tan
(
30
/
180
*
np
.
pi
)
# detla_z / dis的阈值
DEF_ALPHA
=
0.0000001
def
two_point_distance_by_blh
(
blh_point1
,
blh_point2
,
source_srs
):
# 根据经纬度计算两点的距离,使用的是utm坐标系
utm_point1
=
transform_to_utm
([
blh_point1
],
source_srs
)[
0
][
0
]
utm_point2
=
transform_to_utm
([
blh_point2
],
source_srs
)[
0
][
0
]
return
two_point_distance_2d
(
utm_point1
,
utm_point2
)
class
SmoothingElevation
:
"""
对输入的点线的高程进行平滑
"""
def
__init__
(
self
):
self
.
info
=
[]
def
is_reset_elevation
(
self
,
line_features
,
line_directions
,
line_layer_name
,
primary_key
):
# 判断是否调整高程,以及返回节点的高程
# 如果几条线的高程值的极差超过2米,就认为异常,不修复高程
z_list
=
[]
for
i
in
range
(
len
(
line_features
)):
blh_points
=
line_features
[
i
]
.
GetGeometryRef
()
.
GetPoints
()
if
line_directions
[
i
]
==
1
:
z_list
.
extend
([
point
[
2
]
for
point
in
blh_points
[
-
2
:]])
else
:
z_list
.
extend
([
point
[
2
]
for
point
in
blh_points
[:
2
]])
z_range
=
max
(
z_list
)
-
min
(
z_list
)
if
z_range
>
DEF_Z_RANGE_THRESHOLD
:
info
=
str
(
line_layer_name
)
+
"上id: "
+
str
(
line_features
[
0
][
primary_key
])
+
\
"为的节点,附近关联的线的z值的极差过大,不进行处理,请修改数据"
self
.
info
.
append
(
info
)
return
False
,
0
return
True
,
np
.
mean
(
z_list
)
@staticmethod
def
reset_node_elevation
(
node_layer
,
node_feature
,
elevation
):
# 重置节点的高程
node_point
=
node_feature
.
GetGeometryRef
()
.
GetPoints
()[
0
]
new_node_point
=
[
node_point
[
0
],
node_point
[
1
],
elevation
]
node_geom
=
create_point_geometry
(
new_node_point
)
node_feature
.
SetGeometry
(
node_geom
)
node_layer
.
SetFeature
(
node_feature
)
@staticmethod
def
cal_slope
(
blh_point1
,
blh_point2
,
source_srs
):
distance
=
two_point_distance_by_blh
(
blh_point1
,
blh_point2
,
source_srs
)
detla_z
=
abs
(
blh_point1
[
2
]
-
blh_point2
[
2
])
return
detla_z
/
distance
def
reset_line_elevation
(
self
,
line_layer
,
line_feature
,
line_direction
,
elevation
,
source_srs
,
line_layer_name
,
primary_key
):
blh_points
=
[
list
(
point
)
for
point
in
line_feature
.
GetGeometryRef
()
.
GetPoints
()]
if
line_direction
==
-
1
:
blh_points
=
blh_points
[::
-
1
]
blh_points
[
-
1
]
=
[
blh_points
[
-
1
][
0
],
blh_points
[
-
1
][
1
],
elevation
]
j
=
len
(
blh_points
)
-
1
if
j
<=
2
:
slope
=
self
.
cal_slope
(
blh_points
[
len
(
blh_points
)
-
1
],
blh_points
[
len
(
blh_points
)
-
2
],
source_srs
)
# 如果满足条件,直接将点集写入即可
if
slope
>
DEF_SLOPE_THRESHOLD
:
# 此处没办法平滑
info
=
"id: "
+
str
(
line_feature
[
primary_key
])
+
"的线,其长度很短并且无法满足指定角度的要求"
self
.
info
.
append
(
info
)
return
False
else
:
flag
=
False
for
j
in
range
(
len
(
blh_points
)
-
2
,
int
((
len
(
blh_points
)
+
1
)
/
2
)
-
1
,
-
1
):
slope
=
self
.
cal_slope
(
blh_points
[
len
(
blh_points
)
-
1
],
blh_points
[
j
],
source_srs
)
if
slope
<
DEF_SLOPE_THRESHOLD
+
0.001
:
# 0.001是为了防止浮点数计算带来的误差
flag
=
True
break
if
not
flag
:
# 表示没有找到可以达到平滑要求的点
info
=
str
(
line_layer_name
)
+
"上id: "
+
str
(
line_feature
[
primary_key
])
+
\
"的线,其要么长度太短,要么高程值异常"
self
.
info
.
append
(
info
)
return
False
start_point
=
blh_points
[
len
(
blh_points
)
-
1
]
start_elevation
,
end_elevation
=
start_point
[
2
],
blh_points
[
j
][
2
]
distance
=
two_point_distance_by_blh
(
blh_points
[
len
(
blh_points
)
-
1
],
blh_points
[
j
],
source_srs
)
cal_elevation
=
lambda
point
:
two_point_distance_by_blh
(
start_point
,
point
,
source_srs
)
/
\
distance
*
(
end_elevation
-
start_elevation
)
+
start_elevation
for
k
in
range
(
len
(
blh_points
)
-
2
,
j
,
-
1
):
blh_points
[
k
][
2
]
=
cal_elevation
(
blh_points
[
k
])
if
line_direction
==
-
1
:
blh_points
=
blh_points
[::
-
1
]
geom
=
create_line_geometry
(
blh_points
)
line_feature
.
SetGeometry
(
geom
)
line_layer
.
SetFeature
(
line_feature
)
return
True
def
reset_elevation
(
self
,
node_layer
,
line_layer
,
line_layer_name
,
node_features
,
line_features
,
line_directions
,
line_fields
,
source_srs
):
# node_fields为列表,表示用到的节点图层的字段,0-ids字段,1-id字段
# line_fields为列表,表示用到的线图层的字段,0-id字段,1-起点字段,2-终点字段
flag
,
elevation
=
self
.
is_reset_elevation
(
line_features
,
line_directions
,
line_layer_name
,
line_fields
[
0
])
if
not
flag
:
return
if
not
self
.
reset_line_elevation
(
line_layer
,
line_features
[
0
],
line_directions
[
0
],
elevation
,
source_srs
,
line_layer_name
,
line_fields
[
0
])
or
\
not
self
.
reset_line_elevation
(
line_layer
,
line_features
[
1
],
line_directions
[
1
],
elevation
,
source_srs
,
line_layer_name
,
line_fields
[
0
]):
return
self
.
reset_node_elevation
(
node_layer
,
node_features
[
0
],
elevation
)
self
.
reset_node_elevation
(
node_layer
,
node_features
[
1
],
elevation
)
@staticmethod
def
remove_near_points
(
line_layer
,
line_features
,
source_srs
,
alpha
=
0.01
):
# 删除线上过近的点,远近的描述为alpha
for
line_feature
in
line_features
:
blh_points
=
line_feature
.
GetGeometryRef
()
.
GetPoints
()
utm_points
,
utm_srs
=
transform_to_utm
(
blh_points
,
source_srs
)
new_utm_points
=
remove_near_data
(
utm_points
,
alpha
)
new_blh_points
=
transform_to_src
(
new_utm_points
,
source_srs
,
utm_srs
)
geom
=
create_line_geometry
(
new_blh_points
)
line_feature
.
SetGeometry
(
geom
)
line_layer
.
SetFeature
(
line_feature
)
def
models
(
self
,
input_info
):
node_layer
,
line_layer
,
node_features
,
line_features
,
\
line_directions
,
source_srs
,
node_fields
,
line_fields
=
input_info
line_layer_name
=
line_layer
.
GetName
()
try
:
self
.
remove_near_points
(
line_layer
,
line_features
,
source_srs
,
0.01
)
except
Exception
as
e
:
message
=
str
(
line_layer_name
)
+
"在高程平滑之前的去除过近点的过程中出现异常:"
+
str
(
e
)
self
.
info
.
append
(
message
)
return
self
.
reset_elevation
(
node_layer
,
line_layer
,
line_layer_name
,
node_features
,
line_features
,
line_directions
,
line_fields
,
source_srs
)
return
util/common.py
View file @
c7cf5b29
...
...
@@ -60,9 +60,9 @@ def three_point_dot_product(point1, point2, point3):
return
result
def
is_same_point_2d
(
point1
,
point2
):
def
is_same_point_2d
(
point1
,
point2
,
alpha
=
DEF_ALPHA
):
# 判断两个点是不是一个点,仅选择x, y
flag
=
np
.
array
([
np
.
abs
(
point1
[
i
]
-
point2
[
i
])
<
0.000001
for
i
in
range
(
len
(
point1
))])
flag
=
np
.
array
([
np
.
abs
(
point1
[
i
]
-
point2
[
i
])
<
alpha
for
i
in
range
(
len
(
point1
))])
flag
=
flag
[:
2
]
# 当为三元数值得时候,仅取前两位进行比较
if
flag
.
all
():
return
True
...
...
@@ -105,3 +105,23 @@ def nearest_m_point_of_dataset_2d(point, dataset, m):
dist
,
ind
=
tree
.
query
([
np
.
array
(
point
[:
2
])],
k
=
m
)
index_list
=
list
(
ind
[
0
])
return
index_list
def
remove_near_data
(
dataset
,
alpha
=
DEF_ALPHA
):
# 将数据集中非常接近的点去掉,每一个feature至少有起点和终点,并且这两个点不同
dataset1
=
dataset
[::
-
1
]
+
[]
target_dataset
=
[]
point1
=
dataset1
.
pop
()
point2
=
dataset1
[
0
]
target_dataset
.
append
(
point1
)
while
dataset1
:
point2
=
dataset1
.
pop
()
if
is_same_point_2d
(
point1
,
point2
,
alpha
):
continue
target_dataset
.
append
(
point2
)
point1
=
point2
if
not
is_same_point_3d
(
target_dataset
[
-
1
],
point2
):
if
two_point_distance_2d
(
target_dataset
[
-
1
],
point2
)
<
alpha
:
target_dataset
.
pop
()
target_dataset
.
append
(
point2
)
return
target_dataset
connect_solution
/geographic_tool.py
→
util
/geographic_tool.py
View file @
c7cf5b29
# _*_ coding: utf-8 _*_ #
# @Time: 2020/6/1 11:40
# @Author: XiongChao
from
osgeo
import
ogr
,
osr
import
math
def
transform_to_utm
(
blh_dataset
,
source_srs
):
lon
=
blh_dataset
[
0
][
0
]
utm_zone
=
31
+
math
.
floor
(
lon
/
6.0
)
utm_srs
=
osr
.
SpatialReference
()
utm_srs
.
SetUTM
(
utm_zone
,
1
)
src_to_utm_trans
=
osr
.
CreateCoordinateTransformation
(
source_srs
,
utm_srs
)
utm_dataset
=
[]
for
blh_point
in
blh_dataset
:
temp_point
=
blh_point
utm_point
=
list
(
src_to_utm_trans
.
TransformPoint
(
temp_point
[
0
],
temp_point
[
1
]))
utm_point
[
2
]
=
blh_point
[
2
]
utm_dataset
.
append
(
utm_point
)
return
utm_dataset
,
utm_srs
def
transform_to_src
(
utm_dataset
,
source_srs
,
utm_srs
):
utm_to_src_trans
=
osr
.
CreateCoordinateTransformation
(
utm_srs
,
source_srs
)
src_dataset
=
[]
for
utm_point
in
utm_dataset
:
temp_point
=
utm_point
src_point
=
list
(
utm_to_src_trans
.
TransformPoint
(
temp_point
[
0
],
temp_point
[
1
]))
src_point
[
2
]
=
utm_point
[
2
]
src_dataset
.
append
(
src_point
)
return
src_dataset
def
create_line_geometry
(
dataset
):
geo
=
ogr
.
Geometry
(
ogr
.
wkbLineStringZM
)
for
i
in
range
(
len
(
dataset
)):
geo
.
SetPoint
(
i
,
dataset
[
i
][
0
],
dataset
[
i
][
1
],
dataset
[
i
][
2
])
return
geo
def
create_point_geometry
(
point
):
geo
=
ogr
.
Geometry
(
ogr
.
wkbPointZM
)
geo
.
SetPoint
(
0
,
point
[
0
],
point
[
1
],
point
[
2
])
return
geo
# _*_ coding: utf-8 _*_ #
# @Time: 2020/6/1 11:40
# @Author: XiongChao
from
osgeo
import
ogr
,
osr
import
math
def
transform_to_utm
(
blh_dataset
,
source_srs
):
lon
=
blh_dataset
[
0
][
0
]
utm_zone
=
31
+
math
.
floor
(
lon
/
6.0
)
utm_srs
=
osr
.
SpatialReference
()
utm_srs
.
SetUTM
(
utm_zone
,
1
)
src_to_utm_trans
=
osr
.
CreateCoordinateTransformation
(
source_srs
,
utm_srs
)
utm_dataset
=
[]
for
blh_point
in
blh_dataset
:
temp_point
=
blh_point
utm_point
=
list
(
src_to_utm_trans
.
TransformPoint
(
temp_point
[
0
],
temp_point
[
1
]))
utm_point
[
2
]
=
blh_point
[
2
]
utm_dataset
.
append
(
utm_point
)
return
utm_dataset
,
utm_srs
def
transform_to_src
(
utm_dataset
,
source_srs
,
utm_srs
):
utm_to_src_trans
=
osr
.
CreateCoordinateTransformation
(
utm_srs
,
source_srs
)
src_dataset
=
[]
for
utm_point
in
utm_dataset
:
temp_point
=
utm_point
src_point
=
list
(
utm_to_src_trans
.
TransformPoint
(
temp_point
[
0
],
temp_point
[
1
]))
src_point
[
2
]
=
utm_point
[
2
]
src_dataset
.
append
(
src_point
)
return
src_dataset
def
create_line_geometry
(
dataset
):
geo
=
ogr
.
Geometry
(
ogr
.
wkbLineStringZM
)
for
i
in
range
(
len
(
dataset
)):
geo
.
SetPoint
(
i
,
dataset
[
i
][
0
],
dataset
[
i
][
1
],
dataset
[
i
][
2
])
return
geo
def
create_point_geometry
(
point
):
geo
=
ogr
.
Geometry
(
ogr
.
wkbPointZM
)
geo
.
SetPoint
(
0
,
point
[
0
],
point
[
1
],
point
[
2
])
return
geo
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment