谷歌地图离线发布系列之偏移处理(三)纠偏算法
先上代码,用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.java
package 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
|
谷歌地图离线发布系列之偏移处理(三)纠偏算法相关推荐
- 谷歌地图离线地图瓦片下载_如何下载Google地图以供离线使用
谷歌地图离线地图瓦片下载 If you've ever wanted to be able to download Google Maps data for offline use, you shou ...
- 百度地图、高德地图、谷歌地图离线瓦片下载研究(一)
百度地图.高德地图.谷歌地图离线瓦片下载研究(一) 背景 最近公司一个项目用到百度api在线调用百度地图.但是后来客户提出项目需要部署在内网,希望调用离线地图.公司不想再投入资金购买地图数据.网上一些 ...
- 谷歌地图发布海底街景地图
据谷歌官方博客报道,谷歌地图今日发布了一项全新的街景功能:海底街景地图.用户使用"水下街景"功能看到的景象主要来自澳大利亚.夏威夷以及菲律宾海域的珊瑚礁以及生活在其中各种各样的海洋 ...
- 2015年全国谷歌卫星地图离线数据存储方案
一.概述 随着地理信息数字化的发展,大数据时代的到来.海量数据的传输和安全性给我们带来巨大的困难.海量数据的传输受到互联网技术和硬件的限制,占用着较多的在线资源和线下存储空间,产生了能源.空间.人力的 ...
- bigemap如何二次发布谷歌地图?
1. 当前版本支持 谷歌电子/卫星地图瓦片.高德地图.阿里云地图.超图.腾讯地图等(只需下载该地图源的瓦片拷贝到指定目录即可): 2. 效果预览演示地址: 后台编辑体验地址: 可随意在后台添加/修改标 ...
- php离线地图,如何发布百度离线地图及二次开发API
相关教程: 1.说明 离线地图开发环境支持谷歌地图.百度地图.高德地图等等所有常用地图类型,支持在局域网内的地图部署.二次开发. 2.实现 第一步:下载安装离线地图开发环境 下载安装好之后,启动软件, ...
- ios 高德地图加载瓦片地图_OpenLayers加载谷歌地球离线瓦片地图
本文使用OpenLayers最新版本V5.3.0演示:如何使用OpenLayer加载谷歌地球离线瓦片地图.OpenLayers 5.3.0下载地址为:https://github.com/openla ...
- 在线下载离线地图瓦片 (支持百度、高德和谷歌地图)
制作离线地图,下载百度矢量数据制作3D地图,下载离线地图数据,下载离线地图瓦片.支持三个主流地图数据(百度.高德和谷歌). 下载网址:http://wmksj.com/ 1. 点击"地图下载 ...
- 三维地图(3D地图)离线地图开发发布时间:2020-03-03 版权:
三维地图(3D地图)离线地图开发 发布时间:2020-03-03 版权: 1.如何搭建离线地图开发环境 视频教程 2.下载离线地图数据(金 ...
最新文章
- 根据当前记录获取前一条与下一条记录常用 sql语句
- qq飞车登陆服务器无响应,qq飞车手游进不去怎么回事 为什么进不去游戏
- PHP 入门 - 9.安全
- 【ArcGIS遇上Python】窗体版Python批量处理地理数据--栅格裁剪
- 多维标度法MDS古典解的证明与R语言实现
- mount: none already mounted or /cgroup busy
- jwt和传统session的区别?
- matlab线性数据毛刺剔除,matlab滤波技术及区域处理---线性滤波
- 浅析RTB和RTA(一)
- 怎么在html中设置天数倒计时,PPT里面怎样设置时间倒计时,求大佬指教?
- 编程,从来都不晚:来自日本的82岁APP开发者
- [数据挖掘笔记] 聚类算法KMeans
- 报错:Module parse failed: ‘return‘ outside of function (4:1) You may need an appropriate loader
- 操作系统之文件管理(二) ※
- 租房时代,K2 BPM软件带你拥抱更好生活
- 《图解TCP/IP》笔记
- 登陆网上邻居授权共享文件夹没有弹出登陆窗口解决办法
- 成功解决wps文档的论文中插入图片时只显示一半图片(两步教程完美搞定!)
- 《SQL必知必会》 11 使用子查询
- Android跳转淘宝商品详情页代码