谷歌地图离线发布系列之偏移处理(三)纠偏算法
来源:互联网 发布:淘宝直通车开通要求 编辑:程序博客网 时间:2024/05/07 04:50
先上代码,用js实现的纠偏算法:
var pi = 3.14159265358979324;//// Krasovsky 1940//// a = 6378245.0, 1/f = 298.3// b = a * (1 - f)// ee = (a^2 - b^2) / a^2;var a = 6378245.0;var ee = 0.00669342162296594323;function outOfChina(lat, lon){ if (lon < 72.004 || lon > 137.8347) return 1; if (lat < 0.8293 || lat > 55.8271) return 1; return 0;}function transformLat(x,y){ var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(x > 0 ? x:-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;}function transformLon(x,y){ var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(x > 0 ? x:-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;}function transformFromWGSToGCJ(wgLoc){ var mgLoc ={}; mgLoc.lat = 0; mgLoc.lng = 0; if (outOfChina(wgLoc.lat, wgLoc.lng)) { mgLoc = wgLoc; return mgLoc; } var dLat = transformLat(wgLoc.lng - 105.0, wgLoc.lat - 35.0); var dLon = transformLon(wgLoc.lng - 105.0, wgLoc.lat - 35.0); var radLat = wgLoc.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); dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi); mgLoc.lat = wgLoc.lat + dLat; mgLoc.lng = wgLoc.lng + dLon; return mgLoc;}
参考文章1:http://blog.csdn.net/coolypf/article/details/8686588
WGS-84 到 GCJ-02 的转换(即 GPS 加偏)算法是一个普通青年轻易无法接触到的“公开”的秘密。这个算法的代码在互联网上是公开的,详情请使用 Google 搜索 "wgtochina_lb" 。
整理后的算法代码请参考 https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936 。知道了这个算法之后,就可以离线进行 Google 地图偏移校正,不必像之前那么麻烦。
至于 GCJ-02 到 WGS-84 的转换(即 GPS 纠偏),可以使用二分法。
参考文章2:http://www.zuidaima.com/code/file/1665077235663872.htm?dir=/correct_lat_lon/src/com/hgq/correct/MapFix.javapackage
com.hgq.correct;
003
004
005
/**
006
* 经纬度纠偏工具类
007
* [一句话功能简述]<p>
008
* [功能详细描述]<p>
009
* @author PeiYu
010
* @version 1.0, 2012-8-24
011
* @see
012
* @since gframe-v100
013
*/
014
public
class
MapFix
015
{
016
private
double
casm_f =
0.0
;
017
018
private
double
casm_rr =
0.0
;
019
020
private
double
casm_t1 =
0.0
;
021
022
private
double
casm_t2 =
0.0
;
023
024
private
double
casm_x1 =
0.0
;
025
026
private
double
casm_x2 =
0.0
;
027
028
private
double
casm_y1 =
0.0
;
029
030
private
double
casm_y2 =
0.0
;
031
032
private
MapFix()
033
{
034
casm_rr =
0.0
;
035
casm_t1 =
0.0
;
036
casm_t2 =
0.0
;
037
casm_x1 =
0.0
;
038
casm_y1 =
0.0
;
039
casm_x2 =
0.0
;
040
casm_y2 =
0.0
;
041
casm_f =
0.0
;
042
}
043
044
private
static
MapFix instance;
045
046
public
static
MapFix getInstance()
047
{
048
if
(instance ==
null
)
049
{
050
instance =
new
MapFix();
051
}
052
return
instance;
053
}
054
055
/**
056
* 纠偏
057
* @param x 经度
058
* @param y 纬度
059
* @return [0]纠偏后经度 [1]纠偏后纬度
060
*/
061
public
double
[] fix(
double
x ,
double
y)
062
{
063
double
[] res =
new
double
[
2
];
064
try
065
{
066
double
num = x *
3686400.0
;
067
double
num2 = y *
3686400.0
;
068
double
num3 =
0.0
;
069
double
num4 =
0.0
;
070
double
num5 =
0.0
;
071
MapPoint point = wgtochina_lb(
1
, (
int
) num, (
int
) num2, (
int
) num5, (
int
) num3, (
int
) num4);
072
double
num6 = point.getX();
073
double
num7 = point.getY();
074
num6 /=
3686400.0
;
075
num7 /=
3686400.0
;
076
res[
0
] = num6;
077
res[
1
] = num7;
078
}
079
catch
(Exception ex)
080
{
081
System.out.println(ex);
082
}
083
return
res;
084
}
085
086
private
void
IniCasm(
double
w_time ,
double
w_lng ,
double
w_lat)
087
{
088
casm_t1 = w_time;
089
casm_t2 = w_time;
090
double
num = (
int
) (w_time /
0.357
);
091
casm_rr = w_time - (num *
0.357
);
092
if
(w_time ==
0.0
)
093
{
094
casm_rr =
0.3
;
095
}
096
casm_x1 = w_lng;
097
casm_y1 = w_lat;
098
casm_x2 = w_lng;
099
casm_y2 = w_lat;
100
casm_f =
3.0
;
101
}
102
103
private
double
random_yj()
104
{
105
double
num =
314159269.0
;
106
double
num2 =
453806245.0
;
107
casm_rr = (num * casm_rr) + num2;
108
double
num3 = (
int
) (casm_rr /
2.0
);
109
casm_rr -= num3 *
2.0
;
110
casm_rr /=
2.0
;
111
return
casm_rr;
112
}
113
114
private
double
Transform_jy5(
double
x ,
double
xx)
115
{
116
double
num =
6378245.0
;
117
double
num2 =
0.00669342
;
118
double
num3 = Math.sqrt(
1.0
- ((num2 * yj_sin2(x *
0.0174532925199433
)) * yj_sin2(x *
0.0174532925199433
)));
119
return
((xx *
180.0
) / (((num / num3) * Math.cos(x *
0.0174532925199433
)) *
3.1415926
));
120
}
121
122
private
double
Transform_jyj5(
double
x ,
double
yy)
123
{
124
double
num =
6378245.0
;
125
double
num2 =
0.00669342
;
126
double
d =
1.0
- ((num2 * yj_sin2(x *
0.0174532925199433
)) * yj_sin2(x *
0.0174532925199433
));
127
double
num4 = (num * (
1.0
- num2)) / (d * Math.sqrt(d));
128
return
((yy *
180.0
) / (num4 *
3.1415926
));
129
}
130
131
private
double
Transform_yj5(
double
x ,
double
y)
132
{
133
double
num = ((((
300.0
+ (
1.0
* x)) + (
2.0
* y)) + ((
0.1
* x) * x)) + ((
0.1
* x) * y))
134
+ (
0.1
* Math.sqrt(Math.sqrt(x * x)));
135
num += ((
20.0
* yj_sin2(
18.849555921538762
* x)) + (
20.0
* yj_sin2(
6.283185307179588
* x))) *
0.6667
;
136
num += ((
20.0
* yj_sin2(
3.141592653589794
* x)) + (
40.0
* yj_sin2(
1.0471975511965981
* x))) *
0.6667
;
137
return
(num + (((
150.0
* yj_sin2(
0.26179938779914952
* x)) + (
300.0
* yj_sin2(
0.10471975511965979
* x))) *
0.6667
));
138
}
139
140
private
double
Transform_yjy5(
double
x ,
double
y)
141
{
142
double
num = ((((-
100.0
+ (
2.0
* x)) + (
3.0
* y)) + ((
0.2
* y) * y)) + ((
0.1
* x) * y))
143
+ (
0.2
* Math.sqrt(Math.sqrt(x * x)));
144
num += ((
20.0
* yj_sin2(
18.849555921538762
* x)) + (
20.0
* yj_sin2(
6.283185307179588
* x))) *
0.6667
;
145
num += ((
20.0
* yj_sin2(
3.141592653589794
* y)) + (
40.0
* yj_sin2(
1.0471975511965981
* y))) *
0.6667
;
146
return
(num + (((
160.0
* yj_sin2(
0.26179938779914952
* y)) + (
320.0
* yj_sin2(
0.10471975511965979
* y))) *
0.6667
));
147
}
148
149
private
MapPoint wgtochina_lb(
int
wg_flag ,
int
wg_lng ,
int
wg_lat ,
int
wg_heit ,
int
wg_week ,
int
wg_time)
150
{
151
MapPoint point =
null
;
152
if
(wg_heit <=
0x1388
)
153
{
154
double
num = wg_lng;
155
num /=
3686400.0
;
156
double
x = wg_lat;
157
x /=
3686400.0
;
158
if
(num <
72.004
)
159
{
160
return
point;
161
}
162
if
(num >
137.8347
)
163
{
164
return
point;
165
}
166
if
(x <
0.8293
)
167
{
168
return
point;
169
}
170
if
(x >
55.8271
)
171
{
172
return
point;
173
}
174
if
(wg_flag ==
0
)
175
{
176
IniCasm((
double
) wg_time, (
double
) wg_lng, (
double
) wg_lat);
177
point =
new
MapPoint();
178
point.setLatitude((
double
) wg_lng);
179
point.setLongitude((
double
) wg_lat);
180
return
point;
181
}
182
casm_t2 = wg_time;
183
double
num3 = (casm_t2 - casm_t1) /
1000.0
;
184
if
(num3 <=
0.0
)
185
{
186
casm_t1 = casm_t2;
187
casm_f++;
188
casm_x1 = casm_x2;
189
casm_f++;
190
casm_y1 = casm_y2;
191
casm_f++;
192
}
193
else
if
(num3 >
120.0
)
194
{
195
if
(casm_f ==
3.0
)
196
{
197
casm_f =
0.0
;
198
casm_x2 = wg_lng;
199
casm_y2 = wg_lat;
200
double
num4 = casm_x2 - casm_x1;
201
double
num5 = casm_y2 - casm_y1;
202
double
num6 = Math.sqrt((num4 * num4) + (num5 * num5)) / num3;
203
if
(num6 >
3185.0
)
204
{
205
return
point;
206
}
207
}
208
casm_t1 = casm_t2;
209
casm_f++;
210
casm_x1 = casm_x2;
211
casm_f++;
212
casm_y1 = casm_y2;
213
casm_f++;
214
}
215
double
xx = Transform_yj5(num -
105.0
, x -
35.0
);
216
double
yy = Transform_yjy5(num -
105.0
, x -
35.0
);
217
double
num9 = wg_heit;
218
xx = ((xx + (num9 *
0.001
)) + yj_sin2(wg_time *
0.0174532925199433
)) + random_yj();
219
yy = ((yy + (num9 *
0.001
)) + yj_sin2(wg_time *
0.0174532925199433
)) + random_yj();
220
point =
new
MapPoint();
221
point.setX((num + Transform_jy5(x, xx)) *
3686400.0
);
222
point.setY((x + Transform_jyj5(x, yy)) *
3686400.0
);
223
}
224
return
point;
225
}
226
227
private
double
yj_sin2(
double
x)
228
{
229
double
num =
0.0
;
230
if
(x <
0.0
)
231
{
232
x = -x;
233
num =
1.0
;
234
}
235
int
num2 = (
int
) (x /
6.28318530717959
);
236
double
num3 = x - (num2 *
6.28318530717959
);
237
if
(num3 >
3.1415926535897931
)
238
{
239
num3 -=
3.1415926535897931
;
240
if
(num ==
1.0
)
241
{
242
num =
0.0
;
243
}
244
else
if
(num ==
0.0
)
245
{
246
num =
1.0
;
247
}
248
}
249
x = num3;
250
double
num4 = x;
251
double
num5 = x;
252
num3 *= num3;
253
num5 *= num3;
254
num4 -= num5 *
0.166666666666667
;
255
num5 *= num3;
256
num4 += num5 *
0.00833333333333333
;
257
num5 *= num3;
258
num4 -= num5 *
0.000198412698412698
;
259
num5 *= num3;
260
num4 += num5 *
2
.75573192239859E-
06
;
261
num5 *= num3;
262
num4 -= num5 *
2
.50521083854417E-
08
;
263
if
(num ==
1.0
)
264
{
265
num4 = -num4;
266
}
267
return
num4;
268
}
269
}
270
0 0
- 谷歌地图离线发布系列之偏移处理(三)纠偏算法
- 谷歌地图离线发布系列之偏移处理(一)纠偏算法理论基础
- 谷歌地图离线发布系列之偏移处理(二)纠偏算法-火星坐标系那些事
- 谷歌地图纠偏(0.001纠偏)
- 谷歌地图纠偏数据库
- 地图纠偏算法
- 地图纠偏算法
- gps纠偏及大陆地图偏移原因
- gps纠偏及大陆地图偏移原因
- gps纠偏及大陆地图偏移原因
- 谷歌离线地图发布服务器
- 提供一个谷歌(腾讯)、百度地图纠偏数据库
- Google 全国 地图 纠偏数据 偏移数据 超高精度(0.002) (纠偏、偏移、地图、数据)
- 百度 Google 高德 全国 地图 GPS纠偏数据 偏移数据 火星坐标修正方案(经纬度纠偏)
- Google体系地图纠偏算法
- 无意中发现了谷歌、腾讯、高德地图纠偏算法
- 百度离线地图JavaScript版本MFC应用离线纠偏
- 国内首发彻底告别地图偏移,百度影像完美纠偏
- [LeetCode] Valid Parentheses
- 1Z0-051 QUESTION 13 Q字符的特殊使用
- 链表逆序
- 最大匹配模板
- 苹果加急
- 谷歌地图离线发布系列之偏移处理(三)纠偏算法
- Xcode5.1默认使用ARC,如何关闭ARC
- PreferenceActivity的使用
- 纸上得来终觉浅,绝知此事要躬行。
- 二分查找
- Ubuntu 12.04右键在当前位置打开终端
- Objective - c JsonKit 进行json转对象 对象转json数据 & Jastor json数据转为对象
- hive中的udf时间函数用法
- 给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?