1. 程式人生 > >Google Map經緯度偏移修正演算法完美解決方案

Google Map經緯度偏移修正演算法完美解決方案

中國地圖衛星圖都存則偏移量,這個由中國規劃局,確定,一個偏移演算法,實際上是沒有什麼特殊規律的,他的生成演算法是有規律,不過這個規律你我都很難拿到,那我們怎麼解決這個偏差呢,畢竟做地圖開發的都存在衛星圖和地圖的切換,誰不想讓切換以後的地圖對上呢!後來我發現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]



熱心解答,做程式的互相幫助