GPS、谷歌、百度、高德坐标相互转换

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json;

namespace SandManagement.Models
{
    /*
     * WGS84坐标系    地球坐标系,国际通用坐标系
     * GCJ02坐标系    火星坐标系,WGS84坐标系加密后的坐标系;Google国内地图、高德、QQ地图 使用
     * BD09坐标系    百度坐标系,GCJ02坐标系加密后的坐标系
     * */
    public class GpsUtil
    {
        public static double pi = 3.1415926535897932384626;
        public static double x_pi = 3.1415926535897932384626;// * 3000.0 / 180.0;   //转换BD09时偏移
        //public static double cbz = 6378137.0;   //长半轴
        public static double cbz = 6378245.0;   //长半轴
        public static double ee = 0.00669342162296594323;


        public static 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;
        }

        public static double TransformLon(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;
        }

        public static double[] transform(double lat, double lon)
        {
            if (OutOfChina(lat, lon))
            {
                return new double[] { lat, lon };
            }
            double dLat = TransformLat(lon - 105.0, lat - 35.0);
            double dLon = TransformLon(lon - 105.0, lat - 35.0);
            double radLat = lat / 180.0 * pi;
            double magic = Math.Sin(radLat);
            magic = 1 - ee * magic * magic;
            double SqrtMagic = Math.Sqrt(magic);
            dLat = (dLat * 180.0) / ((cbz * (1 - ee)) / (magic * SqrtMagic) * pi);
            dLon = (dLon * 180.0) / (cbz / SqrtMagic * Math.Cos(radLat) * pi);
            double mgLat = lat + dLat;
            double mgLon = lon + dLon;
            return new double[] { mgLat, mgLon };
        }
        /// <summary>
        /// 是否是国内地址
        /// </summary>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        /// <returns></returns>
        public static bool OutOfChina(double lat, double lon)
        {
            if (lon < 72.004 || lon > 137.8347)
                return true;
            if (lat < 0.8293 || lat > 55.8271)
                return true;
            return false;
        }

        /** 
            * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System 
            * 
            * @param lat 
            * @param lon 
            * @return 
            */
        public static double[] Gps84ToGcj02(double lat, double lon)
        {
            if (OutOfChina(lat, lon))
            {
                return new double[] { lat, lon };
            }
            double dLat = TransformLat(lon - 105.0, lat - 35.0);
            double dLon = TransformLon(lon - 105.0, lat - 35.0);
            double radLat = lat / 180.0 * pi;
            double magic = Math.Sin(radLat);
            magic = 1 - ee * magic * magic;
            double SqrtMagic = Math.Sqrt(magic);
            dLat = (dLat * 180.0) / ((cbz * (1 - ee)) / (magic * SqrtMagic) * pi);
            dLon = (dLon * 180.0) / (cbz / SqrtMagic * Math.Cos(radLat) * pi);
            double mgLat = lat + dLat;
            double mgLon = lon + dLon;
            return new double[] { mgLat, mgLon };
        }

        /** 
            * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return 
            * */
        public static double[] Gcj02ToGps84(double lat, double lon)
        {
            double[] gps = transform(lat, lon);
            double lontitude = lon * 2 - gps[1];
            double latitude = lat * 2 - gps[0];
            return new double[] { latitude, lontitude };
        }
        /// <summary>
        /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 
        /// 高德谷歌转为百度
        /// </summary>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        /// <returns></returns>
        public static double[] Gcj02ToBd09(double lat, double lon)
        {
            double x = lon, y = lat;
            double z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * x_pi);
            double theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * x_pi);
            double tempLon = z * Math.Cos(theta) + 0.0065;
            double tempLat = z * Math.Sin(theta) + 0.006;
            double[] gps = { tempLat, tempLon };
            return gps;
        }

        /// <summary>
        /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标
        /// 百度坐标转为高德谷歌坐标
        /// </summary>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        /// <returns></returns>
        public static double[] Bd09ToGcj02(double lat, double lon)
        {
            double x = lon - 0.0065, y = lat - 0.006;
            double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi);
            double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_pi);
            double tempLon = z * Math.Cos(theta);
            double tempLat = z * Math.Sin(theta);
            double[] gps = { tempLat, tempLon };
            return gps;
        }

        /// <summary>
        /// gps84转为bd09
        /// GPS坐标转为百度坐标
        /// </summary>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        /// <returns></returns>
        public static double[] Gps84ToBd09(double lat, double lon)
        {
            double[] gcj02 = Gps84ToGcj02(lat, lon);
            double[] bd09 = Gcj02ToBd09(gcj02[0], gcj02[1]);
            return bd09;
        }
        /// <summary>
        /// 百度坐标转成GPS坐标
        /// </summary>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        /// <returns></returns>
        public static double[] Bd09ToGps84(double lat, double lon)
        {
            double[] gcj02 = Bd09ToGcj02(lat, lon);
            double[] gps84 = Gcj02ToGps84(gcj02[0], gcj02[1]);
            //保留小数点后六位  
            gps84[0] = Retain6(gps84[0]);
            gps84[1] = Retain6(gps84[1]);
            return gps84;
        }

        /// <summary>
        /// 保留小数点后六位 
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        private static double Retain6(double num)
        {
            //String result = String.Format("%.6f", num);
            return Double.Parse(num.ToString("0.000000"));
        }

        /// <summary>  
        /// 获取经度(lon)
        /// </summary>  
        /// <returns></returns>  
        public static string GetLongitudeValue(double value)
        {
            ArrayList arrList = LgetValid(value);
            if (arrList == null)
                return string.Empty;
            if (arrList.Count != 3)
                return string.Empty;
            return string.Format("{0}.{1}.{2}", arrList[0], arrList[1], arrList[2], value > 0 ? "E" : "W");
        }
        /// <summary>  
        /// 获取纬度(lat)
        /// </summary>  
        /// <returns></returns>  
        public static string GetLatitudeValue(double value)
        {
            ArrayList arrList = LgetValid(value);
            if (arrList == null)
                return string.Empty;
            if (arrList.Count != 3)
                return string.Empty;
            return string.Format("{0}.{1}.{2}", arrList[0], arrList[1], arrList[2], value > 0 ? "N" : "S");
        }
        /// <summary>  
        /// 获取经纬度度分秒  
        /// </summary>  
        /// <param name="value"></param>  
        /// <returns></returns>  
        public static ArrayList LgetValid(double value)
        {
            ArrayList aList = new ArrayList();
            string excute = ChangeValue(value);
            string[] sArray = excute.Split('|');
            aList.Insert(0, sArray[0]);
            aList.Insert(1, sArray[1]);
            aList.Insert(2, sArray[2]);
            return aList;
        }
        /// <summary>  
        /// 经纬度转换  
        /// </summary>  
        /// <param name="str">经度</param>  
        /// <param name="num">保留8位值</param>  
        /// <returns></returns>  
        protected static string ChangeValue(double degree)
        {
            if (degree < 0)
            {
                degree = -degree;
            }
            double minute = (degree - (int)degree) * 60;
            double second = (minute - (int)minute) * 60;
            return ((int)degree).ToString() + "|" + ((int)minute).ToString() + "|" + second.ToString("0.000");
        }
        /// <summary>
        /// 度时分 转换成  WGS84
        /// </summary>
        /// <param name="Degrees"></param>
        /// <param name="Minutes"></param>
        /// <param name="Seconds"></param>
        /// <returns></returns>
        public static double TimeToValue(string Degrees, string Minutes, string Seconds)
        {
            double Value = double.Parse(Degrees) + double.Parse(Minutes) / 60 + double.Parse(Seconds) / 3600;
            return double.Parse(Value.ToString("0.000000"));
        }


        /// <summary>
        /// 批量转换
        /// </summary>
        /// <param name="arr">字符串数组["lng,lat","lng,lat"...]</param>
        /// <param name="type">地心坐标,WGS84,GCJ02,BD09</param>
        public static GpsUtilObject piliangzhuan(List<string> arr, string typename)
        {
            //地心
            var list_dx = new List<string>();
            //WGS84
            var list_wgs84 = new List<string>();
            //GCJ02
            var list_gcj02 = new List<string>();
            ///BD09
            var list_bd09 = new List<string>();
            ///BD092
            var list_bd092 = new List<string>();
            foreach (var ar in arr)
            {
                var item = ar.Split(',').ToList();
                //地心 转 w84
                Func<string, double> dxTow84 = (value) =>
                {
                    var v = value.Split('.').ToList();
                    if (v.Count > 3)
                    {
                        return Models.GpsUtil.TimeToValue(v[0], v[1], v[2] + "." + (v[3] ?? "0"));
                    }
                    else
                    {
                        return Models.GpsUtil.TimeToValue(v[0], v[1], v[2]);
                    }
                };
                switch (typename)
                {
                    case "地心坐标":
                        {
                            list_dx.Add(ar);
                            double lng = dxTow84(item[0]);
                            double lat = dxTow84(item[1]);
                            list_wgs84.Add(lng + "," + lat);
                            var gcj02 = Models.GpsUtil.Gps84ToGcj02(lat, lng);
                            list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18"));
                            var bd09 = Models.GpsUtil.Gps84ToBd09(lat, lng);
                            list_bd09.Add(bd09[1].ToString("g18") + "," + bd09[0].ToString("g18"));
                        }
                        break;
                    case "WGS84":
                        {
                            double lng = double.Parse(item[0]);
                            double lat = double.Parse(item[1]);
                            list_wgs84.Add(ar);
                            list_dx.Add(Models.GpsUtil.GetLongitudeValue(lng) + "," + Models.GpsUtil.GetLatitudeValue(lat));
                            var gcj02 = Models.GpsUtil.Gps84ToGcj02(lat, lng);
                            list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18"));
                            var bd09 = Models.GpsUtil.Gps84ToBd09(lat, lng);
                            list_bd09.Add(bd09[1].ToString("g18") + "," + bd09[0].ToString("g18"));
                        }
                        break;
                    case "GCJ02":
                        {
                            double lng = double.Parse(item[0]);
                            double lat = double.Parse(item[1]);
                            list_gcj02.Add(ar);
                            var wgs84 = Models.GpsUtil.Gcj02ToGps84(lat, lng);
                            list_wgs84.Add(wgs84[1].ToString("g18") + "," + wgs84[0].ToString("g18"));
                            list_dx.Add(Models.GpsUtil.GetLongitudeValue(wgs84[1]) + "," + Models.GpsUtil.GetLatitudeValue(wgs84[0]));
                            var bd09 = Models.GpsUtil.Gcj02ToBd09(lat, lng);
                            list_bd09.Add(bd09[1].ToString("g18") + "," + bd09[0].ToString("g18"));
                        }
                        break;
                    case "BD09":
                        {
                            double lng = double.Parse(item[0]);
                            double lat = double.Parse(item[1]);
                            list_bd09.Add(ar);
                            var wgs84 = Models.GpsUtil.Bd09ToGps84(lat, lng);
                            list_wgs84.Add(wgs84[1].ToString("g18") + "," + wgs84[0].ToString("g18"));
                            list_dx.Add(Models.GpsUtil.GetLongitudeValue(wgs84[1]) + "," + Models.GpsUtil.GetLatitudeValue(wgs84[0]));
                            var gcj02 = Models.GpsUtil.Bd09ToGcj02(lat, lng);
                            list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18"));
                        }
                        break;
                    default:
                        break;
                }

            }
            return new GpsUtilObject
            {
                dx = string.Join("|", list_dx),
                wgs84 = string.Join("|", list_wgs84),
                gcj02 = string.Join("|", list_gcj02),
                bd09 = string.Join("|", list_bd09)
            };
        }

        public class GpsUtilObject
        {
            /// <summary>
            /// 地心坐标
            /// </summary>
            public string dx { get; set; }
            /// <summary>
            /// WGS84
            /// </summary>
            public string wgs84 { get; set; }
            /// <summary>
            /// GCJ02
            /// </summary>
            public string gcj02 { get; set; }
            /// <summary>
            /// BD09
            /// </summary>
            public string bd09 { get; set; }
        }

    }
}

 

posted @ 2019-11-21 12:34  鞍山老菜鸟  阅读(854)  评论(0编辑  收藏  举报