Google Map经纬度偏移修正算法完美解决方案

转自:http://www.tufangbian.com/bbs/viewthread.php?tid=68

中国地图卫星图都存则偏移量,这个由中国规划局,确定,一个偏移算法,实际上是没有什么特殊规律的,他的生成算法是有规律,不过这个规律你我都很难拿到,那我们怎么解决这个偏差呢,毕竟做地图开发的都存在卫星图和地图的切换,谁不想让切换以后的地图对上呢!后来我发现google地图服务,ditu.gogle开始的都没有偏差,maps.google开头的服务就有偏差,我就开始查找google的取偏移量算法,事前我还是图破解google手机版本的数据,没有成功,估计是使用了自己的压缩或加密算法,最后也没有找到规律,后来才尝试破解web版本的不过web版本的接口我对于js不是特别熟悉,所以本次破解放弃了分析源代码的步骤,而是直接采用排除法那就是把地图部分访问的全部地址,一个接一个封杀掉,查找那个气偏移做用的网址http://ditu.google.cn/maps/vp?spn=0.0,0.0&z=18&vp=39.111195,117.148067 最后找到了就是这个,记住每次测试用清理浏览器缓存哦,使用fixfox的fildder和adblock就够了 然后就是 分析每次返回内容的规律,黄天不负有心人啊,我总算是搞定了,下面是我整理的接口

Google 中国地图偏移接口



1.      接口地址:http://ditu.google.cn/maps/vp?spn=0.0,0.0&z=18&vp=39.111195,117.148067



(注:.cn和.com都可以,我用国内服务器就会选择.cn用美国服务器就会选择.com)

2.      返回内容中的有效部分:

3.      (39.111195, 117.148067, 18, [9, -2, 18, -4, 37, -8, 74, -16, 149, -33, 298, -67, 596, -135, 1193, -270])4.      Spn参数暂时未知实际意义,但是需要上发spn参数,任意两个小数用逗号分开

Vp参数纬经度值,用逗号分隔,z参数为地图缩放级别,无实际意义

5.      取回的部分中有效数字为[9, -2, 18, -4, 37, -8, 74, -16, 149, -33, 298, -67, 596, -134, 1192, -268]这个数组总共有8组数字,每两个为一组,分为别从11级到18级的地图和卫星图的偏移像素数量,我们前一组数字精确的等于后一组数字除二,我们为了得到最精确的偏移,故选择第18级的偏移量1193,-270,1193为x方向上精度的偏移像素,-270为y方向上维度偏移像素

6.      经纬度的偏移转换我们需要江经纬度39.111195,117.148067转化为18级像素值25620917 和 55392414,然后分别加上偏移量-270,1193,然后再转化为经纬度39.11231854918217 和117.15446412563324,即位偏移后的经纬度



以上是我花了2个小时完成的google偏移接口的破解,后来公司要求,把google的偏移数据全部弄下来,以防止gogle更换服务接口,我现在采用的是每隔0.01个经纬度,取一次偏移量,数据存入bdb,中国的总数据量  千万条级别,我用了两天的时间已经完成了三分之一中国的爬取,当然我用了三台服务器,总数据量估计在1个G一下,是可以接受的范围,精度可以保证最大级别18级地图,偏差小于5个像素






public static boolean getOffset(HttpClient httpClient, int lat, int lng) {

StringBuilder url = new StringBuilder();

url.append("http://ditu.google.com/maps/vp?");

url.append("spn=0.0,0.0&z=18&vp=");

url.append(lat / 100D);

url.append(",");

url.append(lng / 100D);

String urlStr = url.toString();

GetMethod method = new GetMethod(urlStr);

try {

int status = httpClient.executeMethod(method);

if (status == 200) {

byte[] bs = method.getResponseBody();

String js = new String(bs, "utf-8");

int x = js.lastIndexOf("[");

int y = js.lastIndexOf("]");

if (x > 0 && y > 0) {

String text = js.substring(x + 1, y);

int b = text.lastIndexOf(",");

int a = text.lastIndexOf(",", b - 1);

if (a > 0 && b > 0) {

String offsetPixX = text.substring(a + 2, b);

String offsetPixY = text.substring(b + 2);

OffsetBean offset = new OffsetBean();

offset.setLng(lng);

offset.setLat(lat);

offset.setOffset_x(Integer.parseInt(offsetPixX));

offset.setOffset_y(Integer.parseInt(offsetPixY));

OffsetBDB offsetBDB = OffsetBDB.getInstance();

offsetBDB.putOffset(offset);

return true;

}

} else {

logger.error("error 1:  lat:" + lat + "\tlng:" + lng);

}

} else {

logger.error("error 2:  lat:" + lat + "\tlng:" + lng);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

method.releaseConnection();

}

return false;

}





有不明白的地方可以联系我



[email protected]



热心解答,做程序的互相帮助

你可能感兴趣的:(Android)