Coordinate transformation (c #)

Coordinate transformation  

Coordinate conversion, in short, say a coordinate change to the coordinates of another coordinate by a particular model; conversion, the need to use different conversion models, e.g. Bursa seven parameters of three-dimensional space, Morrow Hopkins model; the reference plane three dimensional space, four parameters, the polynomial fit peer model. In this paper, the main use Bursa seven-parameter model coordinate transformation.

Coordinate transformation

Bursa model (seven-parameter model)

For details see Wikipedia:  https://baike.baidu.com/item/%E4%B8%83%E5%8F%82%E6%95%B0

Program realization

1. The write data conversion classes

The various formats of minutes and seconds is calculated as expressed in radians converted, and finally a method to minutes and seconds of arc into ligatures format.

the System the using; 
the using the System.Collections.Generic; 
the using the System.Linq; 
the using the System.Text; 
the using System.Threading.Tasks; 
the using the System.Text.RegularExpressions; 
namespace CoordTF 
{ 
    class DataCnversion 
    { 
        #region 
        /// <Summary> 
        // / data formatting, into the whole of minutes and seconds (X.XXXX) ligatures format 
        /// </ Summary> 
        /// <param name = "oldCoord"> geodetic </ param> 
        /// <param name = " dataFormat "> data format </ param> 
        /// <Returns> </ Returns> 
        public Double DataFormatting (oldCoord String, String the dataFormat) 
        { 
            Double newCoord = 0.00;
            switching (data format)
            { 
        #region form respective degrees to radians
                case "度°分'秒″":
                    newCoord = DMSA_RAD(oldCoord);
                    break;
                case "度:分:秒":
                    newCoord = DMSB_RAD(oldCoord);
                    break;
                case "度:分":

                    break;
                case "度":
                    newCoord = D_RAD(oldCoord); 
                    break;
                case "度分秒连写":
                    newCoord = DMSLX_RAD(oldCoord);
                    break;
            }
            return newCoord;
        }
        #endregion
        double d, m, s;// degrees minutes and seconds
        /// <summary>
        /// 度°分'秒"格式转弧度
        /// </summary>
        /// <param name="dms">格式为XX ° XX ' XX.XX " </param>
        /// <returns></returns>
        public double DMSA_RAD(string dms)
        {
            double rad;
            var newD = dms.Substring(0, dms.IndexOf("°"));
            var newM = dms.Substring(dms.IndexOf("°")+1,dms.IndexOf("′")-3);
            var newS = dms.Substring(dms.IndexOf("′")+1,dms.Length-dms.IndexOf("′")-2);
            rad = (double.Parse(newD) + double.Parse(newM)/ 60 + double.Parse(newS) / 3600) * 
            Math.PI / 180;
            return rad;
        }
        /// <Summary> 
        /// degrees: minutes: seconds format radians 
        /// </ Summary> 
        /// <param name = "DMS"> format degrees: minutes: seconds </ param> 
        /// < Returns> </ Returns> 
        public Double DMSB_RAD (String DMS) 
        { 
            Double RAD; 
            String [] = newDms dms.Split ( ':'); 
            RAD = (double.Parse (newDms [0] .ToString ()) + Double. the Parse (newDms [. 1] .ToString ()) / 60 + 
            double.Parse (newDms [2] .ToString ()) / 3600) * Math.PI / 180 [; 
            return RAD; 
        } 
        /// <Summary> 
        /// minutes and seconds of the ligatures (X.XXXX) radians 
        /// </ Summary> 
        /// <param name = "DMS"> format x.xxxx</param>
        /// <Returns> </ Returns> 
        /// <Returns> </returns>
        public double DMSLX_RAD(string dms)
        {
            RAD Double; 
            var = newDms double.Parse (DMS); 
            D = Math.Floor (newDms); // degrees 
            var X = (newDms - D) * 100; 
            X = double.Parse (x.ToString ( "N8") ); 
            m = Math.Floor (X); // points 
            S = (X - m) * 100; 
            m / = 60; // second 
            S / = 3600; 
            RAD = (m + D + S) / 180 [* ( Math.PI); // radians 
            return RAD; 
        } 
        /// <Summary> 
        /// xx.xxxx format [deg.] radians 
        /// </ Summary> 
        /// <param name = "DMS"> angle, the format [deg.] xx.xxxx </ param> 
        { 
            Double RAD;
        Double D_RAD public (String DMS) 
            RAD = (double.Parse (DMS) * Math.PI / 180 [); 
            return RAD; 
        } 
        #endregion 
        /// <Summary> 
        /// radian rotation angle (result xx.xxxxxx format ligatures ) 
        /// </ Summary> 
        /// <param name = "RAD"> radians </ param> 
        /// <Returns> </ Returns> 
        public Double RAD_DMS (String RAD) 
        { 
            Double DMS; 
            var = Double newRad .Parse (RAD); 
            var newRad D = / * 180 [Math.PI; // degrees 
            var Dstr = d.ToString ( "N8"); 
            D = double.Parse (Dstr); 
            var X = Math.Floor (D) ; 
            var m = (D - X) * 60; // minutes 
            var mStr = m.ToString ( "N8");
            m = double.Parse(mStr);
            var f = Math.Floor(m);
            var s = (m - f) * 60;   //秒
            var sStr = s.ToString("N8");
            s = double.Parse(sStr);
            dms = x + f / 100 + s / 10000;
            return dms;
        }
    }
}

2. Write the coordinate conversion classes

          Comprising the earth space conversion, Gaussian Soid, change with the same coordinate system of calculation, the conversion parameter computing Bursa seven.

If there want to learn programming beginners, you can come to our C / C ++ technology learning Oh buckles qun: front 58,93 followed 4,83-89 free to send the entire system inside the C / C ++ tutorials!

the System the using; 
the using the System.Collections.Generic; 
the using the System.Linq; 
the using the System.Text; 
the using System.Threading.Tasks; 
the using the System.Windows.Forms; 
the using MathNet.Numerics.LinearAlgebra.Double; 
namespace CoordTF 
{ 
    class CoordTransform 
    { 
        / // <Summary> 
        /// world coordinate space at a right angle turn 
        /// </ Summary> 
        /// <param name = "B"> latitude </ param> 
        /// <param name = "L"> longitude </ param> 
        /// <name = "H"> highly </ param> param 
        /// <param name = "A"> semimajor axis of the ellipsoid </ param> 
        /// <param name = "FL"> flat the reciprocal </ param>
        /// <returns></returns>
        public double[] BLH_XYZ(double B, double L, double H, double a, double fl,string 
        dataFormat)
        {
            var f = 1 / fl;
            var e2 = 2 * f - f * f;
            DataCnversion dataCnversion = new DataCnversion();
            B = dataCnversion.DataFormatting(B.ToString(), dataFormat);
            L = dataCnversion.DataFormatting(L.ToString(), dataFormat);
            var W = Math.Sqrt(1 - e2 * (Math.Sin(B) * Math.Sin(B)));
            var N = a / W;
            var X = (N + H) * Math.Cos(B) * Math.Cos(L);
            var Y = (N + H) * Math.Cos(B) * Math.Sin(L);
            var Z = (N * (1 - e2) + H) * Math.Sin(B);
            Double [] = new new Double the XYZ [. 3]; 
            the XYZ [0] = X-; 
            the XYZ [. 1] = the Y; 
            the XYZ [2] = the Z; 
            return the XYZ; 
        } 
        /// <Summary> 
        /// quarter turns geodetic coordinate space 
        /// </ Summary> 
        /// <param name = "X-"> space X-</ param> 
        /// <param name = "the Y"> space the Y </ param> 
        /// <param name = "the Z "> space the Z </ param> 
        /// <param name =" A "> semimajor axis of the ellipsoid </ param> 
        /// <param name =" FL "> flat reciprocal of </ param> 
        /// < Returns> </ Returns> 
        public Double [] XYZ_BLH (X-Double, Double the Y, the Z Double, Double A,double fl)
        {
            var f = 1 / fl;
            var e2 = 2 * f - f * f;
                0) L = -L; 
            var = Rho 206264.806247096363;
            var Error = 0.00001;
            var B1 = Math.Atan(Z / S);
            double B2;
            while (true)
            {
                var W1 = Math.Sqrt(1 - e2 * (Math.Sin(B1) * Math.Sin(B1)));
                var N1 = a / W1;
                B2 = Math.Atan((Z + N1 * e2 * Math.Sin(B1)) / S);
                if (Math.Abs(B2 - B1) * Rho <= Error)
                    break;
                B1 = B2;
            }
            var B = B2;
            var W = Math.Sqrt(1 - e2 * (Math.Sin(B) * Math.Sin(B)));
            var N = a / W;
            var H = S / Math.Cos(B) - N;
            = New new DataCnversion dataCnversion DataCnversion ();
        /// <param name = "dy" > translation parameter y </ param>
            DataCnversion.RAD_DMS = B (B.ToString ( "N8")); 
            L = dataCnversion.RAD_DMS (L.ToString ( "N8")); 
            Double [] = new new Double BLH [. 3]; 
            BLH [0] = B; 
            BLH [. 1] = L; 
            BLH [2] = H; 
            return BLH; 
        } 
        /// <Summary> 
        /// conversion Bursa seven parameters 
        /// </ Summary> 
        /// <param name = "X-"> space Rectangular X-</ param> 
        /// <param name = "the Y"> space Rectangular the Y </ param> 
        /// <param name = "the Z"> space Rectangular the Z </ param> 
        /// <param name = "dx"> translation parameters X </ param>
        /// <param name = "rpx" > rotation parameter x </ param>
            var newX = X-+ DX - A15 * RPY + A16 * RPz + A17 * K;
            var newY = the Y + Dy + A24 * RPX - A26 * RPz + the A27 * K; 
            var the new Z-= the Z + DZ - A34 * RPX + in A35 * RPY + A37 * K; 
            Double [] Result = {newX, newY, the new Z-} ; 

            return Result; 
        } 
        /// <Summary> 
        /// Gauss operator 
        /// </ Summary> 
        /// <param name = "B"> geodetic latitude </ param> 
        /// <param name = "L "> geodetic longitude </ param> 
        /// <param name =" the L0 "> central meridian of longitude (degrees ° minutes' seconds" format) </ param> 
        /// <param name = "A"> ellipsoid major radius </ param> 
        /// <param name = "F1"> flat reciprocal of </ param> 
        /// <param name = "XCON"> X parameters normally </ param>
        /// <param name="yCon">y常参</param>
        /// <returns></returns>
        public double[] BL_xy(double B, double L, double L0, double a, double f1, double xCon, 
        double yCon)
        {
            DataCnversion dataCnversion = new DataCnversion();
            var f = 1 / f1;
            var e2 = 2 * f - f * f;
            var e12 = e2 / (1 - e2);
            B = dataCnversion.DMSLX_RAD(B.ToString("N8"));
            L = dataCnversion.DMSLX_RAD(L.ToString("N8"));
            L0 = dataCnversion.DMSLX_RAD(L0.ToString("N8"));
            var l = L - L0;
            var A0 = 1 + 3 * e2 / 4 + 45 * Math.Pow(e2, 2) / 64 + 350 * Math.Pow(e2, 3) / 512 + 
            11025 * Math.Pow(e2, 4) / 16384;
            var A2 = -(3 * e2 / 4 + 60 * Math.Pow(e2, 2) / 64 + 525 * Math.Pow(e2, 3) / 512 + 17640 
            * Math.Pow (E2, 4) / 16384) / 2; 
            var = A4 (15 * Math.Pow (E2, 2) / 64 + 210 * Math.Pow (E2, 3) / 512 + 8820 * Math.Pow (E2, 
            4) / 16384) / 4; 
            var A6 = - (35 * Math.Pow (E2, 3) / 512 + 2520 * Math.Pow (E2, 4) / 16384) / 6; 
            var A8 = (315 * Math.Pow (E2, 4) / 16384) / 8; 
            var X = a * (1 - E2) * (A0 + A2 * B * Math.Sin (2 * B) + A4 Math.Sin * (4 * B) + A6 * 
            Math.Sin (6 * B) + A8 Math.Sin * (8 * B)); 
            var m0 = l * Math.Cos (B); 
            var t = Math.Tan(B);
            var n2 = e12 * Math.Pow (Math.Cos (B), 2); 
            var Math.Sqrt W = (1 - * E2 Math.Pow (Math.Sin (B), 2)); 
            var N = a / W; 
            var NT = N * t;
            double x = X + (Nt * Math.Pow(m0, 2) / 2) + (Nt * (5 - Math.Pow(t, 2) + (9 * n2) + (4 * 
            Math.Pow(n2, 2))) * Math.Pow(m0, 4) / 24) + (Nt * (61 - (58 * Math.Pow(t, 2)) + 
            Math.Pow(t, 4) + (270 * n2) - (330 * n2 * Math.Pow(t, 2))) * Math.Pow(m0, 6) / 720);
            double y = (N * m0) + (N * (1 - Math.Pow(t, 2) + n2) * Math.Pow(m0, 3) / 6) + (N * (5 - 
            (18 * Math.Pow(t, 2)) + Math.Pow(t, 4) + (14 * n2) - (58 * n2 * Math.Pow(t, 2))) * 
            Math.Pow(m0, 5) / 120);
            x += xCon;
            y += yCon;
            Double [] = new new Double Point [2]; 
            Point [0] = X; 
            Point [. 1] = Y;
        {
            return point;
        }
        /// <Summary> 
        /// Inverse Gaussian 
        /// </ Summary> 
        /// <param name = "X"> plane coordinates X </ param> 
        /// <param name = "Y"> plane coordinates Y </ param> 
        /// <param name = "the L0"> central meridian of longitude </ param> 
        /// <param name = "A"> semimajor axis of the ellipsoid </ param> 
        /// <param name = "f1"> flat reciprocal of </ param> 
        /// <param name = "XCON"> constant parameters X </ param> 
        /// <param name = "yCon"> Y constant parameters </ param> 
        /// <Returns> </ Returns> 
        public Double [] Xy_BL (Double X, Y Double, Double the L0, Double A, Double F1, Double XCON,
        double yCon)
            var k = 1000000;
            x -= xCon;
            if (Math.Abs(y) >= k)
            {
                var zoneNumber = Math.Floor(y / k);
                y -= zoneNumber;
            }
            y -= yCon;
            var f = 1 / f1;
            var e2 = 2 * f - f * f;
            var e12 = e2 / (1 - e2);
            DataCnversion dataCnversion = new DataCnversion();
            L0 = dataCnversion.DMSLX_RAD(L0.ToString("N8"));
            var A0 = 1 + 3 * e2 / 4 + 45 * Math.Pow(e2, 2) / 64 + 350 * Math.Pow(e2, 3) / 512 + 
            11025 * Math.Pow(e2, 4) / 16384;
            var B0 = x / (a * (1 - e2) * A0);
            var K0 = (3 * e2 / 4 + 45 * Math.Pow(e2, 2) / 64 + 350 * Math.Pow(e2, 3) / 512 + 11025 
            * Math.pow (e2, 4) / 16384) / 2; 
            was K2 = - (63 * Math.pow (E2, 2) / 64 + 1108 * Math.pow (e2, 3) / 512 + 58239 *
            was Wf = Math.sqrt (1 - e2 (Math.pow (Math.Sin (Bf), 2)));
            Math.pow (e2, 4) / 16384) / 3; 
            was K4 = (604 * Math.pow (e2, 3) / 512 + 68 484 * Math.pow (e2, 4) / 16384) / 3; 
            was R6 = - (26328 * Math.pow (e2, 4) / 16384) / 3; 
            was SB0 = Math.pow (Math.Sin (B0), 2); 
            was Bf = B0 + Math.Sin (2 * B0) * (K0 + SB0 * (K2 + SB0 (K4 + K6 * SB0))); 
            was nf2 = e12 * Math.pow (Math.Cos (Bf), 2); 
            was tf = Math.Tan (Bf); 
            was tf2 = tf * tf; 
            was TF4 = Math.pow (TF, 4); 
            was Nf = a / Wf; 
            was YNF = y / Nf; 
            was VF2 = 1 + nf2; 
            was B = Bf - 0.5 * VF2 * tf (Math.pow (YNF, 2) - (5 + 3 * tf2 + NF2 - 9 * nf2 * tf2) *
            Math.pow (Note 4) / 12 + (61 + 90 * 45 * + tf2 TF4) * Math.pow (Note 6) / 360); 
            var l = (INS - (1 + 2 + tf2 * m -2) * Math.pow (Note 3) / 6 + (5 + 28 * + 24 * tf2 TF4 + 
            6 + 8 * m -2 * m -2 * tf2) * Math .Pow (Note 5) / 120) / Math.cos (Bf); 
            var L = L0 + l; 
            B = dataCnversion.RAD_DMS (B.ToString ( "N8")); 
            L = dataCnversion.RAD_DMS (L.ToString ( "N8")); 
            double [] point = new double [2]; 
            point [0] = B; 
            point [1] = L; 
            return point; 
        } 
        /// <summary>  
        ///同一坐标系下坐标换带
        /// </ summary> 
        /// <param name = "x"> </ param>
        /// <param name="l1">换带前经度</param>
        /// <param name="l2">换带后经度</param>
        /// <param name="a"></param>
        /// <param name="f1"></param>
        /// <param name="xCon"></param>
        /// <param name="yCon"></param>
        /// <returns></returns>
        public double[] CoordChangeBelt(double x, double y, double l1, double l2, double a, double 
        f1, double xCon, double yCon)
        {
            double[] xy2BL = Xy_BL(x, y, l1, a, f1, xCon, yCon);
            var B = xy2BL[0];
            var L = xy2BL[1];
            double[] BL2xy = BL_xy(B, L, l2, a, f1, xCon, yCon);
            return BL2xy;
        }
    }
}

This, all the base class to complete the conversion, based on the use of coordinate transformation, in turn call the methods in the class.

Guess you like

Origin blog.csdn.net/Abelia/article/details/93352961