一年前無聊作過有關微信公衆號的開發, 那時微信還沒作服務號和訂閱號之分。當時開發中有一項即是經過微信公衆號功能查找附近地理位置信息,這些天幫朋友開發相似功能才發現,我當時的功能有個bug,從微信獲取到的地理座標是基於google的,而百度有本身的標準,因此須要作一個轉換。將google的地理座標換成百度的。html
以下是百度api輔助文檔中的一段信息前端
4.1 座標體系是否遵循國家對地理信息保密要求?
百度對外接口的座標系,都是通過國家測繪局加密處理,符合國家測繪局對地理信息保密要求。java
4.2 百度採用何種座標體系?
百度地圖api中採用兩種座標體系,經緯度座標系和墨卡託投影座標系。前者單位是度,後者單位是米,具體定義能夠參見百科詞條解釋: git
http://baike.baidu.com/view/61394.htm和http://baike.baidu.com/view/301981.htm。web
4.3 百度座標爲什麼有偏移?
國際經緯度座標標準爲WGS-84,國內必須至少使用國測局制定的GCJ-02,對地理位置進行首次加密。百度座標在此基礎上,進行了BD-09二次加密措施,更加保護了我的隱私。百度對外接口的座標系並非GPS採集的真實經緯度,須要經過座標轉換接口進行轉換。 算法
4.4 如何從其餘體系的座標遷移到百度座標?
座標轉換接口非公開。請將您的公司名稱、項目名稱、項目簡介、聯繫人和聯繫方式,發郵件至mapapi@baidu.com諮詢。有專人爲您解答。json
總的歸納就是:後端
因爲受到國家一些法律法規限制,全部的電子地圖服務提供商都須要給地圖數據加上偏移和加密,所謂的地圖數據加密偏移,其實就是用一個偏移算法對地圖的經緯度作一個加減偏移量,從而達到與實際地圖不一致。這個偏移算法自己是沒有什麼規律可言的,每家地圖服務商都有一套本身的加密偏移算法,既然算法上沒有什麼規律可言,可是對於算法中生成的偏移量是否有規律呢?這個是能夠確定的,可是偏移算法中生成的偏移量是有規律而言的。偏移量的規律很可貴到,要是能拿到這個偏移量,就能夠說是破解了某一個地圖服務商的地圖加密。
因此百度對外提供的座標系是百度本身的座標系,同理google對外提供的也是本身的座標系。因此必須得把二者換成統一座標系。換成原始GPS座標在國內原則上是違法的,因此只能統一成各個地圖運營商本身的座標系,好比百度座標系或者google座標系。 api
如何轉換成百度座標系:官方文檔給的是:座標轉換接口非公開。因而我開始搜搜「GPS座標轉換爲百度座標」。百度文檔中也確實說起到了gps座標轉換爲百度座標和goodle轉換爲百度座標。 微信
http://developer.baidu.com/map/jsdemo.htm
浮動框中有以下demo:
只是他們是基於web前端的,提供的方法也是js。
而我這個是在java後端,因此繼續找。最後發現百度本身提供一個有關座標轉換的api。
http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=longitude&y=latitude
其中:
from: 來源座標系 (0表示原始GPS座標,2表示Google座標)
to: 轉換後的座標 (4就是百度本身啦,好像這個必須是4才行)
x: 經度
y: 緯度
返回的結果是一個json字符串:
{"error":0,"x":"MTIxLjUwMDIyODIxNDk2","y":"MzEuMjM1ODUwMjYwMTE3"}
其中:
error:是結果是否出錯標誌位,"0"表示OK
x: 百度座標系的經度(Base64加密)
y: 百度座標系的緯度(Base64加密)
經過測試,發現好用。
以下是部分java源碼:
// 地理位置消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) { String location_x = requestMap.get("Location_X"); String location_y = requestMap.get("Location_Y"); String location = utils.getBaiDuLocationXY(location_x,location_y); CacheUtils.save(location, allresultutil.USER_INDEX_CC + fromUserName); PlaceSearchResponse response = utils.Getditu("ATM", location);
…
public static String getBaiDuLocationXY(String x, String y) { String result = ""; String url = "http://api.map.baidu.com/ag/coord/convert?from=2&to=4&x=" + x + "&y=" + y + ""; String response = HttpClientMethod.doGet(url, "", "utf-8", false); if (StringUtils.isNotBlank(response)) { MapConvert map = com.alibaba.fastjson.JSON.parseObject(response, MapConvert.class); if (map != null && 0 == map.getError()) { byte[] xbuff = Base64.decodeFast(map.getX()); byte[] ybuff = Base64.decodeFast(map.getY()); result = new String(xbuff) + "|" + new String(ybuff); } } return result; }
用戶經過發送地理位置消息,服務獲取到用戶的x/y座標後,測試發現是基於google的座標系的,而後經過百度提供的API將此xy座標換成百度的座標系,而後cache起來,就肯定了當前用戶的地理位置,這樣查詢此用戶附近的諸如「ATM」,「咖啡廳」,「廁所」等位置信息就能夠調用百度提供的豐富api來完成此功能了。
最後來一張截圖,展現此公衆號提供的附近搜索功能。
查詢附近咖啡廳返回的圖文消息:
點擊進入全圖的樣例:
至此此功能就算完成了,
參考:http://www.cnblogs.com/zhaohuionly/archive/2013/06/18/3142623.html