C#坐标系转换的源码

在一个项目中使用过的坐标系转换的类分享给大家,话不多说了看代码:

public class ToolMethods
{
/// <summary>
/// 生成客户端的验证码
/// </summary>
public static string GenerateWXChkCode()
{
string checkCode = String.Empty;
//验证码的字符集,去掉了一些容易混淆的字符
char[] character = { '0', '1', '2', '3', '4', '5', '6', '8', '9' };
Random rnd = new Random();
//生成验证码字符串
for (int i = 0; i < 4; i++)
{
checkCode += character[rnd.Next(character.Length)];
}
return checkCode;
}

#region 转换坐标
const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
const double pi = 3.14159265358979323;
const double a = 6378245.0;
const double ee = 0.00669342162296594323;
/// <summary>
/// 将WGS-84坐标转换为BD-09坐标时发生了异常
/// </summary>
/// <param name="coord">原WGS-84坐标</param>
/// <returns>目标BD-09坐标,如果转换失败返回原坐标</returns>
public static void ConverWGS84_To_BD09(double sLat, double sLng, ref double aLat, ref double aLng)
{
double x = sLng;
double y = sLat;
double bdx = x;
double bdy = y;
double g_x, g_y;
aLat = y;
aLng = x;
if (x != 0 && y != 0)
{
try
{
transform(y, x, out g_y, out g_x);
bd_encrypt(g_y, g_x, out bdy, out bdx);
aLat = bdy;
aLng = bdx;
}
catch (Exception ex)
{
//AppLogger.Instance.Log.Error("将WGS-84坐标转换为BD-09坐标时发生了异常!", ex);
throw ex;
}
}

}

public static void ConverBD09_WGS84(double sLat, double sLng, out double aLat, out double aLng)
{
//double mLat, mLng;
aLat = sLat;
aLng = sLng;
try
{
ConverBD09_To_GCJ02(sLat, sLng, out aLat, out aLng);
// ConverGCJ02_To_WGS84(mLat, mLng, out aLat, out aLng);
}
catch (Exception ex)
{
//AppLogger.Instance.Log.Error("ConverBD09_WGS84 has error", ex);
}
}

public static void ConverBD09_To_GCJ02(double bd_lat, double bd_lon, out double aLat, out double aLng)
{
var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
var x = bd_lon - 0.0065;
var y = bd_lat - 0.006;
var z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi);
var theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_pi);
aLng = z * Math.Cos(theta);
aLat = z * Math.Sin(theta);

}

public static void ConverGCJ02_To_WGS84(double lng, double lat, out double aLat, out double aLng)
{
if (outOfChina(lng, lat))
{
aLng = lng;
aLat = lat;
}
else
{
double dlat, dlng, mglat, mglng;
transform(lat - 35.0, lng - 105.0, out dlat, out dlng);

var radlat = lat / 180.0 * pi;
var magic = Math.Sin(radlat);
magic = 1 - ee * magic * magic;
var sqrtmagic = Math.Sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * pi);
mglat = lat + dlat;
mglng = lng + dlng;

aLat = lat * 2 - mglat;
aLng = lng * 2 - mglng;
}
}

/// <summary>
/// GCJ-02 坐标转换成 BD-09 坐标
/// </summary>
/// <param name="gg_lat"></param>
/// <param name="gg_lon"></param>
/// <param name="bd_lat"></param>
/// <param name="bd_lon"></param>
private static void bd_encrypt(double gg_lat, double gg_lon, out double bd_lat, out double bd_lon)
{
double x = gg_lon, y = gg_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);
bd_lon = z * Math.Cos(theta) + 0.0065;
bd_lat = z * Math.Sin(theta) + 0.006;
}

/// <summary>
/// WGS-84 到 GCJ-02 的转换 World Geodetic System ==> Mars Geodetic System
/// </summary>
/// <param name="wgLat"></param>
/// <param name="wgLon"></param>
/// <param name="mgLat"></param>
/// <param name="mgLon"></param>
private static void transform(double wgLat, double wgLon, out double mgLat, out double mgLon)
{
if (outOfChina(wgLat, wgLon))
{
mgLat = wgLat;
mgLon = wgLon;
return;
}
double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
double radLat = wgLat / 180.0 * pi;
double magic = Math.Sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.Sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi);
mgLat = wgLat + dLat;
mgLon = wgLon + dLon;
}
/// <summary>
/// 坐标是否处理中国范围内
/// </summary>
/// <param name="lat"></param>
/// <param name="lon"></param>
/// <returns></returns>
private 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;
}
/// <summary>
/// 加密纬度
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private 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;
}

/// <summary>
/// 加密经度
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private 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;
}

#endregion

}

posted @ 2020-09-09 17:36  海++龙  阅读(797)  评论(0)    收藏  举报