完美解决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电子地图偏移问题 。
@ifeng
很抱歉ifeng,我对google place api接触不多,帮不了忙。
获取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
这两个链接貌似都打不开了 切片算法换了?
@切片算法换了?
url经常会变
用一些浏览器插件(firefox live http headers ..)就可以抓到url,比如
http://mt1.google.cn/vt/lyrs=s@94&hl=zh-CN&gl=cn&src=api&x=13381&y=7138&z=14&s=Gali
ant,请问http://wap.anttna.com/index-wap2.php?p=641中的(3)剩下的事就是找出有偏移的图片a在图b中的位置(x1,y1),标准图片13381-7138在图b中的实际位置是(256,256),所以偏移值就是X=x1-256,Y=y1-256 里找到图片a是用的图像处理方面的知识么 还是?
ps.(3)中红框标出的图片a好像和(1)中的不太一样 是有问题么 还是我理解错了
@special
是的,用的是图像对比,找出a在b中的位置。
图a是我贴错了,已修改。多谢指正。
我仔细阅读了这篇文章,
问题是这样:
比如我下载了某区域的卫星影像,而且我知道这个区域很多点的未偏移坐标和偏移后坐标,
那么能准确定位吗,在我自己的软件里。
仅知道这个区域左下角和右上角经纬度,能定位吗?
如果不能,是不是说,卫星影像被人为故意扭曲了?
也就是说我拿到了一份谷歌卫星影像,且知道这幅影像的左下角和右上角准确经纬度坐标,那么在这幅影像上能精确定位吗?
@sky11811
可以,只要能算出X,Y两个方向的偏移量。在同一张(256×256)图片上,偏移量不变。
我下载了很大的区域 有20GB 仅知道这个区域的左上角右下角坐标 (偏移未偏移都知道),
能定位吗?
@sky11811
请问 您所说的下载很大的区域 是下载了google地图用作离线么? 谢谢
博主你好,我现在正在做一个地图相关的小应用,正苦恼于坐标偏移。如果直接使用您提供的web接口,是否会因为请求比较频繁对您的服务器造成影响?
博主你好,我如果频繁利用你的接口,比如每1分钟一次,是否会影响到您的服务器,增加服务器压力。另外,我是否能够稳定使用这个接口,我做了一个小程序,可是每次晚上三点的时候程序就死了!苦闷中,求大神指导!!~~(*^__^*) 嘻嘻
@花生米
1分钟一次请求,这样的频率对服务器没有影响。
另外,在程序里处理下异常吧。
那就好@ant
这个纠偏算法是不是要用到图像合成和图像识别啊?感觉比较复杂。