• 大地坐标BLH转平面坐标xyh(高斯投影坐标正算) Java版


    技术背景

      做过位置数据处理的小伙伴基本上都会遇到坐标转换,而基于高斯投影原理的大地坐标转平面坐标就是其中一种坐标转换,坐标转换的目的就是方便后面数据的处理工作,大地坐标转高斯平面坐标常用的有两种,即3°带和6°带,具体采用哪种根据实际情况而定。

    计算原理

      6°带带号n与相应的中央子午线L0经度的关系为:

    image

      3°带带号n’与相应的中央子午线L0’经度的关系为:

    image

      设参考椭球的长半轴为 a,第一偏心率为 e,并令:

    image

      设中央子午线的经度为 L0,再记:

    image

      则高斯投影正算公式为:

    image

      其中:

    image

      没学过测绘的同学对以上原理不是很理解,也很正常,大家可以查阅相关《大地测量学》书籍,具体武大版还是矿大版的,没什么区别。

    具体实现

      具体实现平台依然是IBM的Eclipse软件,编程语言为Java,下面是以3°带为例,进行高斯投影坐标正算,具体内容请看代码

      1 package package1;
      2 
      3 public class BLH_xyh {
      4 
      5 	public static double a          =  6378137;
      6 	public static double e          =  Math.sqrt(0.0066943799013);
      7 	public static double scale_wide =  3;
      8 	public static double π 			=  3.14159265358979323846;
      9 
     10 	public static void main(String[] args) {
     11 		// TODO 自动生成的方法存根
     12 		Point3d xyh = the_coordinates_are_counting(36.0307523111,120.184664478,9.7065);
     13 		System.out.println(xyh.getX()+","+xyh.getY()+","+xyh.getZ());
     14 	}
     15 	public static Point3d the_coordinates_are_counting(double B,double L,double H){
     16 		double A_ = 1
     17 					+3*e*e/4
     18 					+45*e*e*e*e/64
     19 					+175*e*e*e*e*e*e/256
     20 					+11025*e*e*e*e*e*e*e*e/16384
     21 					+43659*e*e*e*e*e*e*e*e*e*e/65536;
     22 		double B_ =   3*e*e/4+15*e*e*e*e/16
     23 					+525*e*e*e*e*e*e/512
     24 					+2205*e*e*e*e*e*e*e*e/2048
     25 					+72765*e*e*e*e*e*e*e*e*e*e/65536;
     26 		double C_ =  15*e*e*e*e/64
     27 					+105*e*e*e*e*e*e/256
     28 					+2205*e*e*e*e*e*e*e*e/4096
     29 					+10395*e*e*e*e*e*e*e*e*e*e/16384;
     30 		double D_ =  35*e*e*e*e*e*e/512
     31 					+315*e*e*e*e*e*e*e*e/2048
     32 					+31185*e*e*e*e*e*e*e*e*e*e/13072;
     33 		/*
     34 		double E_ =  315*e*e*e*e*e*e*e*e/16384
     35 					+3465*e*e*e*e*e*e*e*e*e*e/65536;
     36 		double F_ =  693*e*e*e*e*e*e*e*e*e*e/13072;
     37 		*/
     38 
     39 		double α  =  A_*a*(1-e*e);
     40 		double β  = -B_*a*(1-e*e)/2;
     41 		double γ  =  C_*a*(1-e*e)/4;
     42 		double δ  = -D_*a*(1-e*e)/6;
     43 		/*
     44 		double ε  =  E_*a*(1-e*e)/8;
     45 		double ζ  = -F_*a*(1-e*e)/10;
     46 		*/
     47 
     48 		double C0 =  α;
     49 		double C1 =  2*β+4*γ+6*δ;
     50 		double C2 = -8*γ-32*δ;
     51 		double C3 =  32*δ;
     52 
     53 		double x,y,sign;
     54 		double scale_number = Math.floor(L/scale_wide);
     55 		if(L > (scale_number * scale_wide + scale_wide/2)){
     56 			scale_number =scale_number + 1;
     57 			sign = -1;
     58 		}else{
     59 			sign =  1;
     60 		}
     61 
     62 		double L0 =  scale_wide*scale_number;
     63 		double l  =  Math.abs(L-L0);
     64 			   B  =  B*π/180;
     65 			   l  =  l*π/180;
     66 		double t  =  Math.tan(B);
     67 		double m0 =  Math.cos(B)*l;
     68 		double η  =  Math.sqrt(e*e*Math.pow(Math.cos(B),2)/(1-e*e));
     69 		double N  =  a/Math.sqrt(1-e*e*Math.pow(Math.sin(B), 2));
     70 
     71 		double X0 =  C0*B+Math.cos(B)*(C1*Math.sin(B)+C2*Math.pow(Math.sin(B),3)+C3*Math.pow(Math.sin(B), 5));
     72 
     73 			   x  =  X0
     74 					   +N*t*m0*m0/2
     75 					   +N*t*m0*m0*m0*m0*(5-t*t+9*η*η+4*η*η*η*η)/24
     76 					   +N*t*m0*m0*m0*m0*m0*m0*(61-58*t*t+t*t*t*t)/720;
     77 			   y  =  N*m0+
     78 					 N*m0*m0*m0*(1-t*t+η*η)/6+
     79 					 N*m0*m0*m0*m0*m0*m0*(5-18*t*t+t*t*t*t+14*η*η-58*η*η*t*t)/120;
     80 
     81 			   y =   y*sign+500000;
     82 
     83 		double h =   H;
     84 
     85 		Point3d xyh = new Point3d(x,y,h);
     86 		return xyh;
     87 	}
     88 }

    其中Point3d的定义如下:

      1 package package1;
      2 
      3 public class Point3d {
      4 	private double x;
      5 	private double y;
      6 	private double z;
      7 	public Point3d(double x,double y,double z){
      8 		this.x=x;
      9 		this.y=y;
     10 		this.z=z;
     11 	}
     12 	public double getX() {
     13 		return x;
     14 	}
     15 	public void setX(double x) {
     16 		this.x = x;
     17 	}
     18 	public double getY() {
     19 		return y;
     20 	}
     21 	public void setY(double y) {
     22 		this.y = y;
     23 	}
     24 	public double getZ() {
     25 		return z;
     26 	}
     27 	public void setZ(double z) {
     28 		this.z = z;
     29 	}
     30 }

    测试数据为36.0307523111,120.184664478,9.7065,运行结果如下:

    image

    至此结束

    致谢

      感谢山东科技大学北斗星光创客兴趣学习小组的王老师对于原理文档的整理以及郑** C++代码的技术分享!

    参考文档

    1、山东科技大学”北斗星光创客”兴趣学习小组GNSS技术文档

  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/thyou/p/9978330.html
Copyright © 2020-2023  润新知