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