使用第三方定位API的目的是穩(wěn)定快速,在沒(méi)有GPS信號(hào)時(shí)也能通過(guò)WIFI及移動(dòng)信號(hào)準(zhǔn)確定位,但是因?yàn)檎邌?wèn)題,國(guó)內(nèi)的地圖會(huì)偏移,多半采用GCJ-02坐標(biāo)系,百度采用BD-09坐標(biāo)系,倒是我沒(méi)想到,高德的定位API竟然也返回GCJ-02坐標(biāo)系。

而且,setCoordType()不會(huì)有任何效果,就是說(shuō)在國(guó)內(nèi)不提供WGS84的坐標(biāo)數(shù)據(jù)。
網(wǎng)上有很多關(guān)于把GCJ02轉(zhuǎn)換成WGS84的算法,不過(guò)不得不說(shuō),都是垃圾,想當(dāng)年我還辛辛苦苦把搜到的java代碼重寫成JavaScript代碼,然后一點(diǎn)點(diǎn)調(diào)參數(shù)試的肝腸寸斷。就算網(wǎng)上最靠譜的簡(jiǎn)單算法,最多也只能在部分區(qū)域適用。聽我一個(gè)在百度的師姐說(shuō)他們?cè)谌珖?guó)范圍內(nèi)采了2000多萬(wàn)個(gè)控制點(diǎn)用來(lái)轉(zhuǎn)換的,不知是真是假。
很幸運(yùn),高德SDK提供了一個(gè)CoordinateConverter工具類,用于將阿里云、百度坐標(biāo)、谷歌坐標(biāo)、圖盟坐標(biāo)、圖吧坐標(biāo)、搜搜坐標(biāo)轉(zhuǎn)換成高德地圖坐標(biāo)(不支持反算)。不過(guò)他不支持反算,但是我們可以手動(dòng)反算。
反算有一個(gè)默認(rèn)的前提:GCJ-02和WGS84在同一個(gè)點(diǎn)的坐標(biāo)值通常差別不會(huì)特別大,一般都是小數(shù)點(diǎn)后面三位起,也就是我們明知定位得到的結(jié)果是GCJ02坐標(biāo)系的,但是就算是把他當(dāng)成WGS84,這個(gè)誤差也不會(huì)特別大,反應(yīng)在地圖上一般在500米以內(nèi)。
假設(shè)所在的點(diǎn)P用高德定位出來(lái)的數(shù)據(jù)(Xgcj,Ygcj),那么在這個(gè)點(diǎn)500米的范圍內(nèi),一定存在一個(gè)點(diǎn)P',他的WGS84的坐標(biāo)值與P點(diǎn)的GCJ02的坐標(biāo)值一致,即:
X'wgs = Xgcj
Y'wgs = Ygcj
我們把P'的WGS84的坐標(biāo)值丟進(jìn)CoordinateConverter正算一次,那就得到了P'點(diǎn)GCJ02的坐標(biāo)值(X'gcj,Y'gcj)。P'點(diǎn)的WGS84坐標(biāo)值和GCJ02的坐標(biāo)值當(dāng)然有一個(gè)差值:
dx' = X'gcj - X'wgs
dy' = Y'gcj - Y'wgs
又因?yàn)镻點(diǎn)和P'點(diǎn)相距非常近,所以我們可以認(rèn)為:
dx ≈ dx'
dy ≈ dy'
即:
Xwgs≈Xgcj - dx'
Ywgs≈Ygcj - dy'
代碼就比較簡(jiǎn)單了:
double longitude = amapLocation.getLongitude();
double latitude = amapLocation.getLatitude();
//初始化坐標(biāo)轉(zhuǎn)換類
CoordinateConverter converter = new CoordinateConverter(getApplicationContext());
converter.from(CoordinateConverter.CoordType.GPS);
//設(shè)置需要轉(zhuǎn)換的坐標(biāo)
converter.coord(new DPoint(latitude,longitude));
//轉(zhuǎn)換成高德坐標(biāo)
DPoint destPoint = converter.convert();
double dx = destPoint.getLongitude() -longitude;
double dy = destPoint.getLatitude() -latitude;
longitude = longitude - dx;
latitude = latitude - dy;