先上代码,用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  

谷歌地图离线发布系列之偏移处理(三)纠偏算法相关推荐

  1. 谷歌地图离线地图瓦片下载_如何下载Google地图以供离线使用

    谷歌地图离线地图瓦片下载 If you've ever wanted to be able to download Google Maps data for offline use, you shou ...

  2. 百度地图、高德地图、谷歌地图离线瓦片下载研究(一)

    百度地图.高德地图.谷歌地图离线瓦片下载研究(一) 背景 最近公司一个项目用到百度api在线调用百度地图.但是后来客户提出项目需要部署在内网,希望调用离线地图.公司不想再投入资金购买地图数据.网上一些 ...

  3. 谷歌地图发布海底街景地图

    据谷歌官方博客报道,谷歌地图今日发布了一项全新的街景功能:海底街景地图.用户使用"水下街景"功能看到的景象主要来自澳大利亚.夏威夷以及菲律宾海域的珊瑚礁以及生活在其中各种各样的海洋 ...

  4. 2015年全国谷歌卫星地图离线数据存储方案

    一.概述 随着地理信息数字化的发展,大数据时代的到来.海量数据的传输和安全性给我们带来巨大的困难.海量数据的传输受到互联网技术和硬件的限制,占用着较多的在线资源和线下存储空间,产生了能源.空间.人力的 ...

  5. bigemap如何二次发布谷歌地图?

    1. 当前版本支持 谷歌电子/卫星地图瓦片.高德地图.阿里云地图.超图.腾讯地图等(只需下载该地图源的瓦片拷贝到指定目录即可): 2. 效果预览演示地址: 后台编辑体验地址: 可随意在后台添加/修改标 ...

  6. php离线地图,如何发布百度离线地图及二次开发API

    相关教程: 1.说明 离线地图开发环境支持谷歌地图.百度地图.高德地图等等所有常用地图类型,支持在局域网内的地图部署.二次开发. 2.实现 第一步:下载安装离线地图开发环境 下载安装好之后,启动软件, ...

  7. ios 高德地图加载瓦片地图_OpenLayers加载谷歌地球离线瓦片地图

    本文使用OpenLayers最新版本V5.3.0演示:如何使用OpenLayer加载谷歌地球离线瓦片地图.OpenLayers 5.3.0下载地址为:https://github.com/openla ...

  8. 在线下载离线地图瓦片 (支持百度、高德和谷歌地图)

    制作离线地图,下载百度矢量数据制作3D地图,下载离线地图数据,下载离线地图瓦片.支持三个主流地图数据(百度.高德和谷歌). 下载网址:http://wmksj.com/ 1. 点击"地图下载 ...

  9. 三维地图(3D地图)离线地图开发发布时间:2020-03-03 版权:

    三维地图(3D地图)离线地图开发 发布时间:2020-03-03 版权:               1.如何搭建离线地图开发环境    视频教程               2.下载离线地图数据(金 ...

最新文章

  1. 根据当前记录获取前一条与下一条记录常用 sql语句
  2. qq飞车登陆服务器无响应,qq飞车手游进不去怎么回事 为什么进不去游戏
  3. PHP 入门 - 9.安全
  4. 【ArcGIS遇上Python】窗体版Python批量处理地理数据--栅格裁剪
  5. 多维标度法MDS古典解的证明与R语言实现
  6. mount: none already mounted or /cgroup busy
  7. jwt和传统session的区别?
  8. matlab线性数据毛刺剔除,matlab滤波技术及区域处理---线性滤波
  9. 浅析RTB和RTA(一)
  10. 怎么在html中设置天数倒计时,PPT里面怎样设置时间倒计时,求大佬指教?
  11. 编程,从来都不晚:来自日本的82岁APP开发者
  12. [数据挖掘笔记] 聚类算法KMeans
  13. 报错:Module parse failed: ‘return‘ outside of function (4:1) You may need an appropriate loader
  14. 操作系统之文件管理(二) ※
  15. 租房时代,K2 BPM软件带你拥抱更好生活
  16. 《图解TCP/IP》笔记
  17. 登陆网上邻居授权共享文件夹没有弹出登陆窗口解决办法
  18. 成功解决wps文档的论文中插入图片时只显示一半图片(两步教程完美搞定!)
  19. 《SQL必知必会》 11 使用子查询
  20. Android跳转淘宝商品详情页代码

热门文章

  1. 学习Linux驱动的一点笔记
  2. 用uniapp开发打包多端应用完整指南
  3. 【MySQL】-SQL-统计数据的表格个数
  4. 多硬盘分区管理fdisk-张丹
  5. 华为鸿蒙国内厂商适配,华为再放大招!鸿蒙系统将适配高通/联发科手机:获国产厂商力挺...
  6. MAC install MySQL and DBeaver
  7. 艺赛旗(RPA)国家企业信用信息公示系统验证码破解(二)
  8. 最全PLC输入输出各种回路接线
  9. 金庸笔下武功最强的十人
  10. 计算机图像处理2000字论文,图像处理计算机技术论文