欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C# 高斯正算 高斯反算 高斯换带等

程序员文章站 2022-07-15 22:58:16
...

首先,你要确定椭球参数:

a = 6378140;  //西安80椭球 IGA75
e2 = 0.006694384999588;
m0 = a * (1 - e2);
m2 = 3.0 / 2 * e2 * m0;
m4 = 5.0 / 4 * e2 * m2;
m6 = 7.0 / 6 * e2 * m4;
m8 = 9.0 / 8 * e2 * m6;
a0 = m0 + m2 / 2 + (3.0 / 8.0) * m4 + (5.0 / 16.0) * m6 + (35.0 / 128.0) * m8;
a2 = m2 / 2 + m4 / 2 + 15.0 / 32 * m6 + 7.0 / 16 * m8;
a4 = m4 / 8 + 3.0 / 16 * m6 + 7.0 / 32 * m8;
a6 = m6 / 32 + m8 / 16;
a8 = m8 / 128;
xx = 0;
yy = 0;
_x = 0;
_y = 0;
BB = 0;
LL = 0;

 下面才开始正题:

 高斯正算:把经纬度坐标转换为平面坐标

 

        void GaussPositive(double B, double L, double L0)
        {
            double X, t, N, h2, l, m, Bmiao, Lmiao;
            int Bdu, Bfen, Ldu, Lfen;
            Bdu = (int)B;
            Bfen = (int)(B * 100) % 100;
            Bmiao = (B - Bdu - Bfen * 0.01) * 10000.0;
            B = Bdu * PI / 180.0 + (Bfen / 60.0) * PI / 180.0 + Bmiao / 3600.0 * PI / 180.0;
            Ldu = (int)L;
            Lfen = (int)(L * 100) % 100;
            Lmiao = (L - Ldu - Lfen * 0.01) * 10000.0;
            L = Ldu * PI / 180.0 + (Lfen / 60.0) * PI / 180 + Lmiao / 3600.0 * PI / 180.0;
            l = L - L0 * PI / 180;
            X = a0 * B - Math.Sin(B) * Math.Cos(B) * ((a2 - a4 + a6) + (2 * a4 - 16.0 / 3.0 * a6) * Math.Sin(B) * Math.Sin(B) + 16.0 / 3.0 * a6 * Math.Pow(Math.Sin(B), 4)) + a8 / 8.0 * Math.Sin(8 * B);
            t = Math.Tan(B);
            h2 = e2 / (1 - e2) * Math.Cos(B) * Math.Cos(B);
            N = a / Math.Sqrt(1 - e2 * Math.Sin(B) * Math.Sin(B));
            m = Math.Cos(B) * l;
            xx = X + N * t * ((0.5 + (1.0 / 24.0 * (5 - t * t + 9 * h2 + 4 * h2 * h2) + 1.0 / 720.0 * (61 - 58 * t * t + Math.Pow(t, 4)) * m * m) * m * m) * m * m);
            yy = N * ((1 + (1.0 / 6.0 * (1 - t * t + h2) + 1.0 / 120.0 * (5 - 18 * t * t + Math.Pow(t, 4) + 14 * h2 - 58 * h2 * t * t) * m * m) * m * m) * m);
            yy = yy + 500000;
        }

    高斯反算:把平面坐标转换为经纬度坐标:

   

         void GaussNegative(double x, double y, double L0)
        {
            double Bf, Vf, l, tf, hf2, Nf, Bmiao, Lmiao;
            int Bdu, Bfen, Ldu, Lfen;
            y = y - 500000;
            Bf = hcfansuan(x);
            Vf = Math.Sqrt(1 + e2 / (1 - e2) * Math.Cos(Bf) * Math.Cos(Bf));
            tf = Math.Tan(Bf);
            hf2 = e2 / (1 - e2) * Math.Cos(Bf) * Math.Cos(Bf);
            Nf = a / Math.Sqrt(1 - e2 * Math.Sin(Bf) * Math.Sin(Bf));
            BB = (Bf - 0.5 * Vf * Vf * tf * (Math.Pow(y / Nf, 2) - 1.0 / 12 * (5 + 3 * tf * tf + hf2 - 9 * hf2 * tf * tf) * Math.Pow(y / Nf, 4) + 1.0 / 360 * (61 + 90 * tf * tf + 45 * tf * tf) * Math.Pow(y / Nf, 6))) * 180 / PI;
            Bdu = (int)BB;
            Bfen = (int)((BB - Bdu) * 60);
            Bmiao = ((BB - Bdu) * 60 - Bfen) * 60;
            BB = Bdu + 0.01 * Bfen + 0.0001 * Bmiao;
            l = 1.0 / Math.Cos(Bf) * (y / Nf - 1.0 / 6.0 * (1 + 2 * tf * tf + hf2) * Math.Pow(y / Nf, 3) + 1.0 / 120.0 * (5 + 28 * tf * tf + 24 * Math.Pow(tf, 4) + 6 * hf2 + 8 * hf2 * tf * tf) * Math.Pow(y / Nf, 5)) * 180.0 / PI;
            LL = L0 + l;
            Ldu = (int)LL;
            Lfen = (int)((LL - Ldu) * 60);
            Lmiao = ((LL - Ldu) * 60 - Lfen) * 60;
            LL = Ldu + 0.01 * Lfen + 0.0001 * Lmiao;
        }

   里面涉及到的弧长反算:

  

        double hcfansuan(double pX)
        {
            double Bf0 = pX / a0;
            double Bf1, Bf2;
            Bf1 = Bf0;
            Bf2 = (pX - F(Bf1)) / a0;
            while ((Bf2 - Bf1) > 1.0E-11)
            {
                Bf1 = Bf2;
                Bf2 = (pX - F(Bf1)) / a0;
            }
            return Bf1;
        }

    高斯换带就比较简单了:

   

        void GaussZone(double x, double y, double L0, double L0new)
        {
            GaussNegative(x, y, L0);
            GaussPositive(BB, LL, L0new);
        }