-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathCoordtransform.cs
166 lines (148 loc) · 5.8 KB
/
Coordtransform.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System;
/// <summary>
/// 提供百度坐标系(bd-09)、火星坐标系(国测局坐标系、gcj02)、WGS84坐标系直接的坐标互转,也提供了解析百度地址的方法的c#版本
/// 参照:http://wandergis.com/coordTransform_py/
/// </summary>
public class Coordtransform
{
//定义一些常量
private const double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
private const double PI = 3.1415926535897932384626;// π
private const double a = 6378245.0;// 长半轴
private const double ee = 0.00669342162296594323;// 偏心率平方
/// <summary>
/// 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
/// 即 百度 转 谷歌、高德
/// </summary>
/// <param name="bd_lon"></param>
/// <param name="bd_lat"></param>
/// <returns></returns>
public static double[] Bd09togcj02(double bd_lon, double bd_lat)
{
double x = bd_lon - 0.0065;
double y = bd_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 gg_lng = z * Math.Cos(theta);
double gg_lat = z * Math.Sin(theta);
return new[] { gg_lng, gg_lat };
}
/// <summary>
/// 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
/// 即谷歌、高德 转 百度
/// </summary>
/// <param name="lng"></param>
/// <param name="lat"></param>
/// <returns></returns>
public static double[] Gcj02tobd09(double lng, double lat)
{
double z = Math.Sqrt(lng * lng + lat * lat) + 0.00002 * Math.Sin(lat * x_PI);
double theta = Math.Atan2(lat, lng) + 0.000003 * Math.Cos(lng * x_PI);
double bd_lng = z * Math.Cos(theta) + 0.0065;
double bd_lat = z * Math.Sin(theta) + 0.006;
return new[] { bd_lng, bd_lat };
}
/// <summary>
/// WGS84转GCj02
/// </summary>
/// <param name="lng"></param>
/// <param name="lat"></param>
/// <returns></returns>
public static double[] Wgs84togcj02(double lng, double lat)
{
if (Out_of_china(lng, lat))
{
return new[] { lng, lat };
}
else
{
double dlat = Transformlat(lng - 105.0, lat - 35.0);
double dlng = Transformlng(lng - 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) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * PI);
double mglat = lat + dlat;
double mglng = lng + dlng;
return new[] { mglng, mglat };
}
}
/// <summary>
/// GCJ02 转换为 WGS84
/// </summary>
/// <param name="lng"></param>
/// <param name="lat"></param>
/// <returns></returns>
public static double[] Gcj02towgs84(double lng, double lat)
{
if (Out_of_china(lng, lat))
{
return new[] { lng, lat };
}
else
{
double dlat = Transformlat(lng - 105.0, lat - 35.0);
double dlng = Transformlng(lng - 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) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * PI);
double mglat = lat + dlat;
double mglng = lng + dlng;
return new[] { lng * 2 - mglng, lat * 2 - mglat };
}
}
public static double Transformlat(double lng, double lat)
{
double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.Sqrt(Math.Abs(lng));
ret += (20.0 * Math.Sin(6.0 * lng * PI) + 20.0 * Math.Sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.Sin(lat * PI) + 40.0 * Math.Sin(lat / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * Math.Sin(lat / 12.0 * PI) + 320 * Math.Sin(lat * PI / 30.0)) * 2.0 / 3.0;
return ret;
}
public static double Transformlng(double lng, double lat)
{
double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.Sqrt(Math.Abs(lng));
ret += (20.0 * Math.Sin(6.0 * lng * PI) + 20.0 * Math.Sin(2.0 * lng * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.Sin(lng * PI) + 40.0 * Math.Sin(lng / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * Math.Sin(lng / 12.0 * PI) + 300.0 * Math.Sin(lng / 30.0 * PI)) * 2.0 / 3.0;
return ret;
}
/// <summary>
/// 判断是否在国内,不在国内则不做偏移
/// 纬度3.86~53.55,经度73.66~135.05
/// </summary>
/// <param name="lng"></param>
/// <param name="lat"></param>
/// <returns></returns>
public static bool Out_of_china(double lng, double lat)
{
return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); ;
}
/// <summary>
/// WGS84坐标系->百度坐标系
/// </summary>
/// <param name="lon"></param>
/// <param name="lat"></param>
/// <returns></returns>
public static double[] Wgs84tobd09(double lon, double lat)
{
var gcj02 = Wgs84togcj02(lon, lat);
return Gcj02tobd09(gcj02[0], gcj02[1]);
}
/// <summary>
/// 百度坐标系->WGS84坐标系
/// </summary>
/// <param name="bd_lon"></param>
/// <param name="bd_lat"></param>
/// <returns></returns>
public static double[] Bd09towgs84(double bd_lon, double bd_lat)
{
var gcj02 = Bd09togcj02(bd_lon, bd_lat);
return Gcj02towgs84(gcj02[0], gcj02[1]);
}
}