椭球种类/椭球参数 | 克拉索夫斯基椭球 | 1975国际椭球 | WGS84椭球 | 国家2000坐标系椭球 |
---|---|---|---|---|
长半轴(a) | 6378245 | 6378140 | 6378137 | 6378137 |
短半轴(b) | 6356863.0187730473 | 6356755.288157528 | 6356752.3142451795 | 6356752.3141403558 |
从左到右分别对应常用的北京54坐标系、西安80坐标系、WGS84坐标系以及CGCS2000坐标系。习惯上我们用长半轴a以及扁率表示表示椭球,有了长半轴和短半轴参数信息,常见的表示参数可以下面根据公式求得。
扁率: ∂ = a − b b \partial = \frac{a-b}{b} ∂=ba−b
第一偏心率: e = a 2 − b 2 a e=\frac{\sqrt{a^2-b^2}}{a} e=aa2−b2
第二偏心率: e ′ = a 2 − b 2 b e'=\frac{\sqrt{a^2-b^2}}{b} e′=ba2−b2
图 1 、地心地固坐标系 图1、地心地固坐标系 图1、地心地固坐标系
地心地固坐标系(Earth-Centered,Earth-Fixed,简称ECEF)简称地心坐标系,是一种以地心为原点的地固坐标系(也称地球坐标系)。原点O(0,0,0)为地球质心,z轴与地轴平行指向北极点,x轴指向本初子午线与赤道的交点,y轴垂直于xOz平面(即东经90度与赤道的交点)构成右手坐标系。
图 2 、 G P S 高度计算 图2、GPS高度计算 图2、GPS高度计算
wgs84大地坐标系是由经度(longitude),纬度(latitude),高度(altitude)组成的坐标系,它给出一点的大地纬度、大地经度和大地高程告诉我们该点在地球中的位置,故又被称作纬经高(LLA)坐标系。84坐标系和上面的ECEF坐标系一样,只不过坐标表示方式不一样,具体如下:
图 3 、全局和局部坐标系 图3、全局和局部坐标系 图3、全局和局部坐标系
在 P i P_i Pi 处对应于北、东、上方向的局部(切平面)坐标系的轴 n ‾ i \underline{n}_i ni, e ‾ i \underline{e}_i ei, u ‾ i \underline{u}_i ui 在全局坐标系中表示为:
n ‾ i = [ − s i n φ i c o s λ i − s i n φ i s i n λ i c o s φ i ] , e ‾ i = [ − s i n λ i c o s λ i 0 ] , u ‾ i = [ c o s φ i c o s λ i c o s φ i s i n λ i s i n φ i ] \underline{n}_i =\left[ \begin{matrix} -sin\varphi_icos\lambda_i \\ -sin\varphi_isin\lambda_i \\ cos\varphi_i \end{matrix} \right],\underline{e}_i =\left[ \begin{matrix} -sin\lambda_i \\ cos\lambda_i \\ 0 \end{matrix} \right],\underline{u}_i =\left[ \begin{matrix} cos\varphi_icos\lambda_i \\ cos\varphi_isin\lambda_i \\ sin\varphi_i \end{matrix} \right] ni= −sinφicosλi−sinφisinλicosφi ,ei= −sinλicosλi0 ,ui= cosφicosλicosφisinλisinφi
其中,向量 n i n_i ni 和 e i e_i ei 张成图3中点 P i P_i Pi 的切平面。局部水平系统的第三个坐标轴,即向量 u i u_i ui,与切平面正交,指向圆周率的天顶,这个坐标轴的方向与椭球法线重合。
图 4 、局部坐标系中的测量量 图4、局部坐标系中的测量量 图4、局部坐标系中的测量量
现在介绍局部坐标系中向量 x ‾ i j \underline{x}_{ij} xij的分量 n i j , e i j , u i j n_{ij}, e_{ij}, u_{ij} nij,eij,uij,这些坐标有时表示为ENU坐标。考虑图4,这些分量是向量 X ‾ i j \underline{X}_{ij} Xij在局部坐标轴 n ‾ i \underline{n}_i ni, e ‾ i \underline{e}_i ei, u ‾ i \underline{u}_i ui 上投影得到的,因此:
x ‾ i j = [ n i j e i j u i j ] = [ n ‾ i . X ‾ i j e ‾ i . X ‾ i j u ‾ i . X ‾ i j ] \underline{x}_{ij} =\left[ \begin{matrix} n_{ij} \\ e_{ij} \\ u_{ij} \end{matrix} \right]=\left[ \begin{matrix} \underline{n}_{i}.\underline{X}_{ij} \\ \underline{e}_{i}.\underline{X}_{ij} \\ \underline{u}_{i}.\underline{X}_{ij} \end{matrix} \right] xij= nijeijuij = ni.Xijei.Xijui.Xij
图 5 、 U T M 坐标系生成方式 图5、UTM坐标系生成方式 图5、UTM坐标系生成方式
UTM系统是横向墨卡托系统的改进。首先,椭球体被划分为60个区域,每个区域的宽度为6个经度;其次,将 s c a l e = 0.9996 scale=0.9996 scale=0.9996的比例因子应用于平面的共形坐标,比例因子的作用是为了避免一个区域的外部地区出现相当大的扭曲。横向划分完成后,纵向也按一定的规则进行划分,最终将图1的球面坐标系转化成图2的平面坐标系,具体划分规则见下文。
每6°被编排为一个经度区间,每一个经度区间均以一个数字表示,由西(180°W)向东(180°E)以01至60编排。
从南纬80°开始,每8°被编排为一个纬度区间,而最北的纬度区间(北纬74°以北之区间)则被延伸至北纬84°,以覆盖世界上大部分陆地。每一个纬度区间均以一个英文字母表示,由南向北数以"C"至"X"编排(省略"I"和"O"防止与1和0混淆),具体情况如下︰
维度 | 英文字母 |
---|---|
南纬80° - 南纬72° | C |
南纬72° - 南纬64° | D |
南纬64° - 南纬56° | E |
南纬56° - 南纬48° | F |
南纬48° - 南纬40° | G |
南纬40° - 南纬32° | H |
南纬32° - 南纬24° | J |
南纬24° - 南纬16° | K |
南纬16° - 南纬8° | L |
南纬8° - 赤道0° | M |
赤道0° - 北纬8° | N |
北纬8° - 北纬16° | P |
北纬16° - 北纬24° | Q |
北纬24° - 北纬32° | R |
北纬32° - 北纬40° | S |
北纬40° - 北纬48° | T |
北纬48° - 北纬56° | U |
北纬56° - 北纬64° | V |
北纬64° - 北纬72° | W |
北纬72° - 北纬84° | X |
字母A、B、Y、Z表示UTM坐标系中的极地区域。指定一个UTM网格区域,区域编号(列)在区域字母(行)之前给出,例如 zone 11U。
如上图所示,用水平带划分区域,使得每个分区具有6°经度宽和8°纬度高的维度,但是也有例外,最北的带(X)纬度高是12°而不是8°,从72°N延伸到84°N纬度。覆盖挪威西海岸的32V区由原来的6°经度拓宽为9°经度,导致 31V区缩小。33X和35X区域已经拓宽到12°,覆盖斯瓦尔巴特群岛。同样,31X和37X区域被加宽到 9°。因此,32X、34X 和36X区域被省略。
投影带(zone)中心子午线“东值”为50万米,投影带中心子午线以东的“东值”增加,投影带中心子午线以西的“东值”减小,例如中央子午线以东8米的一点,其东坐标为500000 + 8 = 500008mE。中央子午线以西350米的一个点东坐标为500000 - 350 = 499650mE。
北半球的“北值”表示一个点位于赤道以北的米数;南半球的“北值”等于1000万米减去该点离赤道的距离;赤道处等于1000万米。例如:位于赤道以南34米的点的北坐标9999966mN,而在赤道以北34米的点的北坐标为0000034mN。如果“北值”小于7位,通常会在“北值”前面加上0,以表示“北值”为7位数字。
图 6 、笛卡尔坐标系 X , Y , Z 和椭球坐标系 λ , φ , h 图6、笛卡尔坐标系 X,Y,Z 和椭球坐标系 \lambda,\varphi,h 图6、笛卡尔坐标系X,Y,Z和椭球坐标系λ,φ,h
如图1所示,坐标转换可以根据三角函数来计算,其中wgs84大地坐标系到ecef地心坐标系的转换公式如下:
{ X = ( N + h ) c o s φ c o s λ Y = ( N + h ) c o s φ s i n λ Z = ( b 2 a 2 N + h ) s i n φ (1) \left\{\begin{aligned}X&=(N+h)cos\varphi cos\lambda\\Y&=(N+h)cos\varphi sin\lambda \\Z&=(\frac{b^2}{a^2}N+h)sin\varphi\end{aligned}\right. \tag{1} ⎩ ⎨ ⎧XYZ=(N+h)cosφcosλ=(N+h)cosφsinλ=(a2b2N+h)sinφ(1)
其中N=OB为卯酉圈曲率半径可由下面公式获得:
N = a 2 a 2 c o s 2 φ + b 2 s i n 2 φ (2) N=\frac{a^2}{\sqrt{a^2cos^2\varphi+b^2sin^2\varphi}}\tag{2} N=a2cos2φ+b2sin2φa2(2)
a和b分别为wgs84椭球体的长半轴和短半轴。
定义辅助变量 p p p:
p = X 2 + Y 2 = ( N + h ) c o s φ (3) p=\sqrt{X^2+Y^2}=(N+h)cos\varphi\tag{3} p=X2+Y2=(N+h)cosφ(3)
因此椭球坐标系高度为:
h = p c o s φ − N (4) h=\frac{p}{cos\varphi}-N\tag{4} h=cosφp−N(4)
由:
e 2 = a 2 − b 2 a 2 = > b 2 / a 2 = 1 − e 2 (5) e^2=\frac{a^2-b^2}{a^2} =>b^2/a^2=1-e^2\tag{5} e2=a2a2−b2=>b2/a2=1−e2(5)
将上述公式代入(1)得:
Z = ( N + h − e 2 N ) s i n φ = ( N + h ) ( 1 − e 2 N N + h ) s i n φ (6) Z=(N+h-e^2N)sin\varphi=(N+h)(1-e^2\frac{N}{N+h})sin\varphi\tag{6} Z=(N+h−e2N)sinφ=(N+h)(1−e2N+hN)sinφ(6)
将该等式除以等式(3)得:
Z p = ( 1 − e 2 N N + h ) t a n φ (7) \frac{Z}{p}=(1-e^2\frac{N}{N+h})tan\varphi\tag{7} pZ=(1−e2N+hN)tanφ(7)
从而推出椭球坐标系的纬度 φ \varphi φ:
t a n φ = Z p ( 1 − e 2 N N + h ) − 1 (8) tan\varphi=\frac{Z}{p}(1-e^2\frac{N}{N+h})^{-1}\tag{8} tanφ=pZ(1−e2N+hN)−1(8)
至于椭球坐标系的经度值 λ \lambda λ 可直接由三角公式得到:
t a n λ = Y X (9) tan\lambda=\frac{Y}{X}\tag{9} tanλ=XY(9)
高度、纬度、经度由等式(4)(8)(9)给出,注意除了经度可以直接由地心坐标计算外,高度和纬度都是了不止一个变量,为计算出最终的wgs84大地坐标系,有两种方法可以采纳:迭代法和近似法,西面逐一介绍。
算法流程如下:
1、计算 p = X 2 + Y 2 p=\sqrt{X^2+Y^2} p=X2+Y2
2、计算近似值 φ ( 0 ) \varphi_{(0)} φ(0)
t a n φ ( 0 ) = Z p ( 1 − e 2 ) − 1 tan\varphi_{(0)}=\frac{Z}{p}(1-e^2)^{-1} tanφ(0)=pZ(1−e2)−1
3、计算近似值 N ( 0 ) N_{(0)} N(0)
N ( 0 ) = a 2 a 2 c o s 2 φ ( 0 ) + b 2 s i n 2 φ ( 0 ) N_{(0)}=\frac{a^2}{\sqrt{a^2cos^2\varphi_{(0)}+b^2sin^2\varphi_{(0)}}} N(0)=a2cos2φ(0)+b2sin2φ(0)a2
4、计算椭球坐标高度
h = p c o s φ ( 0 ) − N ( 0 ) h=\frac{p}{cos\varphi_{(0)}}-N_{(0)} h=cosφ(0)p−N(0)
5、计算改进纬度
t a n φ ( 0 ) = Z p ( 1 − e 2 N ( 0 ) N ( 0 ) + h ) − 1 tan\varphi_{(0)}=\frac{Z}{p}(1-e^2\frac{N_{(0)}}{N_{(0)}+h})^{-1} tanφ(0)=pZ(1−e2N(0)+hN(0))−1
6、迭代终止条件
如果 φ = φ ( 0 ) \varphi=\varphi_{(0)} φ=φ(0) 终止迭代,否则令 φ ( 0 ) = φ \varphi_{(0)}=\varphi φ(0)=φ 并继续执行步骤3。
φ = a r c t a n Z + e ′ 2 b s i n 3 θ p − e 2 a c o s 3 θ \varphi=arctan\frac{Z+e'^{2}bsin^3\theta}{p-e^2acos^3\theta} φ=arctanp−e2acos3θZ+e′2bsin3θ
λ = a r c t a n Y X \lambda=arctan\frac{Y}{X} λ=arctanXY
其中
θ = a r c t a n Z a p b 是辅助量, e ′ 2 = a 2 − b 2 b 2 是椭球第二偏心率。 \theta=arctan\frac{Za}{pb}是辅助量,e^{'2}=\frac{a^2-b^2}{b^2}是椭球第二偏心率。 θ=arctanpbZa是辅助量,e′2=b2a2−b2是椭球第二偏心率。
x = N c o s φ ℓ + 1 6 N c o s 3 φ ( 1 − t 2 + η 2 ) ℓ 3 x=Ncos\varphi\ell+\frac{1}{6}Ncos^3\varphi(1-t^2+\eta^2)\ell^3 x=Ncosφℓ+61Ncos3φ(1−t2+η2)ℓ3
+ 1 120 N c o s φ ( 5 − 18 t 2 + t 4 + 14 η 2 − 58 t 2 η 2 ) ℓ 5 +\frac{1}{120}Ncos^\varphi(5-18t^2+t^4+14\eta^2-58t^2\eta^2)\ell^5 +1201Ncosφ(5−18t2+t4+14η2−58t2η2)ℓ5
+ 1 5040 N c o s 7 φ ( 61 − 479 t 2 + 179 t 4 − t 6 ) ℓ 7 + . . . +\frac{1}{5040}Ncos^7\varphi(61-479t^2+179t^4-t^6)\ell^7+... +50401Ncos7φ(61−479t2+179t4−t6)ℓ7+...
y = B ( φ ) + t 2 c o s 2 φ ℓ 2 + t 24 N c o s 4 φ ( 5 − t 2 + 9 η 2 + 4 η 4 ) ℓ 4 y=B(\varphi)+\frac{t}{2}cos^2\varphi\ell^2+\frac{t}{24}Ncos^4\varphi(5-t^2+9\eta^2+4\eta^4)\ell^4 y=B(φ)+2tcos2φℓ2+24tNcos4φ(5−t2+9η2+4η4)ℓ4
+ t 720 N c o s 6 φ ( 61 − 58 t 2 + t 4 + 270 η 2 − 330 t 2 η 2 ) ℓ 6 +\frac{t}{720}Ncos^6\varphi(61-58t^2+t^4+270\eta^2-330t^2\eta^2)\ell^6 +720tNcos6φ(61−58t2+t4+270η2−330t2η2)ℓ6
+ t 40320 N c o s 8 φ ( 1385 − 3111 t 2 + 543 t 4 − t 6 ) ℓ 8 + . . . +\frac{t}{40320}Ncos^8\varphi(1385-3111t^2+543t^4-t^6)\ell^8+... +40320tNcos8φ(1385−3111t2+543t4−t6)ℓ8+...
x = x ∗ s c a l e + 500000.0 x=x*scale + 500000.0 x=x∗scale+500000.0
y = { y ∗ s c a l e ( 北半球 ) y ∗ s c a l e + 10000000 ( 南半球 ) y =\left\{\begin{aligned}y&*scale (北半球)\\y&*scale+10000000 (南半球)\end{aligned}\right. y={yy∗scale(北半球)∗scale+10000000(南半球)
其中:
B ( φ ) B(\varphi) B(φ) …子午线弧长
e ′ 2 = ( a 2 − b 2 ) / b 2 e^{'2}=(a^2-b^2)/b^2 e′2=(a2−b2)/b2 …第二偏心率的平方
η 2 = e ′ 2 c o s 2 φ \eta^2=e^{'2}cos^2\varphi η2=e′2cos2φ …辅助变量
N = a 2 b 1 + η 2 N=\frac{a^2}{b\sqrt{1+\eta^2}} N=b1+η2a2 …radius of curvature in prime vertical
t = t a n φ t=tan\varphi t=tanφ …辅助变量
ℓ = λ − λ 0 \ell=\lambda-\lambda_{0} ℓ=λ−λ0 …与中央经线的经度差
λ 0 \lambda_{0} λ0 …中央经线的经度值
子午线的弧长 B ( φ ) B(\varphi) B(φ)为从赤道到待映射点的椭球距离,可以通过级数展开计算:
B ( φ ) = α [ φ + β s i n 2 φ + γ s i n 4 φ + δ s i n 6 φ + ϵ s i n 8 φ + . . . ] B(\varphi)=\alpha[\varphi+\beta sin2\varphi+\gamma sin4\varphi+\delta sin6\varphi +\epsilon sin8\varphi+...] B(φ)=α[φ+βsin2φ+γsin4φ+δsin6φ+ϵsin8φ+...]
其中:
α = a + b 2 ( 1 + 1 4 n 2 + 1 64 n 4 + . . . ) \alpha=\frac{a+b}{2}(1+\frac{1}{4}n^2+\frac{1}{64}n^4+...) α=2a+b(1+41n2+641n4+...)
β = − 3 2 n + 9 16 n 3 − 3 32 n 5 + . . . \beta=-\frac{3}{2}n+\frac{9}{16}n^3-\frac{3}{32}n^5+... β=−23n+169n3−323n5+...
γ = 15 16 n 2 − 15 32 n 4 + . . . \gamma=\frac{15}{16}n^2-\frac{15}{32}n^4+... γ=1615n2−3215n4+...
δ = − 35 48 n 3 + 105 256 n 5 − . . . \delta=-\frac{35}{48}n^3+\frac{105}{256}n^5-... δ=−4835n3+256105n5−...
ϵ = 315 512 n 4 + . . . \epsilon=\frac{315}{512}n^4+... ϵ=512315n4+...
n = a − b a + b n=\frac{a-b}{a+b} n=a+ba−b
下表给出了两种椭球对应的参数:
计算好的参数 | 贝塞尔椭球 | WGS-84椭球 |
---|---|---|
α \alpha α | 6366742.5203m | 6367449.1458m |
β \beta β | − 2.51127456 ⋅ 1 0 − 3 -2.51127456·10^{-3} −2.51127456⋅10−3 | − 2.51882792 ⋅ 1 0 − 3 -2.51882792·10^{-3} −2.51882792⋅10−3 |
γ \gamma γ | 2.62771 ⋅ 1 0 − 6 2.62771·10^{-6} 2.62771⋅10−6 | 2.64354 ⋅ 1 0 − 6 2.64354·10^{-6} 2.64354⋅10−6 |
δ \delta δ | − 3.42 ⋅ 1 0 − 9 -3.42·10^{-9} −3.42⋅10−9 | − 3.45 ⋅ 1 0 − 9 -3.45·10^{-9} −3.45⋅10−9 |
ϵ \epsilon ϵ | 5 ⋅ 1 0 − 12 5·10^{-12} 5⋅10−12 | 5 ⋅ 1 0 − 12 5·10^{-12} 5⋅10−12 |
x = x − 500000 s c a l e x=\frac{x-500000}{scale} x=scalex−500000
y = { y s c a l e ( 北半球 ) y − 10000000 s c a l e ( 南半球 ) y =\left\{\begin{aligned}&\frac{y}{scale} (北半球)\\ &\frac{y-10000000}{scale} (南半球)\end{aligned}\right. y=⎩ ⎨ ⎧scaley(北半球)scaley−10000000(南半球)
φ = φ f + t f 2 N f 2 ( − 1 − η f 2 ) x 2 \varphi=\varphi_f+\frac{t_f}{2N_f^2}(-1-\eta_f^2)x^2 φ=φf+2Nf2tf(−1−ηf2)x2
+ t f 24 N f 4 ( 5 + 3 t f 2 + 6 η f 2 − 6 t f 2 η f 2 − 3 η f 4 − 9 t f 2 η f 4 ) x 4 +\frac{t_f}{24N_f^4}(5+3t_f^2+6\eta_f^2-6t_f^2\eta_f^2-3\eta_f^4-9t_f^2\eta_f^4)x^4 +24Nf4tf(5+3tf2+6ηf2−6tf2ηf2−3ηf4−9tf2ηf4)x4
+ t f 720 N f 6 ( − 61 − 90 t f 2 − 45 t f 4 − 107 η f 2 + 162 t f 2 η 2 + 45 t f 4 η 2 ) x 6 +\frac{t_f}{720N_f^6}(-61-90t_f^2-45t_f^4-107\eta_f^2+162t_f^2\eta^2+45t_f^4\eta^2)x^6 +720Nf6tf(−61−90tf2−45tf4−107ηf2+162tf2η2+45tf4η2)x6
+ t f 40320 N f 8 ( 1385 + 3633 t f 2 + 4095 t f 4 + 1575 t f 6 ) x 8 + . . . +\frac{t_f}{40320N_f^8}(1385+3633t_f^2+4095t_f^4+1575t_f^6)x^8+... +40320Nf8tf(1385+3633tf2+4095tf4+1575tf6)x8+...
λ = λ 0 + 1 N f c o s φ f x + 1 6 N f 3 c o s φ f ( − 1 − 2 t f 2 − η f 2 ) x 3 \lambda=\lambda_0+\frac{1}{N_f cos\varphi_f}x+\frac{1}{6N_f^3cos\varphi_f}(-1-2t_f^2-\eta_f^2)x^3 λ=λ0+Nfcosφf1x+6Nf3cosφf1(−1−2tf2−ηf2)x3
+ 1 120 N f 5 c o s φ f ( 5 + 28 t f 2 + 24 t f 4 + 6 η 2 + 8 t f 2 η f 2 ) x 5 +\frac{1}{120N_f^5cos\varphi_f}(5+28t_f^2+24t_f^4+6\eta^2+8t_f^2\eta_f^2)x^5 +120Nf5cosφf1(5+28tf2+24tf4+6η2+8tf2ηf2)x5
+ 1 5040 N f 7 c o s φ f ( − 61 − 662 t f 2 − 1320 t f 4 − 720 t f 6 ) x 7 + . . . +\frac{1}{5040N_f^7cos\varphi_f}(-61-662t_f^2-1320t_f^4-720t_f^6)x^7+... +5040Nf7cosφf1(−61−662tf2−1320tf4−720tf6)x7+...
footpoint latitude φ f \varphi_f φf由级数展开计算:
φ f = y ‾ + β ‾ s i n 2 y ‾ + γ ‾ s i n 4 y ‾ + δ ‾ s i n 6 y ‾ + ϵ ‾ s i n 8 y ‾ + . . . \varphi_f=\overline{y}+\overline{\beta}sin2\overline{y}+\overline{\gamma}sin4\overline{y}+\overline{\delta}sin6\overline{y}+\overline{\epsilon}sin8\overline{y}+... φf=y+βsin2y+γsin4y+δsin6y+ϵsin8y+...
其中:
α ‾ = a + b 2 ( 1 + 1 4 n 2 + 1 64 n 4 + . . . ) \overline{\alpha}=\frac{a+b}{2}(1+\frac{1}{4}n^2+\frac{1}{64}n^4+...) α=2a+b(1+41n2+641n4+...)
β ‾ = 3 2 n − 27 32 n 3 + 269 512 n 5 + . . . \overline{\beta}=\frac{3}{2}n-\frac{27}{32}n^3+\frac{269}{512}n^5+... β=23n−3227n3+512269n5+...
γ ‾ = 21 16 n 2 − 55 32 n 4 + . . . \overline{\gamma}=\frac{21}{16}n^2-\frac{55}{32}n^4+... γ=1621n2−3255n4+...
δ ‾ = 151 96 n 3 − 417 128 n 5 + . . . \overline{\delta}=\frac{151}{96}n^3-\frac{417}{128}n^5+... δ=96151n3−128417n5+...
ϵ ‾ = 1097 512 n 4 + . . . \overline{\epsilon}=\frac{1097}{512}n^4+... ϵ=5121097n4+...
y ‾ = y α ‾ \overline{y}=\frac{y}{\overline{\alpha}} y=αy
注意系数 α ‾ \overline{\alpha} α与 α \alpha α in(10.23)相同,带有下标f的项必须根据 φ f \varphi_f φf计算。
t f = t a n ( φ f ) t_f=tan(\varphi_f) tf=tan(φf)
η f 2 = e ′ 2 c o s 2 ( φ f ) \eta_f^2=e^{'2}cos^2(\varphi_f) ηf2=e′2cos2(φf)
N f = a 2 b 1 + η f 2 N_f=\frac{a^2}{b\sqrt{1+\eta_f^2}} Nf=b1+ηf2a2
下表给出了两种椭球对应的参数:
计算好的参数 | 贝塞尔椭球 | WGS-84椭球 |
---|---|---|
α ‾ \overline{\alpha} α | 6366742.5203m | 6367449.1458m |
β ‾ \overline{\beta} β | 2.51127324 ⋅ 1 0 − 3 2.51127324·10^{-3} 2.51127324⋅10−3 | 2.51882658 ⋅ 1 0 − 3 2.51882658·10^{-3} 2.51882658⋅10−3 |
γ ‾ \overline{\gamma} γ | 3.67879 ⋅ 1 0 − 6 3.67879·10^{-6} 3.67879⋅10−6 | 3.70095 ⋅ 1 0 − 6 3.70095·10^{-6} 3.70095⋅10−6 |
δ ‾ \overline{\delta} δ | 7.38 ⋅ 1 0 − 9 7.38·10^{-9} 7.38⋅10−9 | 7.45 ⋅ 1 0 − 9 7.45·10^{-9} 7.45⋅10−9 |
ϵ ‾ \overline{\epsilon} ϵ | 17 ⋅ 1 0 − 12 17·10^{-12} 17⋅10−12 | 17 ⋅ 1 0 − 12 17·10^{-12} 17⋅10−12 |
#ifndef __COORDINATESYSTEM_H__
#define __COORDINATESYSTEM_H__
#include
#include
#include
double pi = 3.14159265358979;
// 椭球模型常数
double a = 6378137.0; // 长半轴(ellipsoid major axis)
double b = 6356752.3142451795; // 短半轴(ellipsoid minor axis)
double scale = 0.9996; // 缩放因子
// 经纬度
struct WGS84Coord
{
double latitude;
double longitude;
double height;
};
// UTM坐标系
struct UTMCoord
{
double x;
double y;
};
// ECEF坐标系
struct ECEFCoord
{
double x;
double y;
double z;
};
// ENU坐标系
struct ENUCoord
{
double e;
double n;
double u;
};
struct ENUAxis
{
double x;
double y;
double z;
};
// 角度转弧度
double DegToRad(double deg)
{
return (deg / 180.0 * pi);
}
// 弧度转角度
inline double RadToDeg(double rad)
{
return (rad / pi * 180.0);
}
// 计算从赤道到待映射点的椭球距离,单位为米。
double ArcLengthOfMeridian(double phi)
{
double alpha, beta, gamma, delta, epsilon, n;
n = (a - b) / (a + b);
alpha = ((a + b) / 2.0) * (1.0 + (pow(n, 2.0) / 4.0) + (pow(n, 4.0) / 64.0));
beta = (-3.0 * n / 2.0) + (9.0 * pow(n, 3.0) / 16.0) + (-3.0 * pow(n, 5.0) / 32.0);
gamma = (15.0 * pow(n, 2.0) / 16.0) + (-15.0 * pow(n, 4.0) / 32.0);
delta = (-35.0 * pow(n, 3.0) / 48.0) + (105.0 * pow(n, 5.0) / 256.0);
epsilon = (315.0 * pow(n, 4.0) / 512.0);
double result = alpha * (phi + (beta * sin(2.0 * phi)) + (gamma * sin(4.0 * phi)) + (delta * sin(6.0 * phi)) + (epsilon * sin(8.0 * phi)));
return result;
}
// 计算footpoint latitude
double FootpointLatitude(double y)
{
double y_, alpha_, beta_, gamma_, delta_, epsilon_, n;
n = (a - b) / (a + b);
alpha_ = ((a + b) / 2.0) * (1 + (pow(n, 2.0) / 4) + (pow(n, 4.0) / 64));
y_ = y / alpha_;
beta_ = (3.0 * n / 2.0) + (-27.0 * pow(n, 3.0) / 32.0) + (269.0 * pow(n, 5.0) / 512.0);
gamma_ = (21.0 * pow(n, 2.0) / 16.0) + (-55.0 * pow(n, 4.0) / 32.0);
delta_ = (151.0 * pow(n, 3.0) / 96.0) + (-417.0 * pow(n, 5.0) / 128.0);
epsilon_ = (1097.0 * pow(n, 4.0) / 512.0);
double result = y_ + (beta_ * sin(2.0 * y_)) + (gamma_ * sin(4.0 * y_)) + (delta_ * sin(6.0 * y_)) + (epsilon_ * sin(8.0 * y_));
return result;
}
// 计算UTM投影带中央子午线(角度制)
double CalCulateUTMCentralMeridian(double latitude, double longitude)
{
// A区
if (longitude < 0.0 && latitude < -80.0)
{
return -90.0;
}
// B区
if (longitude >= 0.0 && latitude < -80.0)
{
return 90.0;
}
// 31V区
if (longitude >= 0.0 && longitude < 3.0 && latitude >= 56.0 && latitude < 64.0)
{
return 1.5;
}
// 32V区
if (longitude >= 3.0 && longitude < 12.0 && latitude >= 56.0 && latitude < 64.0)
{
return 7.5;
}
// 31X区
if (longitude >= 0.0 && longitude < 9.0 && latitude >= 72.0 && latitude < 84.0)
{
return 4.5;
}
// 33X区
if (longitude >= 9.0 && longitude < 21.0 && latitude >= 72.0 && latitude < 84.0)
{
return 15.0;
}
// 35X区
if (longitude >= 21.0 && longitude < 33.0 && latitude >= 72.0 && latitude < 84.0)
{
return 27.0;
}
// 37X区
if (longitude >= 33.0 && longitude < 42.0 && latitude >= 72.0 && latitude < 84.0)
{
return 37.5;
}
// Y区
if (longitude < 0.0 && latitude >= 84.0)
{
return -90.0;
}
// A区
if (longitude >= 0.0 && latitude >= 84.0)
{
return 90.0;
}
int zone = (int)longitude / 6 + 31;
return (-183.0 + zone * 6.0);
}
// 计算UTM投影带中央子午线(角度制)
double CalCulateUTMCentralMeridian(std::string zone)
{
// A区
if (zone == "A")
{
return -90.0;
}
// B区
if (zone == "B")
{
return 90.0;
}
// 31V区
if (zone == "31V")
{
return 1.5;
}
// 32V区
if (zone == "32V")
{
return 7.5;
}
// 31X区
if (zone == "31X")
{
return 4.5;
}
// 33X区
if (zone == "33X")
{
return 15.0;
}
// 35X区
if (zone == "35X")
{
return 27.0;
}
// 37X区
if (zone == "37X")
{
return 37.5;
}
// Y区
if (zone == "Y")
{
return -90.0;
}
// Z区
if (zone == "Z")
{
return 90.0;
}
zone.substr(0, 1);
int zone_num = std::stoi(zone.substr(0, 1));
return (-183.0 + zone_num * 6.0);
}
// 经纬度转UTM
void LatLonToUTM(WGS84Coord latlon, UTMCoord& xy)
{
double phi = latlon.latitude;
double lambda = latlon.longitude;
// 计算投影带中央子午线
double center_lambda_deg = CalCulateUTMCentralMeridian(phi, lambda);
double center_lambda_rad = DegToRad(center_lambda_deg);
double lambda0 = center_lambda_rad;
double N, ep2, eta2, t, t2, ell;
double x_coef1, x_coef2, x_coef3, y_coef1, y_coef2, y_coef3;
double tmp;
ep2 = (pow(a, 2.0) - pow(b, 2.0)) / pow(b, 2.0);
eta2 = ep2 * pow(cos(phi), 2.0);
N = pow(a, 2.0) / (b * sqrt(1 + eta2));
t = tan(phi);
t2 = t * t;
ell = lambda - lambda0;
x_coef1 = 1.0 - t2 + eta2;
x_coef2 = 5.0 - 18.0 * t2 + (t2 * t2) + 14.0 * eta2 - 58.0 * t2 * eta2;
x_coef3 = 61.0 - 479.0 * t2 + 179.0 * (t2 * t2) - (t2 * t2 * t2);
xy.x = N * cos(phi) * ell + (N / 6.0 * pow(cos(phi), 3.0) * x_coef1 * pow(ell, 3.0))
+ (N / 120.0 * pow(cos(phi), 5.0) * x_coef2 * pow(ell, 5.0))
+ (N / 5040.0 * pow(cos(phi), 7.0) * x_coef3 * pow(ell, 7.0));
y_coef1 = 5.0 - t2 + 9 * eta2 + 4.0 * (eta2 * eta2);
y_coef2 = 61.0 - 58.0 * t2 + (t2 * t2) + 270.0 * eta2 - 330.0 * t2 * eta2;
y_coef3 = 1385.0 - 3111.0 * t2 + 543.0 * (t2 * t2) - (t2 * t2 * t2);
xy.y = ArcLengthOfMeridian(phi)
+ (t / 2.0 * N * pow(cos(phi), 2.0) * pow(ell, 2.0))
+ (t / 24.0 * N * pow(cos(phi), 4.0) * y_coef1 * pow(ell, 4.0))
+ (t / 720.0 * N * pow(cos(phi), 6.0) * y_coef2 * pow(ell, 6.0))
+ (t / 40320.0 * N * pow(cos(phi), 8.0) * y_coef3 * pow(ell, 8.0));
// 调整UTM东和北值
xy.x = xy.x * scale + 500000.0;
xy.y = xy.y * scale;
if (xy.y < 0.0)
xy.y += 10000000.0;
}
// UTM转经纬度
void UTMToLatLon(UTMCoord xy, bool southhemi, std::string zone, WGS84Coord& latlon)
{
double x = xy.x;
double y = xy.y;
x -= 500000.0;
x /= scale;
// 南半球
if (southhemi)
y -= 10000000.0;
y /= scale;
// 计算投影带中央子午线
double center_lambda_deg = CalCulateUTMCentralMeridian(zone);
double center_lambda_rad = DegToRad(center_lambda_deg);
double lambda0 = center_lambda_rad;
double phif, Nf, Nf2, Nf3, Nf4, Nf5, Nf6, Nf7,Nf8, etaf2, ep2, tf, tf2, tf4, cf;
double lamba_coef1, lamba_coef2, lamba_coef3, lamba_coef4;
double phi_coef1, phi_coef2, phi_coef3, phi_coef4;
phif = FootpointLatitude(y);
ep2 = (pow(a, 2.0) - pow(b, 2.0)) / pow(b, 2.0);
cf = cos(phif);
etaf2 = ep2 * pow(cf, 2.0);
Nf = pow(a, 2.0) / (b * sqrt(1 + etaf2));
Nf2 = Nf * Nf;
Nf3 = Nf2 * Nf;
Nf4 = Nf3 * Nf;
Nf5 = Nf4 * Nf;
Nf6 = Nf5 * Nf;
Nf7 = Nf6 * Nf;
Nf8 = Nf7 * Nf;
tf = tan(phif);
tf2 = tf * tf;
tf4 = tf2 * tf2;
lamba_coef1 = 1.0 / (Nf * cf);
lamba_coef2 = 1.0 / (6.0 * Nf3 * cf) * (-1.0 - 2 * tf2 - etaf2);
lamba_coef3 = 1.0 / (120.0 * Nf5 * cf) * (5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * etaf2 + 8.0 * tf2 * etaf2);
lamba_coef4 = 1.0 / (5040.0 * Nf7 * cf) * (-61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2));
latlon.longitude = lambda0 + lamba_coef1 * x + lamba_coef2 * pow(x, 3.0) + lamba_coef3 * pow(x, 5.0) + lamba_coef4 * pow(x, 7.0);
phi_coef1 = tf / (2.0 * Nf2) * (-1.0 - etaf2);
phi_coef2 = tf / (24.0 * Nf4) * (5.0 + 3.0 * tf2 + 6.0 * etaf2 - 6.0 * tf2 * etaf2 - 3.0 * (etaf2 * etaf2) - 9.0 * tf2 * (etaf2 * etaf2));
phi_coef3 = tf / (720.0 * Nf6) * (-61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * etaf2 + 162.0 * tf2 * etaf2);
phi_coef4 = tf / (40320.0 * Nf8) * (1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2));
latlon.latitude = phif + phi_coef1 * pow(x, 2.0) + phi_coef2 * pow(x, 4.0) + phi_coef3 * pow(x, 6.0) + phi_coef4 * pow(x, 8.0);
}
// 经纬度转ECEF
void LatLonHeiToECEF(WGS84Coord llh, ECEFCoord& xyz)
{
double phi = llh.latitude;
double lambda = llh.longitude;
double height = llh.height;
double sin_phi = std::sin(phi);
double cos_phi = std::cos(phi);
double sin_lambda = std::sin(lambda);
double cos_lambda = std::cos(lambda);
double N = a * a / std::sqrt(a * a * cos_phi * cos_phi + b * b * sin_phi * sin_phi);
xyz.x = (N + height) * cos_phi * cos_lambda;
xyz.y = (N + height) * cos_phi * sin_lambda;
xyz.z = (b * b / (a * a) * N + height) * sin_phi;
}
// ECEF转经纬度(近似法)
void ECEFtoLatLonHei(ECEFCoord xyz,WGS84Coord& llh)
{
double X = xyz.x;
double Y = xyz.y;
double Z = xyz.z;
double p = std::sqrt(X * X + Y * Y);
double theta = std::atan(Z * a / (p * b));
double sin_theta = std::sin(theta);
double cos_theta = std::cos(theta);
// first numerical eccentricity
double e2 = (a * a - b * b) / (a * a);
// second numerical eccentricity
double ep2 = (a * a - b * b) / (b * b);
double phi = std::atan((Z + ep2 * b * std::pow(sin_theta, 3)) / (p - e2 * a * std::pow(cos_theta, 3)));
double lambda = std::atan(Y / X);
double sin_phi = std::sin(phi);
double cos_phi = std::cos(phi);
double N = a * a / std::sqrt(a * a * cos_phi * cos_phi + b * b * sin_phi * sin_phi);
double h = p / std::cos(phi) - N;
llh.latitude = phi;
llh.longitude = lambda;
llh.height = h;
}
// 输入局部原点和某个点的wgs84坐标,计算某个点的enu坐标
void CalculateEnuXYZ(WGS84Coord original, WGS84Coord llh, ENUCoord& xyz)
{
double phi_i = original.latitude;
double lambda_i = original.longitude;
double sin_phi_i = std::sin(phi_i);
double cos_phi_i = std::cos(phi_i);
double sin_lambda_i = std::sin(lambda_i);
double cos_lambda_i = std::cos(lambda_i);
// 局部坐标系的三个主轴
ENUAxis e, n, u;
e.x = -sin_lambda_i;
e.y = cos_lambda_i;
e.z = 0;
n.x = -sin_phi_i * cos_lambda_i;
n.y = -sin_phi_i * sin_lambda_i;
n.z = cos_phi_i;
u.x = cos_phi_i * cos_lambda_i;
u.y = cos_phi_i * sin_lambda_i;
u.z = sin_phi_i;
// 计算原点和某个点的相对坐标值
ECEFCoord X_i, X_j, X_ij;
LatLonHeiToECEF(original, X_i);
LatLonHeiToECEF(llh, X_j);
X_ij.x = X_j.x - X_i.x;
X_ij.y = X_j.y - X_i.y;
X_ij.z = X_j.z - X_i.z;
// 输出enu坐标值
xyz.e = e.x * X_ij.x + e.y * X_ij.y + e.z * X_ij.z;
xyz.n = n.x * X_ij.x + n.y * X_ij.y + n.z * X_ij.z;
xyz.u = u.x * X_ij.x + u.y * X_ij.y + u.z * X_ij.z;
}
#endif //__COORDINATESYSTEM_H__