跳转到内容
RailWise KB已发布

坐标系统转换工具 — CGCS2000、地方坐标系与施工坐标系转换

支持CGCS2000、WGS84、地方坐标系及施工坐标系之间的转换,包含七参数、四参数转换和投影计算

复核 2026-07-09入门公开可引用RailWise 技术团队
tool-guide

本工具实现不同坐标系统之间的转换,包括大地坐标(经纬度)与平面坐标的转换、不同平面坐标系之间的转换(四参数/七参数),以及施工坐标系的建立与转换。

  • GPS测量成果向地方坐标系的转换
  • 不同期监测数据的坐标系统一
  • 施工坐标系的建立与使用
  • 多源数据(设计、施工、监测)的坐标融合
类型 内容
输入 源坐标、转换参数、坐标系信息
输出 目标坐标、转换精度评估、残差分析

由大地坐标(B, L)计算平面坐标(X, Y):

$$X = C_0 + C_1 l^2 + C_2 l^4 + C_3 l^6$$ $$Y = C_0’ l + C_1’ l^3 + C_2’ l^5$$

其中:

  • B:纬度
  • L:经度
  • l = L - L₀:经差(L₀为中央子午线经度)

由平面坐标(X, Y)反算大地坐标(B, L)。

2.2 四参数转换(平面坐标系间)

Section titled “2.2 四参数转换(平面坐标系间)”

适用于同一椭球体下的平面坐标转换:

$$\begin{bmatrix} X_{target} \ Y_{target} \end{bmatrix} = \begin{bmatrix} X_0 \ Y_0 \end{bmatrix} + (1 + m) \begin{bmatrix} \cos\theta & -\sin\theta \ \sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} X_{source} \ Y_{source} \end{bmatrix}$$

其中:

  • $X_0, Y_0$:平移参数
  • $\theta$:旋转参数(弧度)
  • $m$:尺度参数

2.3 七参数转换(不同椭球体间)

Section titled “2.3 七参数转换(不同椭球体间)”

适用于不同椭球体间的大地坐标或空间直角坐标转换:

$$\begin{bmatrix} X_B \ Y_B \ Z_B \end{bmatrix} = \begin{bmatrix} \Delta X \ \Delta Y \ \Delta Z \end{bmatrix} + (1 + m) \begin{bmatrix} 1 & -R_Z & R_Y \ R_Z & 1 & -R_X \ -R_Y & R_X & 1 \end{bmatrix} \begin{bmatrix} X_A \ Y_A \ Z_A \end{bmatrix}$$

其中:

  • $\Delta X, \Delta Y, \Delta Z$:三个平移参数
  • $R_X, R_Y, R_Z$:三个旋转参数(弧度)
  • $m$:尺度参数
坐标系 椭球名称 长半轴a(m) 扁率f
CGCS2000 CGCS2000 6378137 1/298.257222101
WGS84 WGS84 6378137 1/298.257223563
北京54 Krassovsky 6378245 1/298.3
西安80 IAG75 6378140 1/298.257

Terminal window
# 高斯投影正算
python tool_coordinate_conversion.py gauss-forward \
--lat 30.123456 --lon 121.456789 \
--central-meridian 121.0 --ellipsoid CGCS2000
# 四参数转换
python tool_coordinate_conversion.py four-param \
--source-x 34512.345 --source-y 67890.123 \
--params params.json
# 七参数转换
python tool_coordinate_conversion.py seven-param \
--source-x 34512.345 --source-y 67890.123 --source-z 15.234 \
--params seven_params.json
from coordinate_conversion import CoordinateConverter
# 初始化转换器
converter = CoordinateConverter(ellipsoid='CGCS2000')
# 高斯正算
x, y = converter.gauss_forward(
latitude=30.123456,
longitude=121.456789,
central_meridian=121.0
)
# 四参数转换
target_x, target_y = converter.four_parameter_transform(
source_x=34512.345,
source_y=67890.123,
params={'dx': 100.0, 'dy': 50.0, 'rotation': 0.5, 'scale': 1.000001}
)

参数名 含义 类型 取值范围 必填 说明
latitude 纬度 float -90~90° 十进制度
longitude 经度 float -180~180° 十进制度
central_meridian 中央子午线 float -180~180° 3°带或6°带中央子午线
ellipsoid 椭球类型 str CGCS2000/WGS84/北京54/西安80 决定椭球参数
zone_width 带宽 int 3/6 默认3°带
false_easting 东偏移 float - 默认500km
参数名 含义 单位 说明
dx X方向平移 m 两坐标系原点X差
dy Y方向平移 m 两坐标系原点Y差
rotation 旋转角 顺时针为正
scale 尺度因子 - 通常为1.0000xx
参数名 含义 单位 说明
dx X方向平移 m
dy Y方向平移 m
dz Z方向平移 m
rx X轴旋转
ry Y轴旋转
rz Z轴旋转
scale 尺度因子 ppm 百万分之一

场景:CGCS2000坐标系,点P纬度30°15′20.56″,经度121°27′24.40″,3°带第40带。

输入

params = {
'latitude': dms_to_decimal(30, 15, 20.56),
'longitude': dms_to_decimal(121, 27, 24.40),
'central_meridian': 120.0, # 3°带中央子午线
'ellipsoid': 'CGCS2000'
}

计算结果

X = 3348123.456 m
Y = 40567890.123 m (含带号40)

场景:施工坐标系向地方坐标系转换。

已知参数

  • dx = 100.0 m
  • dy = 50.0 m
  • rotation = 0.5°
  • scale = 1.000001

转换点:施工坐标 (1000.0, 2000.0)

计算过程

  1. 旋转矩阵:cos(0.5°) = 0.999962, sin(0.5°) = 0.008727
  2. X_target = 100.0 + 1.000001 × (1000 × 0.999962 - 2000 × 0.008727) = 1082.26 m
  3. Y_target = 50.0 + 1.000001 × (1000 × 0.008727 + 2000 × 0.999962) = 2058.67 m

转换类型 典型精度 适用场景
高斯投影 0.1~1 mm 同椭球内坐标转换
四参数 1~5 cm 同一区域内平面坐标转换
七参数 2~10 cm 不同椭球间坐标转换
拟合转换 1~3 cm 局部区域高精度转换
  • 残差应呈随机分布
  • 系统残差表明参数有误或存在系统变形
  • 残差超限的点应检查或剔除

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
坐标系统转换工具
支持CGCS2000、WGS84、地方坐标系及施工坐标系转换
Author: RailWise技术团队
Version: 1.0.0
"""
import math
from typing import Dict, Optional, Tuple
from dataclasses import dataclass
# 椭球参数
ELLIPSOID_PARAMS = {
'CGCS2000': {'a': 6378137.0, 'f': 1 / 298.257222101},
'WGS84': {'a': 6378137.0, 'f': 1 / 298.257223563},
'北京54': {'a': 6378245.0, 'f': 1 / 298.3},
'西安80': {'a': 6378140.0, 'f': 1 / 298.257},
}
@dataclass
class Ellipsoid:
"""椭球参数"""
a: float # 长半轴
f: float # 扁率
b: float # 短半轴
e2: float # 第一偏心率平方
e2_second: float # 第二偏心率平方
def __init__(self, name: str):
if name not in ELLIPSOID_PARAMS:
raise ValueError(f"未知椭球: {name}")
params = ELLIPSOID_PARAMS[name]
self.a = params['a']
self.f = params['f']
self.b = self.a * (1 - self.f)
self.e2 = 1 - (self.b ** 2) / (self.a ** 2)
self.e2_second = (self.a ** 2) / (self.b ** 2) - 1
class CoordinateConverter:
"""坐标转换器"""
def __init__(self, ellipsoid: str = 'CGCS2000'):
"""
初始化坐标转换器
Args:
ellipsoid: 椭球类型
"""
self.ellipsoid = Ellipsoid(ellipsoid)
def dms_to_decimal(self, degrees: int, minutes: int, seconds: float) -> float:
"""度分秒转十进制度"""
return degrees + minutes / 60 + seconds / 3600
def decimal_to_dms(self, decimal: float) -> Tuple[int, int, float]:
"""十进制度转度分秒"""
d = int(decimal)
m = int((decimal - d) * 60)
s = (decimal - d - m / 60) * 3600
return d, m, s
def deg_to_rad(self, deg: float) -> float:
"""度转弧度"""
return deg * math.pi / 180
def rad_to_deg(self, rad: float) -> float:
"""弧度转度"""
return rad * 180 / math.pi
def gauss_forward(
self,
latitude: float,
longitude: float,
central_meridian: float,
false_easting: float = 500000.0
) -> Tuple[float, float]:
"""
高斯-克吕格投影正算
Args:
latitude: 纬度(度)
longitude: 经度(度)
central_meridian: 中央子午线(度)
false_easting: 东偏移(m)
Returns:
(X, Y): 平面坐标(m)
"""
a = self.ellipsoid.a
e2 = self.ellipsoid.e2
B = self.deg_to_rad(latitude)
L = self.deg_to_rad(longitude)
L0 = self.deg_to_rad(central_meridian)
l = L - L0 # 经差
# 计算辅助量
sinB = math.sin(B)
cosB = math.cos(B)
tanB = math.tan(B)
N = a / math.sqrt(1 - e2 * sinB ** 2) # 卯酉圈曲率半径
# 计算系数
t = tanB
eta2 = self.ellipsoid.e2_second * cosB ** 2
# 子午线弧长
X0 = self._meridian_arc_length(B)
# 高斯投影公式
X = X0 + N / 2 * sinB * cosB * l ** 2 + \
N / 24 * sinB * cosB ** 3 * (5 - t ** 2 + 9 * eta2) * l ** 4 + \
N / 720 * sinB * cosB ** 5 * (61 - 58 * t ** 2 + t ** 4) * l ** 6
Y = N * cosB * l + \
N / 6 * cosB ** 3 * (1 - t ** 2 + eta2) * l ** 3 + \
N / 120 * cosB ** 5 * (5 - 18 * t ** 2 + t ** 4 + 14 * eta2 - 58 * t ** 2 * eta2) * l ** 5
Y = Y + false_easting
return X, Y
def _meridian_arc_length(self, B: float) -> float:
"""计算子午线弧长"""
a = self.ellipsoid.a
e2 = self.ellipsoid.e2
# 简化计算,使用级数展开
A0 = a * (1 - e2 / 4 - 3 * e2 ** 2 / 64 - 5 * e2 ** 3 / 256)
A2 = a * (3 * e2 / 8 + 3 * e2 ** 2 / 32 + 45 * e2 ** 3 / 1024)
A4 = a * (15 * e2 ** 2 / 256 + 45 * e2 ** 3 / 1024)
A6 = a * (35 * e2 ** 3 / 3072)
return A0 * B - A2 * math.sin(2 * B) + A4 * math.sin(4 * B) - A6 * math.sin(6 * B)
def four_parameter_transform(
self,
source_x: float,
source_y: float,
params: Dict[str, float]
) -> Tuple[float, float]:
"""
四参数转换
Args:
source_x: 源X坐标
source_y: 源Y坐标
params: 四参数字典 {dx, dy, rotation(度), scale}
Returns:
(target_x, target_y): 目标坐标
"""
dx = params.get('dx', 0.0)
dy = params.get('dy', 0.0)
rotation = self.deg_to_rad(params.get('rotation', 0.0))
scale = params.get('scale', 1.0)
cos_r = math.cos(rotation)
sin_r = math.sin(rotation)
target_x = dx + scale * (source_x * cos_r - source_y * sin_r)
target_y = dy + scale * (source_x * sin_r + source_y * cos_r)
return target_x, target_y
def seven_parameter_transform(
self,
source_x: float,
source_y: float,
source_z: float,
params: Dict[str, float]
) -> Tuple[float, float, float]:
"""
七参数转换(简化版,适用于小旋转角)
Args:
source_x, source_y, source_z: 源坐标
params: 七参数字典 {dx, dy, dz, rx(秒), ry(秒), rz(秒), scale(ppm)}
Returns:
(target_x, target_y, target_z): 目标坐标
"""
dx = params.get('dx', 0.0)
dy = params.get('dy', 0.0)
dz = params.get('dz', 0.0)
rx = self.deg_to_rad(params.get('rx', 0.0) / 3600) # 秒转弧度
ry = self.deg_to_rad(params.get('ry', 0.0) / 3600)
rz = self.deg_to_rad(params.get('rz', 0.0) / 3600)
scale = 1.0 + params.get('scale', 0.0) * 1e-6
# 旋转矩阵(小角度近似)
target_x = dx + scale * (source_x + source_y * rz - source_z * ry)
target_y = dy + scale * (-source_x * rz + source_y + source_z * rx)
target_z = dz + scale * (source_x * ry - source_y * rx + source_z)
return target_x, target_y, target_z
def create_construction_coordsystem(
self,
origin_x: float,
origin_y: float,
azimuth: float
) -> Dict:
"""
建立施工坐标系
Args:
origin_x: 施工坐标系原点在地方系中的X
origin_y: 施工坐标系原点在地方系中的Y
azimuth: 施工坐标系X轴方位角(度)
Returns:
四参数字典
"""
rotation = -azimuth # 施工系到地方系的旋转
return {
'dx': origin_x,
'dy': origin_y,
'rotation': rotation,
'scale': 1.0
}
def convert_to_construction(
self,
local_x: float,
local_y: float,
origin_x: float,
origin_y: float,
azimuth: float
) -> Tuple[float, float]:
"""
地方坐标转施工坐标
Args:
local_x, local_y: 地方坐标
origin_x, origin_y: 施工原点
azimuth: 施工X轴方位角
Returns:
施工坐标
"""
# 平移到原点
dx = local_x - origin_x
dy = local_y - origin_y
# 旋转
rotation = self.deg_to_rad(-azimuth)
cos_r = math.cos(rotation)
sin_r = math.sin(rotation)
const_x = dx * cos_r - dy * sin_r
const_y = dx * sin_r + dy * cos_r
return const_x, const_y
def print_conversion_report(
source: Tuple[float, ...],
target: Tuple[float, ...],
conversion_type: str
) -> None:
"""打印转换报告"""
print("=" * 55)
print(f"坐标转换报告 ({conversion_type})")
print("=" * 55)
print(f"源坐标: {source}")
print(f"目标坐标: {target}")
print("=" * 55)
# CLI接口
if __name__ == '__main__':
import argparse
import json
parser = argparse.ArgumentParser(description='坐标系统转换工具')
subparsers = parser.add_subparsers(dest='command', help='转换类型')
# 高斯正算
gauss_parser = subparsers.add_parser('gauss-forward', help='高斯投影正算')
gauss_parser.add_argument('--lat', type=float, required=True, help='纬度(度)')
gauss_parser.add_argument('--lon', type=float, required=True, help='经度(度)')
gauss_parser.add_argument('--cm', type=float, required=True, help='中央子午线(度)')
gauss_parser.add_argument('--ellipsoid', type=str, default='CGCS2000')
# 四参数转换
four_parser = subparsers.add_parser('four-param', help='四参数转换')
four_parser.add_argument('--x', type=float, required=True, help='源X')
four_parser.add_argument('--y', type=float, required=True, help='源Y')
four_parser.add_argument('--params', type=str, required=True, help='参数文件')
# 施工坐标
const_parser = subparsers.add_parser('to-construction', help='转施工坐标')
const_parser.add_argument('--x', type=float, required=True, help='地方X')
const_parser.add_argument('--y', type=float, required=True, help='地方Y')
const_parser.add_argument('--origin-x', type=float, required=True, help='原点X')
const_parser.add_argument('--origin-y', type=float, required=True, help='原点Y')
const_parser.add_argument('--azimuth', type=float, required=True, help='方位角(度)')
args = parser.parse_args()
converter = CoordinateConverter()
if args.command == 'gauss-forward':
x, y = converter.gauss_forward(args.lat, args.lon, args.cm)
print(f"X = {x:.3f} m, Y = {y:.3f} m")
elif args.command == 'four-param':
with open(args.params, 'r') as f:
params = json.load(f)
tx, ty = converter.four_parameter_transform(args.x, args.y, params)
print(f"目标X = {tx:.3f} m, 目标Y = {ty:.3f} m")
elif args.command == 'to-construction':
cx, cy = converter.convert_to_construction(
args.x, args.y, args.origin_x, args.origin_y, args.azimuth
)
print(f"施工X = {cx:.3f} m, 施工Y = {cy:.3f} m")
else:
parser.print_help()

  • 高斯投影正算精度约为0.1~1mm
  • 四参数转换精度取决于公共点分布和数量,建议至少3个公共点
  • 七参数转换适用于大范围,局部精度不如四参数
  • 高斯投影适用于3°带和6°带
  • 四参数适用于同一椭球、小范围(<50km)转换
  • 七参数适用于不同椭球间转换

Q: 转换后残差大怎么办? A: 检查公共点坐标是否有误;检查参数是否适用于该区域;考虑使用拟合转换。

Q: 带号如何确定? A: 3°带:n = round(L/3);6°带:n = round(L/6)。中央子午线L₀ = 3°×n或6°×n-3。

Q: 施工坐标系与地方系如何衔接? A: 通过至少2个公共点建立四参数关系,定期检核转换精度。



#坐标转换 #CGCS2000 #WGS84 #地方坐标系 #施工坐标系 #七参数 #四参数 #高斯投影 #Python工具 #RailWise


文档版本: 1.0.0 | 最后更新: 2026-06-10 | 作者: RailWise技术团队

引用与复核把知识带回真实工程判断

引用时保留页面与来源线索;涉及标准条文、阈值、频率和项目结论,请回到现行依据与责任人复核。

查看 Agent 使用规则