高斯投影
来源:互联网 发布:无锡房价 知乎 编辑:程序博客网 时间:2024/05/24 05:03
坐标转换–高斯投影
1. 什么是高斯投影
高斯投影是地球椭球面和平面之间的一种正行投影。属于等角横切椭圆柱投影。可以想象地球为一个椭球,将赤道面作为水平面,用一个同样水平放置的圆柱将该椭球套在内部,然后把椭球投影在圆柱面上,最后把圆柱面展开,就得到了高斯投影的结果。在我国高斯投影分为3度带和6度带,大于1:1万地形图采用3度带,1:2.5万至1:50万的地形图采用6度带投影,每一个投影带都有一个中央经线,在投影过程中,中央经线就是与圆柱面相切的线。根据以上特点,我们可以发现,高斯投影后中央经线长度保持不变,赤道线为直线,但是长度有变形,越远离中央经线,变形越大,其余经线凹向中央经线,其余纬线凸向赤道线。
2. 计算公式
正算公式
其中,ρ”在使用弧度角时值为1;X为子午线弧长;t为B的正切值;l”为经度差;η计算公式:
η = e2*cosB
e2为椭球第二偏心率,X(子午线弧长)计算公式如下:
m0 = a * (1 - e1*e1); m2 = 3 * (e1 * e1 * m0) / 2.0; m4 = 5 * (e1 * e1 * m2) / 4.0; m6 = 7 * (e1 * e1 * m4) / 6.0; m8 = 9 * (e1 * e1 * m6) / 8.0; a0 = m0 + m2/2.0 + 3*m4/8.0 + 5*m6/16.0 + 35*m8/128.0; a2 = m2/2.0 + m4/2.0 + 15*m6/32.0 + 7*m8/16.0; a4 = m4/8.0 + 3*m6/16.0 + 7*m8/32.0; a6 = m6/32.0 + m8/16.0; X = a0*B - sinB*cosB*( (a2-a4+a6) + (2*a4-(16*a6/3))*sinB*sinB + 16*a6*Math.pow(sinB, 4)/3.0 );
其中e1为椭球第一偏心率。
反算公式
高斯投影反算有两种计算方式,一种是直接算法,另一种是设定初值迭代计算。这里主要说明一下迭代算法:
其中,Bf为底点纬度,即当x=X(子午线弧长)时对应的纬度,因此可以按照子午线弧长公式进行迭代。
设初始值
则按照如下公式进行迭代:
重复迭代直到差值小于ε
关于一些中间参数的计算:
给出正反算的代码:
/** * 高斯投影正算 * @param coord 要正算的坐标 * @param pcs 投影坐标系 * @param L0 中央经线 * @return */ public Coordinate gaussBL2XY(Coordinate coord, ProjectCoordinateSystem pcs, double L0){ Coordinate newCoord = new Coordinate(); double B = Math.toRadians(coord.X); double L = Math.toRadians(coord.Y); // 计算相关中间参数 double a, e1, e2; double m0, m2, m4, m6, m8; double a0, a2, a4, a6; double X; double l; double N, W; double ita2, T, sinB, cosB; a = pcs.GCS.referenceSpheroid.semimajorAxis; //长半轴 e1 = pcs.GCS.referenceSpheroid.getFirstEccentricity(); //第一偏心率 e2 = pcs.GCS.referenceSpheroid.getSecondEccentricity(); //第二偏心率 ita2 = e2*e2*Math.cos(B)*Math.cos(B); sinB = Math.sin(B); cosB = Math.cos(B); l = L - Math.toRadians(L0); W = Math.sqrt(1-e1*e1*sinB*sinB); N = a/W; T = Math.tan(B) * Math.tan(B); m0 = a * (1 - e1*e1); m2 = 3 * (e1 * e1 * m0) / 2.0; m4 = 5 * (e1 * e1 * m2) / 4.0; m6 = 7 * (e1 * e1 * m4) / 6.0; m8 = 9 * (e1 * e1 * m6) / 8.0; a0 = m0 + m2/2.0 + 3*m4/8.0 + 5*m6/16.0 + 35*m8/128.0; a2 = m2/2.0 + m4/2.0 + 15*m6/32.0 + 7*m8/16.0; a4 = m4/8.0 + 3*m6/16.0 + 7*m8/32.0; a6 = m6/32.0 + m8/16.0; X = a0*B - sinB*cosB*( (a2-a4+a6) + (2*a4-(16*a6/3))*sinB*sinB + 16*a6*Math.pow(sinB, 4)/3.0 ); newCoord.X = X + N*sinB*cosB*l*l/2.0 + N*sinB*cosB*cosB*cosB*(5-T+9*ita2+4*ita2*ita2)*l*l*l*l/24.0 + N*sinB*cosB*cosB*cosB*cosB*cosB*(61-58*T+T*T)*l*l*l*l*l*l/720.0; newCoord.Y = N*cosB*l + N*cosB*cosB*cosB*(1-T+ita2)*l*l*l/6.0 + N*cosB*cosB*cosB*cosB*cosB*(5-18*T+T*T+14*ita2-58*ita2*T)*l*l*l*l*l/120.0; // 加入尺寸变化和坐标轴偏移量 newCoord.X = newCoord.X*pcs.projectParameter.scale; newCoord.Y = newCoord.Y*pcs.projectParameter.scale; newCoord.X += pcs.projectParameter.offsetX; newCoord.Y += pcs.projectParameter.offsetY; newCoord.Z = 0; return newCoord; }/** * 高斯投影反算 * @param coord 要反算的坐标 * @param referenceSpheroid 参考椭球体 * @param L0 中央经线 * @return 返回计算结果 */ public Coordinate gaussXY2BL(Coordinate coord, ProjectCoordinateSystem pcs, double L0){ Coordinate newCoord = new Coordinate(); // 反算坐标偏移和尺度变换 double x = coord.X - pcs.projectParameter.OffsetX; double y = coord.Y - pcs.projectParameter.OffsetY; x = x/pcs.projectParameter.Scale; y = y/pcs.projectParameter.Scale; // 计算相关中间参数 double e1Pow2; double e2Pow2; double m0, m2, m4, m6, m8; double a0, a2, a4, a6, a8; double Nf, Mf, Wf; double a; double n2; double cosBf, sinBf, tanBf; a = pcs.GCS.referenceSpheroid.SemimajorAxis; e1Pow2 = pcs.GCS.referenceSpheroid.GetFirstEccentricityPow2(); e2Pow2 = pcs.GCS.referenceSpheroid.GetSecondEccentricityPow2(); m0 = a * (1 - e1Pow2); m2 = 3 * e1Pow2 * m0 / 2; m4 = 5 * e1Pow2 * m2 / 4; m6 = 7 * e1Pow2 * m4 / 6; m8 = 9 * e1Pow2 * m6 / 8; a0 = m0 + m2/2 + 3/8*m4 + 5/16*m6 + 35/128*m8; a2 = m2/2 + m4/2 + 15/32*m6 + 7/16*m8; a4 = m4/8 + 3/16*m6 + 7/32*m8; a6 = m6/32 + m8/16; a8 = m8/128; // 迭代计算Bf(底点纬度) double Bf; double Bfi1 = x/a0; double Bfi0 = Bfi1; double FBi; boolean isMin = false; int count = 0; //限制最多迭代30次 do{ Bfi0 = Bfi1; FBi = 0.0 - a2*Math.sin(2*Bfi0)/2 + a4*Math.sin(4*Bfi0)/4 - a6*Math.sin(6*Bfi0)/6 + a8*Math.sin(8*Bfi0)/8; Bfi1 = (x - FBi) / a0; if(Math.abs(Bfi1-Bfi0) < (Math.PI * Math.pow(10.0,-8)/(36*18))){ isMin = true; } count++; } while(!isMin && count < 30); Bf = Bfi1; Nf = a / Math.sqrt((1 - e1Pow2 * Math.sin(Bf) * Math.sin(Bf))); cosBf = Math.cos(Bf); sinBf = Math.sin(Bf); tanBf = Math.tan(Bf); Wf = Math.sqrt(1 - e1Pow2*sinBf*sinBf); Nf = a / Wf; Mf = a*(1 - e1Pow2)/(Wf*Wf*Wf); n2 = e2Pow2*cosBf*cosBf; newCoord.X = Bf - tanBf/(2*Mf*Nf)*y*y + tanBf/(24*Mf*Math.pow(Nf, 3))*(5+3*tanBf*tanBf+n2-9*n2*tanBf*tanBf)*Math.pow(y, 4) - tanBf/(720*Mf*Math.pow(Nf, 5))*(61+90*tanBf*tanBf+45*Math.pow(tanBf, 4))*Math.pow(y, 6); newCoord.Y = y/(Nf*cosBf) - Math.pow(y, 3)/(6*Math.pow(Nf, 3)*cosBf)*(1+2*tanBf*tanBf+n2) + Math.pow(y, 5)/(120*Math.pow(Nf, 5)*cosBf)*(5+28*tanBf*tanBf+24*Math.pow(tanBf, 4)+6*n2+8*n2*tanBf*tanBf); newCoord.Y += Math.toRadians(L0); newCoord.X = Math.toDegrees(B); newCoord.Y = Math.toDegrees(L); return newCoord; }
以上代码中的投影坐标系为自定义的数据结构,其中具体参数的计算同上面的公式介绍中一致。
第一次写博客,如有错误的地方还望指正。
ps转载请注明出处
阅读全文
2 0
- 高斯-克吕格投影
- 高斯-克吕格投影
- 高斯-克吕格投影
- 高斯投影
- 高斯投影
- 高斯-克吕格投影与UTM投影
- 高斯投影正反算
- 高斯投影正反算的代码
- 高斯-克吕格投影与地形图分带
- 高斯投影正、反算 代码
- GPS 高斯投影 坐标转换 代码
- 高斯投影正、反算
- 高斯投影坐标正反算公式
- 大地测量学高斯投影正反算
- 高斯投影正、反算
- 高斯投影 北京54转WGS84
- 高维空间中的高斯分布和随机投影
- 高斯-克吕格(Gauss-Kruger)投影与UTM投影的区别
- Scala基础入门(十一 ) Vector集合容器使用介绍
- 正数年份判断闰年代码
- 利用postfix+mutt+dovecot 搭建邮件的收发服务器
- Android布局的优化-include、merge、ViewStub
- 初识SVN
- 高斯投影
- struts2中文乱码问题
- 排列(permutition)
- 设计模式之装饰者设计模式
- python模拟网站登录
- jieba分词
- ERROR 1142 (42000): INSERT command denied to user 'radius'@'localhost' for table 'radcheck'
- 深拷贝和浅拷贝
- 使用SciPy进行常用的图像操作