c#坐标系互相转换

转自群友的博客:https://www.xiaofengyu.com/?p=108

群友的github地址:https://github.com/jfwangncs/GPSConvert

 各种坐标系的各种转换

复制代码
 public class TempGps
    {

        public double Tlng;
        public double Tlat;
    }

    public class GPS
    {
        public string oLng;//经度 度分秒坐标
        public string oLat;//纬度 度分秒坐标

        public double lng;//经度 WGS-84
        public double lat;//纬度 WGS-84

        public double gLng;//经度 GCJ-02 中国坐标偏移标准 Google Map、高德、腾讯使用
        public double gLat;//纬度 GCJ-02 中国坐标偏移标准 Google Map、高德、腾讯使用

        public double bLng;//经度 BD-09 百度坐标偏移标准,Baidu Map使用
        public double bLat;//纬度 BD-09 百度坐标偏移标准,Baidu Map使用


        public double PI = Math.PI;
        double xPI = Math.PI * 3000.0 / 180.0;

        public TempGps delta(TempGps t)
        {
            var a = 6378245.0; //  a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
            var ee = 0.00669342162296594323; //  ee: 椭球的偏心率。
            var dLat = this.transformLat(t.Tlng - 105.0, t.Tlat - 35.0);
            var dLng = this.transformLng(t.Tlng - 105.0, t.Tlat - 35.0);
            var radLat = t.Tlat / 180.0 * PI;
            var magic = Math.Sin(radLat);
            magic = 1 - ee * magic * magic;
            var sqrtMagic = Math.Sqrt(magic);
            return new TempGps() { Tlat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI),  Tlng= (dLng * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * PI) };
        }
        //WGS-84 to GCJ-02
        public void gcj_encrypt()
        {
            if (this.outOfChina(lng, lat))
            {
                gLng = lng;
                gLat = lat;
            }
            var t = this.delta(new TempGps() { Tlng = lng, Tlat = lat });
            gLng = t.Tlng+lng;
            gLat = t.Tlat+lat;
        }

        //GCJ-02 to WGS-84
        public void gcj_decrypt()
        {


            if (this.outOfChina(gLng, gLat))
            {
                lng = gLng;
                lat = gLat;

            }
            var t = this.delta(new TempGps() { Tlng = gLng, Tlat = gLat });
            lng = gLng-t.Tlng;
            lat = gLat-t.Tlat;
        }

        //GCJ-02 to BD-09
        public void bd_encrypt()
        {
            double x = gLng;
            double y = gLat;
            double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * xPI);
            double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * xPI);
            bLng = z * Math.Cos(theta) + 0.0065;
            bLat = z * Math.Sin(theta) + 0.006;
        }
        //BD-09 to GCJ-02
        public void bd_decrypt()
        {
            double x = bLng - 0.0065;
            double y = bLat - 0.006;
            double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * xPI);
            double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * xPI);
            gLng = z * Math.Cos(theta);
            gLat = z * Math.Sin(theta);
        }

        //WGS-84 to 度分秒坐标  
        public void wgs_decrypt()
        {
            oLng = TranDegreeToDMs(lng);
            oLat = TranDegreeToDMs(lat);
        }


        //度分秒坐标 to WGS-84
        public void wgs_encrypt()
        {
            lng = TranDMsToDegree(oLng);
            lat = TranDMsToDegree(oLat);
        }


        public double TranDMsToDegree(string _dms)
        {
            string[] dms = _dms.Split('.');
            if (dms.Length > 2)
                return double.Parse(dms[0]) + double.Parse(dms[1]) / 60 + double.Parse(dms[2] + "." + dms[3] ?? "0") / 3600;
            else
                return 0d;

        }


        private static string TranDegreeToDMs(double d)
        {
            int Degree = Convert.ToInt16(Math.Truncate(d));//度
            d = d - Degree;
            int M = Convert.ToInt16(Math.Truncate((d) * 60));//分
            int S = Convert.ToInt16(Math.Round((d * 60 - M) * 60));
            if (S == 60)
            {
                M = M + 1;
                S = 0;
            }
            if (M == 60)
            {
                M = 0;
                Degree = Degree + 1;
            }
            string rstr = Degree.ToString() + ".";
            if (M < 10)
                rstr = rstr + "0" + M.ToString();
            else
                rstr = rstr + M.ToString();
            if (S < 10)
                rstr = rstr + "0" + S.ToString();
            else
                rstr = rstr + S.ToString();
            return rstr;
        }

        private bool outOfChina(double _lng, double _lat)
        {
            if (lng < 72.004 || lng > 137.8347)
                return true;
            if (lat < 0.8293 || lat > 55.8271)
                return true;
            return false;
        }

        private double transformLat(double x, double y)
        {
            double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
            ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.Sin(y * PI) + 40.0 * Math.Sin(y / 3.0 * PI)) * 2.0 / 3.0;
            ret += (160.0 * Math.Sin(y / 12.0 * PI) + 320 * Math.Sin(y * PI / 30.0)) * 2.0 / 3.0;
            return ret;
        }

        private double transformLng(double x, double y)
        {
            double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
            ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
            ret += (20.0 * Math.Sin(x * PI) + 40.0 * Math.Sin(x / 3.0 * PI)) * 2.0 / 3.0;
            ret += (150.0 * Math.Sin(x / 12.0 * PI) + 300.0 * Math.Sin(x / 30.0 * PI)) * 2.0 / 3.0;
            return ret;
        }
    }
复制代码

调用

复制代码
  GPS t = new GPS();
                    t.oLng = dt.Rows[i][1].ToString();
                    t.oLat = dt.Rows[i][2].ToString();
                    t.wgs_encrypt();
                    t.gcj_encrypt();
                    t.bd_encrypt();
                    cells[i+1, 3].PutValue(t.bLng);
                    cells[i+1, 4].PutValue(t.bLat);

转载于:https://www.cnblogs.com/otsf/p/10161027.html

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,你可以使用数学库来实现大地坐标系和地固系坐标的互相转换。以下是一个示例代码,演示了如何使用C#实现这种转换: ```csharp using System; namespace CoordinateConversion { class Program { static void Main(string[] args) { // 大地坐标系参数 double a = 6378137; // 长半轴 double b = 6356752.3142; // 短半轴 double f = (a - b) / a; // 扁率 double e = Math.Sqrt(2 * f - Math.Pow(f, 2)); // 第一偏心率 double e2 = Math.Sqrt(Math.Pow(e, 2) / (1 - Math.Pow(e, 2))); // 第二偏心率 // 地心坐标系参数 double N; // 卯酉圈曲率半径 double X, Y, Z; // 地心坐标 // 大地坐标系转地心坐标系 double B = 40.0; // 纬度 double L = 116.0; // 经度 double H = 100.0; // 高程 double sinB = Math.Sin(B * Math.PI / 180); double cosB = Math.Cos(B * Math.PI / 180); double sinL = Math.Sin(L * Math.PI / 180); double cosL = Math.Cos(L * Math.PI / 180); N = a / Math.Sqrt(1 - Math.Pow(e * sinB, 2)); X = (N + H) * cosB * cosL; Y = (N + H) * cosB * sinL; Z = (N * (1 - Math.Pow(e, 2)) + H) * sinB; Console.WriteLine("地心坐标系:"); Console.WriteLine("X: " + X.ToString()); Console.WriteLine("Y: " + Y.ToString()); Console.WriteLine("Z: " + Z.ToString()); // 地心坐标系转大地坐标系 double B2, L2, H2; double p = Math.Sqrt(Math.Pow(X, 2) + Math.Pow(Y, 2)); double theta = Math.Atan(Z * a / (p * b)); B2 = Math.Atan((Z + Math.Pow(e2, 2) * b * Math.Pow(Math.Sin(theta), 3)) / (p - Math.Pow(e, 2) * a * Math.Pow(Math.Cos(theta), 3))); L2 = Math.Atan(Y / X); H2 = p / Math.Cos(B2) - a / Math.Sqrt(1 - Math.Pow(e * Math.Sin(B2), 2)); Console.WriteLine("大地坐标系:"); Console.WriteLine("纬度 B: " + (B2 * 180 / Math.PI).ToString()); Console.WriteLine("经度 L: " + (L2 * 180 / Math.PI).ToString()); Console.WriteLine("高程 H: " + H2.ToString()); Console.ReadLine(); } } } ``` 在这个示例代码中,我们首先定义了大地坐标系和地心坐标系的参数。然后,我们使用大地坐标系的纬度、经度和高程来计算地心坐标系的X、Y、Z坐标。接着,我们再通过地心坐标系的X、Y、Z坐标计算大地坐标系的纬度、经度和高程。 请注意,这个示例代码仅仅是提供了一个基本的转换方法,并没有考虑更复杂的情况,比如不同的大地基准、不同的坐标系转换方法等。在实际应用中,你可能需要根据具体需求进行更详细的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值