完美解决Google电子地图偏移问题II
之前写了篇”完美解决Google电子地图偏移问题“,但是 google在3月31日更新了ditu.google.cn的实现,原有的方法已经不适用。ant 分析了google maps新的纠偏方法,并写出了相应的纠偏算法。今天正好有时间把思路整理一下贴出来,以免大家分析google地图偏移时走弯路。
新版谷歌地图的偏移原理
以前的谷歌地图(ditu.google.cn),电子地图和卫星地图图片都和mas.google.com一样。用户在使用浏览器访问谷歌地图时,客户端浏览器把要显示的电子地图和卫星地图下载到本地,再调用google的偏移接口获取偏移值,用javascript进行地图纠偏。一切操作都是在客户端浏览器进行的。现在改进后的谷歌地图就不一样了,谷歌地图在服务器上预先把标准的卫星地图按照偏移量切割成新的带偏移的图片,用户在使用浏览器访问谷歌地图时,客户端浏览器直接下载偏移的地图图片,在和谷歌地图的交互过程中不传输任何偏移值。
新版谷歌地图的纠偏方法
谷歌地图的这次升级很完美,以前大家普遍采用的纠偏方法都失效了。但是,任何系统都有漏洞,关键就看怎么去挖掘。现在的切入点就是,谷歌地图升级后,同一经纬度的卫星图片 ditu.google.cn和maps.google.com不一样。
我们看看对于经纬度(22.535076,114.021229),通过ditu.google.cn和maps.google.com访问得到zoom 14级别卫星图片的差别。关于经纬度和google maps的图片编号x,y转换关系这里就不叙述了。
用公式计算出(22.535076,114.021229)在zoom 14下的图片编号为x=13381,y=7138
获取ditu.google.cn图片:
http://mt1.google.cn/vt/lyrs=s@58&gl=cn&x=13381&y=7138&z=14&s=Gali
获取maps.google.com图片:
http://khm1.google.com/kh/v=58&x=13381&y=7138&z=14&s=Gali

同一个点在cn地图和com地图上的位置是不一样的,两个位置坐标的差值就是偏移量!
下面就重点研究如何获取这个差值。单纯取一个像素点来算会有很大误差,而且图片中的一个正确点经过偏移后,很可能已经“跑”出这张256×256图片的范围。ant对以前通过接口获取的偏移值统计分析发现,zoom 18级别地图的X方向的偏移<2000,Y方向<1000,也就是16×8 张图片的范围。
为了计算方便和提高精度,我们用zoom 14下整张图片(256×256)做对比的方法来计算偏移,因为zoom 14和zoom 18大小相差16倍,通过计算可知,zoom 14下的偏移范围是X<125,Y<63。所以在zoom 14级别下可以保证一张标准卫星图片经过偏移后不会“跑”出以该图片为中心的9张 (3×3)图片范围。
(1)首先读取ditu.google.cn下(22.535076,114.021229)经过偏移后的卫星地图(图片a) ,x=13381,y=7138

(2)读取maps.google.com下以坐标点(13381,7138)为中心的9张图片,分别是
(13380,7137),(13381,7137),(13382,7137),
(13380,7138),(13381,7138),(13382,7138),
(13380,7139),(13381,7139),(13382,7139)

合并成一张图片(图片b)

(3)剩下的事就是找出有偏移的图片a在图b中的位置(x1,y1),标准图片13381-7138在图b中的实际位置是(256,256),所以偏移值就是X=x1-256,Y=y1-256

纠偏算法验证
ant用vc写了个example来验证算法的正确性,感谢虫牙童鞋在算法上的帮助。给定经纬度后,程序计算该经纬度对应的zoom 18级的偏移值。

(22.535076,114.021229)实际偏移值是:938,568,测试程序计算出的结果是942,566。偏差x方向4个像素,y方向2个像素。
ant又找了10个不同的点,这些点都保存了以前通过google接口查询的标准值,用来验证算法的正确性。
| 经度 | 纬度 | 标准值 | 计算值 | 误差(像素) | |
| 上海市 | 121.345001 | 31.261600 | 852,411 | 855,412 | x:3,y:1 |
| 上海市 | 121.454002 | 31.227900 | 855,410 | 855,414 | x:0,y:4 |
| 深圳市 | 114.038223 | 22.519770 | 945,559 | 949,557 | x:4,y:2 |
| 深圳市 | 113.893997 | 22.796499 | 912,604 | 912,606 | x:0,y:2 |
| 北京市 | 116.525002 | 39.968300 | 1107,-284 | 1105,-280 | x:2,y:4 |
| 北京市 | 115.952324 | 39.732647 | 1109,-255 | 1112,-257 | x:3,y:2 |
| 重庆市 | 106.530998 | 29.456900 | 703,605 | 702,609 | x:1,y:4 |
| 重庆市 | 106.496002 | 29.539000 | 723,576 | 722,580 | x:1,y:4 |
| 西安市 | 108.931976 | 34.271782 | 862,360 | 865,360 | x:3,y:0 |
| 西安市 | 109.001999 | 34.278198 | 907,322 | 913,321 | x:6,y:1 |
从结果看,偏移值误差大部分在4个像素内,也就是说在google maps卫星地图最高的清晰度级别(zoom 18)时,算法的误差大概是1~2米。
如何快速获取谷歌电子地图的偏移
上面提到的方法挺复杂,其实最简单的方法就是使用anttna.com的偏移接口: http://www.anttna.com/goffset/goffset1.php?lat=xxx&lon=xxx
虽然google接口关闭了,但是ant的goffset接口仍然有效。
goffset的具体使用方法见ant的上一篇blog 完美解决Google电子地图偏移问题 。
嗯。嗯。嗯。又熬到后半夜了。最近很辛苦啊。有个问题,如果下次GG对地图偏移算法又有更新…那是不是又得重新计算…还好GG不会十天半个月更新一次啊…
@lain
这次谷歌地图只是升级了系统,用了更高级的方法纠正偏移,但是google地图所使用的偏移算法没变。
偏移算法貌似是国家测绘局统一规定的,每个地方的偏移值都是固定的,不会改变。
我塞,ANT同志在研究GG地图便宜又有了新的研究成果啊,赶紧立个项。
K,瞧我这水平,那么不严谨的态度,没法申请项目了。。。
发现点小问题:http://www.anttna.com/goffset/goffset.php?lat=xxx&lon=xxx 提示错误的时候没有设置编码方式,导致很多默认不使用UTF8的用户看到的是乱码,建议增加META标签。
@ELM
接口输出的全是数字,就那一句中文。呵呵,直接给改成英文了。
能否提供偏移接口的数据或算法,可购买。邮箱:coolware_hb@hotmail.com
@coolware
偏移数据和偏移算法只提供使用,不出售。
@coolware
偏移数据和偏移算法只提供使用,不出售。
請問ANT的接口會關閉嗎?
@Howard
接口会一直提供使用。
经测试,在广东茂名市区,利用ant大大的纠偏接口得到纠偏数据不准,偏差较大,主要是lat偏差大,往南有0.002左右的偏差,我的测试point是: defCenterPoint = new GLatLng(21.65888889, 110.9197222);
@google api新手
该点数据已更新,(21.65888889, 110.9197222)最新的偏移值应该是(844,560)
大大,依然有偏差哦,东西方向的偏差完全没有,但是南北的偏差还是有不少,还是有0.002度的往南经纬度偏差。给大大一个实际采集的点: 110.91 21.66666667,这个点实际位置应该是在茂名油城四路新湖3街,与“飘逸感觉”这个点的一样纬度的,请大大测试一下。
@google api新手
(21.66666667,110.91)这个点的偏移值836,558 没有问题
至于为什么会出现你说的情况,我也不太清楚。
哈,老大真抱歉,我马大哈,传错offsetx为offsety了,:(,谢谢你的解答,较偏很准,谢谢你提供了一个好借口。
ANT:
我通过你那个服务,输入下面坐标
39.90 116.01
其中经度由116.01-116.09所返回的偏移都是18,1138,-289
这个是什么问题?
@lamgz
有些经纬度系统没算出精确偏移值,会根据附近点给出一个近似值
@ant
google’ map纠偏有纠偏数据库。简单讲,就是每个经纬度组合对应一个固定的纠偏值。
@uestar
问题是google现在不对外开放偏移数据库,所以只能通过其他办法找出偏移量
老大,接口不能用了!
提供的接口,现在访问不了了,Forbidden
You don’t have permission to access /goffset/goffset.php on this server.
接口可以用的啊!!
不过这样每次都得调用这个接口。。
而且,如果停止服务就死定了~
哎
请问只利用google map 的最新偏移接口(http://ditu.google.cn/maps/vp?…)还能直接算出纠正后的坐标吗?就是没有所谓的纠偏数据库的情况下,谢谢
@xuanyuancl
不能。
现在都不用搞了!很准确的了
怎么不能提供VC demo让我们研究研究呢^_^,谈钱伤感情~~
1)第一个问题:关于经纬度和google maps的图片编号x,y转换关系这里就不叙述了。
用公式计算出(22.535076,114.021229) 这个公式是怎么样?搜索也没找到,麻烦告诉我一下;
2)是不是我用你的接口算出了偏移了,基本上一个城市就可以按照这个偏移量来矫正误差了?
非常感谢
请教该方法URL获得数据,怎么使用呢?比如返回 18,879,498 ;
我怎么用?谢谢!
@ant
不对,国家测绘局给出的偏移不是固定的,也不是线性的,而且每一级的偏移大小还不一样,所有国内的图都要送国家测绘局审核,其实就是进行人为加偏处理,加密算法是高级机密。
国家保密插件,也叫做加密插件或者加偏或者SM模组,其实就是对真实坐标系统进行人为的加偏处理,按照几行代码的算法,将真实的坐标加密成虚假的坐标,而这个加偏并不是线性的加偏,所以各地的偏移情况都会有所不同。而加密后的坐标也常被人称为火星坐标系统,这是我们的国家又一个伟大的发明,让国外的政府和企业等,都看不懂我们的坐标系统。
其实很少有人知道国家保密插件问题,但作为导航电子地图产业或者汽车导航产业中的人,多多少少都会了解到这个问题。国家是出于国家安全考虑,将我们看到的真实的坐标变成假的虚拟的坐标,这样,我们的国家就安全了,不会被恐怖分子破坏了。最简单的举例来说,比如鸟巢吧,你真实的坐标是这个,加密后就成了那个,导航电子地图上看到的就是那个,那么人家导弹要是攻击那个的时候,那么导弹就打不中我们的鸟巢啦,我们的鸟巢就安全了。不过,个人担心这样加密后没有打中鸟巢,会不会打中水立方呢,可能是无心插柳柳成荫了。
具体说说这个保密插件的问题吧,是如何运作的呢?
现在,所有的电子地图所有的导航设备,都需要加入国家保密插件。第一步,地图公司测绘地图,测绘完成后,送到国家测绘局,将真实坐标的电子地图,加密成“火星坐标”,这样的地图才是可以出版和发布的,然后才可以让GPS公司处理。第二步,所有的GPS公司,只要需要汽车导航的,需要用到导航电子地图的,统统需要在软件中加入国家保密算法,将COM口读出来的真实的坐标信号,加密转换成国家要求的保密的坐标,这样,GPS导航仪和导航电子地图就可以完全匹配啦,GPS也就可以正常工作啦。
所以,所有的导航电子地图公司,像四维图新、瑞图、易图通、高德等等,都需要将自己的电子地图拿到国家测绘局进行加密处理,而所有的导航软件公司,都需要将自己的导航软件中加入国家测绘局提供的加密算法的代码。而这一段代码,就是国家的机密,不是公开的,每次去国家测绘局加密处理都需要预约并在封闭的环境中进行,编译完成后需要是在主程序的exe中,而不能编译在外部dll等文件中。
当然,国家的保密插件,是需要收费的,早期的时候,一个导航仪就需要10块钱的保密插件许可费,恩,保密插件也不是白用的,毕竟国家花了很多的钱和人力和物力才做出来的保护国家安全的保密东西怎么可以随便送你用呢,收点钱也就算是正常也算是在预料之中啦。现在的话,好像已经下放到地图数据公司了,就是看这个地图数据公司的经营状况,大概会出货多少份电子地图,然后一次性收取地图数据公司多少钱,可能是多少百万,然后这个钱呢,你们数据公司就自己找你们的导航软件公司的客户收吧,算在每一台设备中的许可费,恩,国家的办事效率变高了,一次直接从导航电子地图公司收费比逐个收取导航软件公司的钱要来的容易和不那么麻烦。
现阶段,有些人或者组织,为了自己的利益,将导航软件和导航地图进行破解,并发现了导航电子地图中存在的地图偏差,所以就采取人为的手段,将地图反加密,将虚假的坐标转换成标准的WGS84坐标,最笨的方法就是线性的平移,大概偏差的距离为500米,基本上能够反回来,但误差较大,特别是南北距离加大的情况下,而聪明一点的方法,用matlab等工具计算出其中的曲线,然后反转回来。多么的可怕那,这是触犯国家法律的行为,国家的安全就这样被你们破坏了,这是一个刑事问题,而不是简单的破解软件破解地图的经济犯罪问题了。请大家务必务必遵守国家的法律,不要干出这样的傻事出来,出了事谁都保不了你,毕竟你将成为国家的敌人。
最后,说说保密插件带来的弊端,好处不容忽视,国家为了安全考虑,保密了就安全了,但弊端是,制造了人为的障碍,非常的不好用,比如导航软件出来的坐标,不能和Google Earth等国际软件匹配,Google Earth和Map在国内基本上就是废物。进一步带来的导航问题是,寻宝、分享等许多好玩的GPS活动,都无法在大陆地区展开,这一点真的让人很无奈。当然,也有一些时候,由于导航软件的保密插件问题,导致不能导航等等。保密插件,是一个让人哭笑不得的东西,就如同国际的WGS84坐标对我们的54坐标或者80坐标,就如同最近的国家部门准备开发“影像中国”反制google earth的泄密问题。等等种种,法律不可逾越,但我们也不希望人为的制造麻烦,或者为了更深入的经济利益。
谢谢ant的分享,真的是非常感谢!
国家这么做,初衷是好的,但发展到现在,就是为了让有关部门多赚些钱罢了,
我看是早晚要取消掉的,说白了,卫星都不是你的,真要搞导弹,哪会用这种?自欺欺人罢了
google map api v3 你提供的接口还可以用吗?v3里没有相应的方法及函数
请问怎样将经纬度转换成google地图的图片编号x,y呢?
博主你好 我想问下 怎么找到 x1 和y1 的坐标呢
国家测绘局原始的数据就没美国的准 难道人家连你不加密的数据都不会用 ,还会用你加过密的数据? 人家发导弹会用你的数据? 人家自己的卫星比你好多了 难道不会用自己的卫星来导航? 为了防止恐怖攻击 gps要加密而有误差 .简直是天大的笑话! 只有搞到自己国家的老百姓 人家在国外上google erath 查到的都是准确的坐标 只有在国内google erath才是有误差的 而且 国内也可以很方便的修正地图数据
ant你好,为什么偏移接口查询不到数据呢?http://www.anttna.com/goffset/goffset.php?lat=xxx&lon=xxx,XXX已经替换为经纬度坐标值,但每次都是显示18,0,0。
@不听不说
http://www.anttna.com/archives/468.html
请使用本站的偏移修正接口: http://www.anttna.com/goffset/goffset1.php?lat=纠偏前的纬度值&lon=纠偏前的经度值
老大,你文章中关于新版谷歌地图纠偏方法的第3步“找出有偏移的图片a在图b中的位置”,是人工完成的,还是程序自动完成的,如果是自动的,那不是要用图像匹配程序吗?
每次都是显示18,0,0。接口好像又没用了!
请问如何把经纬度转为对应的x与y值 虚心求教…
大大, 能把算法及相应的数据文件给我么, 谢谢啦, 发我邮箱就行
@ttt
数据量很大的
http://www.anttna.com/goffset/goffset1.php?lat=纠偏前的纬度值&lon=纠偏前的经度值
你好,上面连接的偏移算法是如何计算的,能告诉我吗? 谢谢
看来老大也不愿将好人做到底啊@!只提供使用,不给算法!
可是我要在内网中使用怎么办呢?
說到底,安全只是幌子,要各個政府部門利用自己的權力賺錢才是硬道理
我想问下,有那种逆向 http://www.anttna.com/goffset/goffset1.php?lat=xxx&lon=xxx 的接口么?就是我知道修正后的坐标,想得到修正前的坐标啊!!!!
@维维
http://www.anttna.com/archives/1006.html
仔细读完了纠偏的相关资料,试用了博主的接口。深感佩服
这样好的接口,衷心希望能长期使用。如果有什么变化,也请提前告知
谢谢博主
这个纠偏的接口非常不错,唯一不好的地方是获取速度太慢。获取一个纠偏后的经纬度需要3~4秒。如果能在一秒以内就好了。
非常感谢兄弟的纠编接口,帮我解决了定位不准的问题。另还有个问题请教一下。我想利用google的place api做一个周边公交站查询的功能,发现测试结果不理想
1. 设置type=bus_station name=空, https://maps.googleapis.com/maps/api/place/search/json?location=22.535076,114.021229&radius=1000&name=&sensor=false&key=xxx&type=bus_station 查出的结果没一个是公交站点
2.设置type=空,name=站
https://maps.googleapis.com/maps/api/place/search/json?location=22.535076,114.021229&radius=1000&name=站&sensor=false&key=xxx&type=
能查出地名中包括“站”关键字的地点,如福田总站,xx加油站,也能查询名字不带“站”但坐标确实是公交站点的位置来,如“竹子林,深航大厦”。而其返回json里竹子林、深航大厦的type都是”establishment”(这个type值真是搞不懂)。
3.设置type=establishment,name=站,情况和2类似,能找到想要的公交站点,只是响应结果中都包括了许多多余的地点。
请教一下是否怎么改一下接口参数可以满足要求,或者有别的更好的开放api,多谢