大地坐标与空间直角坐标转换

一、椭球
1、常用椭球参数

克拉索夫斯基椭球1975年国际椭球WGS-84椭球CGCS2000(2000中国大地坐标系)
a6378245(m)6378140(m)6378137(m)6378137(m)
b6356863.0187730473(m)6356755.2881575287(m)6356752.3142 (m)6356752.3141(m)
c6399698.9017827110(m)6399596.6519880105(m)6399593.6258(m)6399593.6259(m)
α1/298.31/298.2571/298.2572235631/298.257222101
e20.0066934216229660.0066943849995880.006694379990130.00669438002290
e’20.0067385254146830.0067395018194730.006739496742270.00673949677548

决定旋转椭球的大小和形状只要知道以上参数中的两个就可(至少包含一个长度元素)

我国的北京54坐标系是基于克拉索夫斯基椭球建立的,
西安80坐标系是基于1975年国际椭球建立,
GPS定位系统是基于WGS-84椭球,

CGCS2000坐标系是全球地心坐标系在我国的体现,坐标系原点是地球质心(包括大气和海洋),
Z轴指向国际时间局1984年定义的CTP,X轴为起始子午面与通过原点且正交于Z轴的赤道面,构成右手地心地固直角坐标系

2、
C#构建椭球类

class Ellipsoid
    {
        //长半轴
        public double a;
        //短半轴
        public double b;
        //扁率
        public double f;
        //第一偏心率平方
        public double ec;
        //第二偏心率平方
        public double ecc;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="a为长半轴"></param>
        /// <param name="Invf为扁率"></param>
        public Ellipsoid(double a,double Invf)
        {
            this.a = a;
            f = 1 / Invf;
            evaluate();
        }
        public Ellipsoid()
        {
            a = 6378137.000;
            f = 1 / 298.3;
            evaluate();
        }
        void evaluate()
        {
            double b = a - a * f;
            ec = 1 - Math.Pow(b, 2) / Math.Pow(a, 2);
            ecc= ec / (1-ec);
        }
    }

二、大地坐标与空间直角坐标转换

1、转换类

class Transform
    {
        public double a;
        public double ec;
        public double ecc;
        public Transform(Ellipsoid ellipsoid)
        {
            a = ellipsoid.a;
            ec = ellipsoid.ec;
            ecc = ellipsoid.ecc;
        }
        public PointXYZ BLHToXYZ(PointBLH  bLH)
        {
            double B = bLH.B;
            double L = bLH.L;
            double H = bLH.H;
            //辅助计算公式
            double W = Math.Sqrt(1 - ec * Math.Pow(Math.Sin(B), 2));
            double N = a / W;
            PointXYZ xYZ = new PointXYZ();
            xYZ.X = (N + H) * Math.Cos(B) * Math.Cos(L);
            xYZ.Y = (N + H) * Math.Cos(B) * Math.Sin(L);
            xYZ.Z = (N * (1 - ec) + H) * Math.Sin(B);
            return xYZ;
        }
        
        public PointBLH XYZToBLH(PointXYZ xYZ)
        {
            double X = xYZ.X;
            double Y = xYZ.Y;
            double Z = xYZ.Z;
            PointBLH bLH = new PointBLH();
            bLH.L = Math.Atan(Y / X);
            if (X < 0)
                bLH.L += Math.PI;
            var r = Math.Sqrt(X * X + Y * Y);
            var B1 = Math.Atan(Z / r);
            double B2;
            while (true)
            {
                var W1 = Math.Sqrt(1 - ec * (Math.Sin(B1) * Math.Sin(B1)));
                var N1 = a / W1;
                B2 = Math.Atan((Z + N1 * ec * Math.Sin(B1)) / r);
                if (Math.Abs(B2 - B1) <= 0.0000000001)
                    break;
                B1 = B2;
            }
            bLH.B = B2;
            var W = Math.Sqrt(1 - ec * (Math.Sin(B2) * Math.Sin(B2)));
            var N = a / W;
            bLH.H = r / Math.Cos(B2) - N;
            return bLH;
        }
    }

把输入的点构造成Mypoint类

class PointBLH
    {
        public double B;
        public double L;
        public double H;
    }
    class PointXYZ
    {
        public double X;
        public double Y;
        public double Z;
    }

2、大地坐标系与空间之间坐标系转换公式

在这里插入图片描述
大地坐标换算到空间直角坐标
P点投影到椭球面上,大地高为H
在这里插入图片描述

空间直角坐标换算到大地坐标

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
解算大地纬度的时候需要进行迭代计算,
保证前后两次迭代<e-10时,可保证计算精度达到0.0001″

  • 29
    点赞
  • 272
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
以下是大地坐标空间直角坐标转换的 Python 代码: ```python import math a = 6378137.0 # 长半轴 f = 1 / 298.257223563 # 扁率 def geodetic_to_ecef(latitude, longitude, height): """大地坐标空间直角坐标""" b = (1 - f) * a # 短半轴 e = math.sqrt(1 - (b / a) ** 2) # 第一偏心率 sin_latitude = math.sin(math.radians(latitude)) cos_latitude = math.cos(math.radians(latitude)) sin_longitude = math.sin(math.radians(longitude)) cos_longitude = math.cos(math.radians(longitude)) N = a / math.sqrt(1 - e ** 2 * sin_latitude ** 2) x = (N + height) * cos_latitude * cos_longitude y = (N + height) * cos_latitude * sin_longitude z = (N * (1 - e ** 2) + height) * sin_latitude return x, y, z def ecef_to_geodetic(x, y, z): """空间直角坐标大地坐标""" b = (1 - f) * a # 短半轴 e = math.sqrt(1 - (b / a) ** 2) # 第一偏心率 p = math.sqrt(x ** 2 + y ** 2) theta = math.atan2(z * a, p * b) sin_theta = math.sin(theta) cos_theta = math.cos(theta) latitude = math.atan2(z + e ** 2 * b * sin_theta ** 3, p - a * e ** 2 * cos_theta ** 3) longitude = math.atan2(y, x) N = a / math.sqrt(1 - e ** 2 * math.sin(latitude) ** 2) height = p / math.cos(latitude) - N latitude = math.degrees(latitude) longitude = math.degrees(longitude) return latitude, longitude, height ``` 其中,`geodetic_to_ecef` 函数将大地坐标转换空间直角坐标,输入参数为纬度、经度和高程,返回值为 X、Y 和 Z 坐标。`ecef_to_geodetic` 函数将空间直角坐标转换大地坐标,输入参数为 X、Y 和 Z 坐标,返回值为纬度、经度和高程。 注意,在这里使用的是 WGS84 椭球体参数。如果需要使用其他椭球体参数进行转换,则需要相应地修改代码中的 `a` 和 `f` 值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值