google地圖經緯度偏移修正算法完美解決方案


http://baixiaozhe.iteye.com/blog/931814

 

 

原帖:http://blog.sina.com.cn/s/blog_65bd7eef0100hu5o.html

 

由於受到國家一些法律法規限制,所有的電子地圖服務提供商都需要給地圖數據加上偏移和加密,因此廣受大家關注的google地圖也不例外。但是作為一些用慣了免費服務的網友們,始終對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-2701193x方向上精度的偏移像素,-270y方向上維度偏移像素

6.      經緯度的偏移轉換我們需要江經緯度39.111195117.148067轉化為18級像素值25620917 55392414,然后分別加上偏移量-270,1193,然后再轉化為經緯度39.11231854918217 117.15446412563324,即位偏移后的經緯度

 

google的地圖采用將地球圓表面投影成平面的方式進行貼圖

假設zoom=15;

橫坐標從左至右像素為0-256*2的15次冪,也就是每增加一級,地圖大小橫縱坐標加倍,256為一個標准圖片的大小

顯示-180度到+180的范圍,經度越大x越大

縱坐標從上到下像素為0-256*2的15次冪,顯示+85到-85度的范圍,緯度越小y越大

我們先看一下經度的轉換

經度的轉換,我就不多說了,均勻分布,大家簡單的看一下下面的公式就明白了

經度到像素X值

public static double lngToPixel(double lng, int zoom) {

return (lng + 180) * (256L << zoom) / 360;

}

像素X到經度

public static double pixelToLng(double pixelX, int zoom) {

return pixelX * 360 / (256L << zoom) - 180;

}

緯度到像素Y

public static double latToPixel(double lat, int zoom) {

double siny = Math.sin(lat * Math.PI / 180);

double y = Math.log((1 + siny) / (1 - siny));

return (128 << zoom) * (1 - y / (2 * Math.PI));

}

像素Y到緯度

public static double pixelToLat(double pixelY, int zoom) {

double y = 2 * Math.PI * (1 - pixelY / (128 << zoom));

double z = Math.pow(Math.E, y);

double siny = (z - 1) / (z + 1);

return Math.asin(siny) * 180 / Math.PI;

}

 

維度的這個轉換,單純去理解不是很好理解,我也沒有太深入的了解,從公式來看,采用了一種非線性變化,也就是靠近赤道的地方單位像素表現的緯度間距大,越靠近兩極越小,可能是因為 經度在靠近兩極的方向均勻變化,導致緯度也要進行拉伸,否則  靠近兩極的地方,地理形狀就該發生變化了,總之上面的轉換公式大家還是可以研究一下的,google維度的表示范圍是-85到+85,這個可以求出來!

上面得到的像素XY是像素的坐標,並非是google地圖取地圖的那個XY那個XY是把像素所標除以256得到的商,也就是每張圖片的大小

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM