using System.Collections; namespace AutoDispathingWork.Utils { /* * 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 }; } /// /// 是否是国内地址 /// /// /// /// 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 }; } /// /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 /// 高德谷歌转为百度 /// /// /// /// 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; } /// /// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 /// 百度坐标转为高德谷歌坐标 /// /// /// /// 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; } public static Tuple BaiduToGaode(double bdLat, double bdLng) { double x = bdLng - 0.0065; double y = bdLat - 0.006; double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * Math.PI); double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * Math.PI); double ggLng = z * Math.Cos(theta); double ggLat = z * Math.Sin(theta); return Tuple.Create(ggLat, ggLng); } /// /// gps84转为bd09 /// GPS坐标转为百度坐标 /// /// /// /// public static double[] Gps84ToBd09(double lat, double lon) { double[] gcj02 = Gps84ToGcj02(lat, lon); double[] bd09 = Gcj02ToBd09(gcj02[0], gcj02[1]); return bd09; } /// /// 百度坐标转成GPS坐标 /// /// /// /// 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; } /// /// 保留小数点后六位 /// /// /// private static double Retain6(double num) { //String result = String.Format("%.6f", num); return Double.Parse(num.ToString("0.000000")); } /// /// 获取经度(lon) /// /// 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"); } /// /// 获取纬度(lat) /// /// 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"); } /// /// 获取经纬度度分秒 /// /// /// 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; } /// /// 经纬度转换 /// /// 经度 /// 保留8位值 /// 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"); } /// /// 度时分 转换成 WGS84 /// /// /// /// /// 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")); } /// /// 批量转换 /// /// 字符串数组["lng,lat","lng,lat"...] /// 地心坐标,WGS84,GCJ02,BD09 public static GpsUtilObject piliangzhuan(List arr, string typename) { //地心 var list_dx = new List(); //WGS84 var list_wgs84 = new List(); //GCJ02 var list_gcj02 = new List(); ///BD09 var list_bd09 = new List(); ///BD092 var list_bd092 = new List(); foreach (var ar in arr) { var item = ar.Split(',').ToList(); //地心 转 w84 Func dxTow84 = (value) => { var v = value.Split('.').ToList(); if (v.Count > 3) { return GpsUtil.TimeToValue(v[0], v[1], v[2] + "." + (v[3] ?? "0")); } else { return 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 = GpsUtil.Gps84ToGcj02(lat, lng); list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18")); var bd09 = 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(GpsUtil.GetLongitudeValue(lng) + "," + GpsUtil.GetLatitudeValue(lat)); var gcj02 = GpsUtil.Gps84ToGcj02(lat, lng); list_gcj02.Add(gcj02[1].ToString("g18") + "," + gcj02[0].ToString("g18")); var bd09 = 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 = GpsUtil.Gcj02ToGps84(lat, lng); list_wgs84.Add(wgs84[1].ToString("g18") + "," + wgs84[0].ToString("g18")); list_dx.Add(GpsUtil.GetLongitudeValue(wgs84[1]) + "," + GpsUtil.GetLatitudeValue(wgs84[0])); var bd09 = 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 = GpsUtil.Bd09ToGps84(lat, lng); list_wgs84.Add(wgs84[1].ToString("g18") + "," + wgs84[0].ToString("g18")); list_dx.Add(GpsUtil.GetLongitudeValue(wgs84[1]) + "," + GpsUtil.GetLatitudeValue(wgs84[0])); var gcj02 = 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 { /// /// 地心坐标 /// public string dx { get; set; } /// /// WGS84 /// public string wgs84 { get; set; } /// /// GCJ02 /// public string gcj02 { get; set; } /// /// BD09 /// public string bd09 { get; set; } } } }