一年前無聊做過有關微信公眾號的開發, 那時微信還沒做服務號和訂閱號之分。當時開發中有一項便是通過微信公眾號功能查找附近地理位置信息,這些天幫朋友開發類似功能才發現,我當時的功能有個bug,從微信獲取到的地理坐標是基于google的,而百度有自己的標準,所以需要做一個轉換。將google的地理坐標換成百度的。
如下是百度api輔助文檔中的一段信息
4.1 坐標體系是否遵循國家對地理信息保密要求?
百度對外接口的坐標系,都是經過國家測繪局加密處理,符合國家測繪局對地理信息保密要求。
4.2 百度采用何種坐標體系?
百度地圖api中采用兩種坐標體系,經緯度坐標系和墨卡托投影坐標系。前者單位是度,后者單位是米,具體定義可以參見百科詞條解釋:
http://baike.baidu.com/view/61394.htm和http://baike.baidu.com/view/301981.htm。
4.3 百度坐標為何有偏移?
國際經緯度坐標標準為WGS-84,國內必須至少使用國測局制定的GCJ-02,對地理位置進行首次加密。百度坐標在此基礎上,進行了BD-09二次加密措施,更加保護了個人隱私。百度對外接口的坐標系并不是GPS采集的真實經緯度,需要通過坐標轉換接口進行轉換。
4.4 如何從其他體系的坐標遷移到百度坐標?
坐標轉換接口非公開。請將您的公司名稱、項目名稱、項目簡介、聯系人和聯系方式,發郵件至mapapi@baidu.com咨詢。有專人為您解答。
總的概括就是:
由于受到國家一些法律法規限制,所有的電子地圖服務提供商都需要給地圖數據加上偏移和加密,所謂的地圖數據加密偏移,其實就是用一個偏移算法對地圖的經緯度做一個加減偏移量,從而達到與實際地圖不一致。這個偏移算法本身是沒有什么規律可言的,每家地圖服務商都有一套自己的加密偏移算法,既然算法上沒有什么規律可言,但是對于算法中生成的偏移量是否有規律呢?這個是可以肯定的,但是偏移算法中生成的偏移量是有規律而言的。偏移量的規律很難得到,要是能拿到這個偏移量,就可以說是破解了某一個地圖服務商的地圖加密。
所以百度對外提供的坐標系是百度自己的坐標系,同理google對外提供的也是自己的坐標系。所以必須得把兩者換成統一坐標系。換成原始GPS坐標在國內原則上是違法的,所以只能統一成各個地圖運營商自己的坐標系,比如百度坐標系或者google坐標系。
如何轉換成百度坐標系:官方文檔給的是:坐標轉換接口非公開。于是我開始搜搜“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
文章列表