C#——GPS坐标与地方坐标相互转换

  自决定总结之前做的模块以后,过了三天了,现在在公司,也不忙就简单的写一下。代码回去后附上。

  这是老师布置的第一份任务,一开始也没理解这到底是怎么回事,后来就按照错误的理解去做,做了、错了;重新理解、又做、又错,又重新理解,大约花了三周时间才把问题搞明白。当时大二,做事效率是真不行,唉……

  现在说正题吧,首先介绍一下任务:每个矿区有自己独立的坐标系,现在已知矿区中的三个点的两套坐标,一个是GPS坐标(经纬度坐标),另一个是矿区的独立坐标系中的坐标(X,Y坐标),根据这三个点的已知坐标,计算出用于坐标转换的参数。也就是给出一个点的GPS坐标,能够计算出对应的矿区坐标。

  当初接到这个问题,也没有查资料,单凭自己的理解去做。最初最笨最傻的理解是把地球近似为圆的,然后呢矿区认为是平的。基于这个假设,根据简单的几何关系去计算,计算的几何方法就不说了……没用,白瞎忙活了好久。

  后面就查了资料,这个问题前人已经总结了好多遍,现将坐标转换的具体步骤详细介绍:

    首先定义点结构体:

 1 /*---------------------------------------------------------
 2  *   // Copyright (C) 2011 东北大学
 3    // 版权所有。
 4    //
 5    // 文件名:点的结构体
 6    // 文件功能描述:定义一个点的结构体
 7    //
 8    // 创建标识:  潘腾 2013.09.12
 9    //
10    // 修改标识:
11    // 修改描述:
12  *    ------------------------------------------------------------*/
13 namespace OMCC.Calculate
14 {
15     /// <summary>
16     /// 定义一个点的结构体
17     /// </summary>
18     public struct APoint
19     {
20         public double b;      //经度坐标
21         public double l;      //纬度坐标
22         public double x1;     //高斯平面坐标系下的坐标
23         public double y1;     //高斯平面坐标系下的坐标
24         public double x2;     //地方坐标系下的坐标
25         public double y2;     //地方坐标系下的坐标
26 
27         /// <summary>
28         /// 点的结构体
29         /// </summary>
30         /// <param name="b"></param> 
31         /// <param name="l"></param>
32         /// <param name="x1"></param>
33         /// <param name="y1"></param>
34         /// <param name="x2"></param>
35         /// <param name="y2"></param>
36         public APoint(double b, double l, double x1, double y1,double x2,double y2)
37         {
38             this.b = b;
39             this.l = l;
40             this.x1 = x1;
41             this.y1 = y1;
42             this.x2 = x2;
43             this.y2 = y2;
44         }
45     }
46 }
View Code

经纬度坐标到平面坐标之间的转换

/*---------------------------------------------------------
 *   // Copyright (C) 2011 东北大学
   // 版权所有。
   //
   // 文件名:高斯转换
   // 文件功能描述:由大地坐标(经纬度坐标)到平面直角坐标
 *                     (X Y坐标)之间的转换
   //
   // 创建标识:潘腾 2013.09.12
   //
   // 修改标识:
   // 修改描述:
 *    ------------------------------------------------------------*/
using System;

namespace OMCC.Calculate
{
    /*----------------------------------------------------
     * 输入:输入某个点的大地坐标
     * 输出:该点的高斯坐标
     *------------------------------------------------*/
    class BL2XY
    {
        #region  类属性
        private APoint PointA;

        public APoint A1
        {
            get { return PointA; }
            set { PointA = value; }
        }
        #endregion

        #region 高斯转换

        /// <summary>
        /// 
        /// </summary>
        /// <param name="PointA"></param>
        /// <returns></returns>
        public double[] BL2GS(APoint PointA)
        {
            //由弧度制到角度制在化为以秒为单位的转化
            PointA.b = PointA.b * 180 / Math.PI;
            PointA.b = PointA.b * 3600;
            PointA.l = PointA.l * 180 / Math.PI;
            PointA.l = PointA.l * 3600;

            double B = PointA.b;
            double L = PointA.l;
            double x, y;
            double L0;
            double l1;
            double p = 206264.80625;
            double b = B / p;
            double N;


            //N = (int)(L / (3 * 3600) + 0.5);
            //L0 =3 * N * 3600;
            //l1 = (L - L0) / p;

            N = (int)(L / (6 * 3600) + 1);
            L0 = (6 * N - 3) * 3600;
            l1 = (L - L0) / p;

            double c = Math.Pow(Math.Cos(b), 2);
            double c1 = Math.Sin(b) * Math.Cos(b);
            double c2 = Math.Cos(b);
            double l2 = Math.Pow(l1, 2);
            double n = 6399698.902 - (21562.267 - (108.973 - 0.612 * c) * c) * c;
            double a0 = 32140.404 - (135.3302 - (0.7092 - 0.0040 * c) * c) * c;
            double a4 = (0.25 + 0.00252 * c) * c - 0.04166;
            double a6 = (0.166 * c - 0.084) * c;
            double a3 = (0.3333333 + 0.001123 * c) * c - 0.1666667;
            double a5 = 0.0083 - (0.1667 - (0.1968 + 0.0040 * c) * c) * c;


            x = 6367558.4969 * b - (a0 - (0.5 + (a4 + a6 * l2) * l2) * l2 * n) * c1;
            y = (1 + (a3 + a5 * l2) * l2) * l1 * n * c2;

            double y1 = y + 500000.0;
            double abc = new double();
            for (int i = 1; y1 / i > 1; i = i * 10)
            {
                abc = (N * i * 10 + y1);
            }
            return new double[] { x, abc };
        }
        #endregion
    }
}
View Code

 两个平面坐标之间的转换

/*---------------------------------------------------------
 *   // Copyright (C) 2011 东北大学
   // 版权所有。
   //
   // 文件名:平面坐标转换参数计算
   // 文件功能描述:返回两个平面直角坐标变换之间的参数
   //
   // 创建标识:潘腾 2013.09.12
   //
   // 修改标识:
   // 修改描述:
 *    ------------------------------------------------------------*/
using System.Collections.Generic;

namespace OMCC.Calculate
{
    /*----------------------------------------------------
     * 输入:三个点A B C在两个坐标系中的坐标
     * 输出:两个坐标系的转换参数
     *------------------------------------------------*/
    class XY2XY
    {
        #region  类属性

        private APoint pointA;
        /// <summary>
        /// 第一个点
        /// </summary>
        public APoint PointA
        {
            get { return pointA; }
            set { pointA = value; }
        }

        private APoint pointB;
        /// <summary>
        /// 第二个点
        /// </summary>
        public APoint PointB
        {
            get { return pointB; }
            set { pointB = value; }
        }
        /// <summary>
        /// 第三个点
        /// </summary>
        private APoint pointC;

        public APoint PointC
        {
            get { return pointC; }
            set { pointC = value; }
        }

        #endregion

        #region 返回两个平面坐标转换参数
        public List<double> GetXY2XY()
        {
            double ratioa3 = (((pointB.x1) - (pointA.x1)) * ((pointC.x2) - (pointA.x2)) - ((pointB.x2) 
                - (pointA.x2)) * ((pointC.x1) - (pointA.x1))) /(((pointC.y1) - (pointA.y1)) * ((pointB.x1)
                - (pointA.x1)) - ((pointC.x1) - (pointA.x1)) * ((pointB.y1) - (pointA.y1)));
            double ratioa2 = ((pointC.x2) - (pointA.x2) - ratioa3 * ((pointC.y1) - (pointA.y1))) / ((pointC.x1) - (pointA.x1));
            double ratioa1 = (pointA.x2) - ratioa2 * (pointA.x1) - ratioa3 * (pointA.y1);
            double ratiob3 = (((pointB.x1) - (pointA.x1)) * ((pointC.y2) - (pointA.y2)) - ((pointB.y2) - (pointA.y2)) * 
                ((pointC.x1) - (pointA.x1))) /(((pointC.y1) - (pointA.y1)) * ((pointB.x1) - (pointA.x1))
                - ((pointC.x1) - (pointA.x1)) * ((pointB.y1) - (pointA.y1)));
            double ratiob2 = ((pointC.y2) - (pointA.y2) - ratiob3 * ((pointC.y1) - (pointA.y1))) / ((pointC.x1) - (pointA.x1));
            double ratiob1 = (pointA.y2) - ratiob2 * (pointA.x1) - ratiob3 * (pointA.y1);
            List<double> result = new List<double>();
            result.Add(ratioa1);
            result.Add(ratioa2);
            result.Add(ratioa3);
            result.Add(ratiob1);
            result.Add(ratiob2);
            result.Add(ratiob3);
            return result;
        }
        #endregion
    }
}
View Code

OK了,就写到这儿吧,时间过太久了,也不想在花太多时间去回顾了。写的也许不够详细………………

posted @ 2014-09-02 08:53  沙中世界  阅读(1111)  评论(0)    收藏  举报