13 KiB
13 KiB
坐标转换工具为 GIS 和测绘应用提供了一套完整的坐标系统转换功能,涵盖角度格式转换、坐标系统转换、几何变换等核心能力。本模块通过 PySSMath 提供高性能的坐标转换算法,支持从基础的角度格式互转到复杂的坐标系统映射变换。本文档面向高级开发者,详细说明各类坐标转换工具的 API 使用方法和应用场景。
Sources: PySSMath.py
角度格式转换
PySSMath 提供了多种角度表示形式之间的转换功能,支持弧度制、十进制度数、度分秒(DMS)格式之间的灵活互转,满足测绘应用中不同角度表示需求。
基础角度转换
| 函数名 | 功能描述 | 参数 | 返回值 |
|---|---|---|---|
degToRadian(deg) |
十进制度数转弧度 | deg: float | 弧度值 |
radianToDeg(dRadian) |
弧度转十进制度数 | dRadian: float | 度数值 |
degToDms(deg) |
十进制度数转度分秒 | deg: float | DMS 值 |
dmsToDeg(dms) |
度分秒转十进制度数 | dms: float | 度数值 |
dmsToRadian(dDms) |
度分秒转弧度 | dDms: float | 弧度值 |
radianToDms(dRadian) |
弧度转度分秒 | dRadian: float | DMS 值 |
dmsToSec(dms) |
度分秒转秒数 | dms: float | 秒数 |
secToDms(sec) |
秒数转度分秒 | sec: float | DMS 值 |
角度调整函数
| 函数名 | 功能描述 | 参数说明 |
|---|---|---|
adjustAngle(dRadian) |
调整弧度值到 [-π, π] 范围 | dRadian: 待调整的弧度值 |
adjustDmsAngle(dAngle) |
调整 DMS 角度值 | dAngle: 待调整的 DMS 角度值 |
adjustDegAngle(dAngle) |
调整度数值到 [0, 360] 范围 | dAngle: 待调整的度数值 |
角度转换示例
import sunvpy.PySSMath as ssMath
# 十进制度数转弧度
deg_value = 45.5
rad_value = ssMath.degToRadian(deg_value)
print(f"{deg_value}° = {rad_value:.6f} rad")
# 弧度转度分秒
dms_value = ssMath.radianToDms(1.5708)
print(f"1.5708 rad = {dms_value:.4f} (DMS格式)")
# 角度调整到标准范围
adjusted_angle = ssMath.adjustAngle(7.0) # 超出范围的角度
print(f"调整后角度: {adjusted_angle:.6f} rad")
Sources: PySSMath.py
极坐标与直角坐标转换
极坐标和直角坐标是两种常用的坐标表示方式,适用于不同的应用场景。PySSMath 提供了两者之间的双向转换功能。
坐标转换函数
| 函数名 | 功能描述 | 参数说明 |
|---|---|---|
rightToPolar(x, y) |
直角坐标转极坐标 | x, y: 直角坐标值,返回 (距离, 方位角) |
polarToRight(r, angle) |
极坐标转直角坐标 | r: 距离;angle: 方位角(弧度) |
getPolar(p1, p2, dist, dRadian) |
从基点按距离和方位角获取点 | p1: 基点;p2: 参考点;dist: 距离;dRadian: 方位角 |
getPoint(p1, p2, dist, dRadian) |
同 getPolar | 参数同 getPolar |
极坐标转换示例
import sunvpy.PySSMath as ssMath
# 直角坐标转极坐标
x, y = 100.0, 100.0
distance, angle = ssMath.rightToPolar(x, y)
print(f"直角坐标 ({x}, {y}) -> 极坐标: 距离={distance:.2f}, 方位角={angle:.6f} rad")
# 极坐标转直角坐标
r = 141.42
angle_rad = 0.785398
x_new, y_new = ssMath.polarToRight(r, angle_rad)
print(f"极坐标 (r={r}, angle={angle_rad}) -> 直角坐标: ({x_new:.2f}, {y_new:.2f})")
# 从基点获取极坐标点
import sunvpy.PySSMath.Point3D as Point3D
p1 = Point3D(0, 0, 0)
p2 = Point3D(1, 0, 0)
new_point = ssMath.getPolar(p1, p2, 100, ssMath.degToRadian(45))
print(f"从原点向东45°方向100米处的点: ({new_point.x():.2f}, {new_point.y():.2f})")
Sources: PySSMath.py
方位角计算
方位角计算是测绘和导航应用中的核心功能,PySSMath 提供了多种方位角计算方法,支持点对点方位角、角度平分等场景。
方位角计算函数
| 函数名 | 功能描述 | 参数说明 |
|---|---|---|
bearing(x1, y1, x0, y0) |
计算从点 (x0, y0) 到点 (x1, y1) 的方位角 | 返回弧度值 |
bearing(p0, p1) |
计算方位角(使用 Point3D 对象) | p0: 起始点;p1: 目标点 |
jiaoPingfenFangWei(x1, y1, x0, y0, x2, y2) |
计算两线段的夹角平分方位角 | (x1,y1)-(x0,y0) 和 (x2,y2)-(x0,y0) 的平分方向 |
角度计算函数
| 函数名 | 功能描述 | 返回值 |
|---|---|---|
openAngle(p1, p0, p2) |
计算 ∠p1p0p2 的夹角 | 弧度值 |
openAngleDeg(p1, p0, p2) |
计算夹角(度数) | 度数 |
方位角计算示例
import sunvpy.PySSMath as ssMath
import sunvpy.PySSMath.Point3D as Point3D
# 计算两点间的方位角
x0, y0 = 100.0, 100.0 # 起点
x1, y1 = 200.0, 150.0 # 终点
azimuth_rad = ssMath.bearing(x1, y1, x0, y0)
azimuth_deg = ssMath.radianToDeg(azimuth_rad)
print(f"从 ({x0}, {y0}) 到 ({x1}, {y1}) 的方位角: {azimuth_deg:.2f}°")
# 使用 Point3D 对象计算方位角
p0 = Point3D(100.0, 100.0, 0)
p1 = Point3D(200.0, 150.0, 0)
azimuth_rad2 = ssMath.bearing(p0, p1)
print(f"方位角(弧度): {azimuth_rad2:.6f}")
# 计算角度平分方向
# 从 (0,0) 到 (100,0) 和 (0,100) 的夹角平分方向
bisect_angle = ssMath.jiaoPingfenFangWei(100, 0, 0, 0, 0, 100)
bisect_deg = ssMath.radianToDeg(bisect_angle)
print(f"90°角的平分方位角: {bisect_deg:.2f}°")
# 计算三点夹角
p1 = Point3D(0, 100, 0)
p_center = Point3D(0, 0, 0)
p2 = Point3D(100, 0, 0)
angle_rad = ssMath.openAngle(p1, p_center, p2)
angle_deg = ssMath.radianToDeg(angle_rad)
print(f"夹角 ∠p1-center-p2: {angle_deg:.2f}°")
Sources: PySSMath.py
几何变换操作
几何变换是坐标转换的重要应用场景,包括旋转、平移、缩放、镜像等基本变换,以及系统坐标旋转、映射变换等高级变换。
二维几何变换
| 函数名 | 功能描述 | 参数说明 |
|---|---|---|
rotate2DList(Points, angle, basePoint) |
二维点集旋转 | angle: 旋转角(弧度);basePoint: 旋转基点 |
offset2DList(Points, dx, dy) |
二维点集平移 | dx, dy: X和Y方向的平移量 |
三维几何变换
| 函数名 | 功能描述 | 参数说明 |
|---|---|---|
rotate3DList(*args) |
三维点集旋转 | 支持多种参数形式(绕轴旋转、绕任意轴旋转) |
offset3DList(*args) |
三维点集偏移 | 支持偏移向量或分量形式 |
zoom3DList(*args) |
三维点集缩放 | 支持缩放中心和缩放因子 |
mirror3DList(baseP0, baseP1, Ps) |
三维点集镜像 | baseP0, baseP1: 镜像轴上的两点;Ps: 待变换点集 |
extend3DList(Points, dist, bTail) |
点集延伸 | dist: 延伸距离;bTail: true=尾部延伸,false=头部延伸 |
smooth3DList(Ps0, fScale, nFlag) |
点集平滑 | fScale: 平滑系数;nFlag: 平滑方式 |
mapping3DList(Points, ctrlPoints_old, ctrlPoints_new) |
点集映射变换 | 基于控制点的仿射变换 |
系统坐标变换
| 函数名 | 功能描述 | 参数说明 |
|---|---|---|
sysRotate(Xold, Yold, Xnew, Ynew, X0, Y0, dRadian) |
系统旋转 | 将旧坐标系旋转至新坐标系 |
grdbodyRotate(*args) |
网格体旋转 | 支持多种参数形式 |
几何变换示例
import sunvpy.PySSMath as ssMath
import sunvpy.PySSMath.POINT3DLIST as POINT3DLIST
import sunvpy.PySSMath.Point3D as Point3D
# 创建点集
points = POINT3DLIST()
points.push_back(Point3D(10, 10, 0))
points.push_back(Point3D(20, 10, 0))
points.push_back(Point3D(20, 20, 0))
# 二维旋转(绕原点旋转90度)
basePoint = Point3D(0, 0, 0)
angle = ssMath.degToRadian(90)
ssMath.rotate2DList(points, angle, basePoint)
print("旋转后的点集:")
for i in range(points.size()):
pt = points.at(i)
print(f" 点{i+1}: ({pt.x():.2f}, {pt.y():.2f}, {pt.z():.2f})")
# 二维平移
ssMath.offset2DList(points, 5.0, 5.0)
print("平移后的点集:")
for i in range(points.size()):
pt = points.at(i)
print(f" 点{i+1}: ({pt.x():.2f}, {pt.y():.2f}, {pt.z():.2f})")
# 镜像变换
points2 = POINT3DLIST()
points2.push_back(Point3D(10, 10, 0))
points2.push_back(Point3D(30, 10, 0))
points2.push_back(Point3D(30, 30, 0))
baseP0 = Point3D(0, 0, 0) # 镜像轴起点
baseP1 = Point3D(1, 0, 0) # 镜像轴终点(X轴)
ssMath.mirror3DList(baseP0, baseP1, points2)
print("镜像后的点集:")
for i in range(points2.size()):
pt = points2.at(i)
print(f" 点{i+1}: ({pt.x():.2f}, {pt.y():.2f}, {pt.z():.2f})")
Sources: PySSMath.py
坐标转换应用场景
测绘坐标转换
import sunvpy.PySSMath as ssMath
# 场景1:测量角度转换
# 将测量得到的度分秒格式转换为十进制度数
dms_angle = 30.3045 # 30°30'45" 表示为 30.3045
deg_angle = ssMath.dmsToDeg(dms_angle)
rad_angle = ssMath.degToRadian(deg_angle)
print(f"测量角度 {dms_angle:.4f} (DMS) = {deg_angle:.6f}° = {rad_angle:.6f} rad")
# 场景2:方位角归一化
# 确保方位角在 [0, 2π) 范围内
azimuth = 450.0 # 超出范围的方位角
normalized_deg = ssMath.adjustDegAngle(azimuth)
normalized_rad = ssMath.degToRadian(normalized_deg)
print(f"归一化方位角: {azimuth}° -> {normalized_deg:.2f}° = {normalized_rad:.6f} rad")
# 场景3:极坐标测量转直角坐标
# 从测站向东偏北45°方向测量距离100米
dist = 100.0
azimuth_from_north = ssMath.degToRadian(45) # 从北方向向东
# 注意:测量通常以北方为0°,顺时针为正
# PySSMath的bearing函数可能以东方为0°,需要根据实际情况调整
GIS 坐标变换
import sunvpy.PySSMath as ssMath
import sunvpy.PySSMath.POINT3DLIST as POINT3DLIST
import sunvpy.PySSMath.Point3D as Point3D
# 场景1:地图旋转校正
# 将倾斜的地图元素旋转到标准方向
polygon = POINT3DLIST()
polygon.push_back(Point3D(100, 100, 0))
polygon.push_back(Point3D(110, 95, 0))
polygon.push_back(Point3D(105, 105, 0))
# 计算需要旋转的角度
angle_correction = ssMath.degToRadian(5) # 逆时针旋转5度
rotation_center = Point3D(100, 100, 0)
ssMath.rotate2DList(polygon, angle_correction, rotation_center)
# 场景2:坐标系平移
# 将局部坐标系下的坐标转换到全局坐标系
offset_x = 500000.0 # 全局坐标系X偏移量
offset_y = 3000000.0 # 全局坐标系Y偏移量
ssMath.offset2DList(polygon, offset_x, offset_y)
# 场景3:比例尺变换
# 应用地图比例尺变换
scale_factor = 1000.0 # 1:1000比例尺
zoom_center = Point3D(500000, 3000000, 0)
ssMath.zoom3DList(polygon, scale_factor, scale_factor, scale_factor, zoom_center)
工程应用变换
import sunvpy.PySSMath as ssMath
import sunvpy.PySSMath.POINT3DLIST as POINT3DLIST
import sunvpy.PySSMath.Point3D as Point3D
# 场景:基于控制点的坐标映射
# 已知旧坐标系和新坐标系中的控制点对
control_points_old = POINT3DLIST()
control_points_old.push_back(Point3D(0, 0, 0))
control_points_old.push_back(Point3D(100, 0, 0))
control_points_old.push_back(Point3D(0, 100, 0))
control_points_new = POINT3DLIST()
control_points_new.push_back(Point3D(500000, 3000000, 0))
control_points_new.push_back(Point3D(500100, 3000000, 0))
control_points_new.push_back(Point3D(500000, 3000100, 0))
# 待变换的点集
points_to_transform = POINT3DLIST()
points_to_transform.push_back(Point3D(50, 50, 0))
points_to_transform.push_back(Point3D(75, 25, 0))
# 执行映射变换
ssMath.mapping3DList(points_to_transform, control_points_old, control_points_new)
print("变换后的点:")
for i in range(points_to_transform.size()):
pt = points_to_transform.at(i)
print(f" 点{i+1}: ({pt.x():.2f}, {pt.y():.2f}, {pt.z():.2f})")
Sources: PySSMath.py
最佳实践与注意事项
角度单位处理
在进行角度计算时,务必注意角度单位的统一性。PySSMath 的函数默认使用弧度制进行内部计算,但提供了多种角度格式的转换函数。
import sunvpy.PySSMath as ssMath
# 推荐:在计算开始时统一转换为弧度制
def calculate_with_angles(deg_angle):
rad_angle = ssMath.degToRadian(deg_angle)
# 执行计算
result = rad_angle * 2 # 示例计算
# 将结果转换回需要的格式
return ssMath.radianToDeg(result)
坐标变换顺序
多个几何变换的执行顺序会影响最终结果。通常建议的顺序为:平移 → 旋转 → 缩放。
import sunvpy.PySSMath as ssMath
import sunvpy.PySSMath.POINT3DLIST as POINT3DLIST
import sunvpy.PySSMath.Point3D as Point3D
points = POINT3DLIST()
# ... 添加点 ...
# 推荐的变换顺序
ssMath.offset3DList(points, dx, dy, dz) # 1. 先平移
ssMath.rotate3DList(points, angle, axis) # 2. 再旋转
ssMath.zoom3DList(points, sx, sy, sz, center) # 3. 最后缩放
精度控制
在比较坐标和角度时,使用容差而非精确相等。
import sunvpy.PySSMath as ssMath
import sunvpy.PySSMath.Point3D as Point3D
p1 = Point3D(100.0, 100.0, 0.0)
p2 = Point3D(100.0001, 100.0001, 0.0)
# 使用带容差的比较
epsilon = 0.001
is_same = ssMath.isSamePoint(p1, p2, epsilon)