文章出處

一年前無聊做過有關微信公眾號的開發, 那時微信還沒做服務號和訂閱號之分。當時開發中有一項便是通過微信公眾號功能查找附近地理位置信息,這些天幫朋友開發類似功能才發現,我當時的功能有個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:

image

只是他們是基于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來完成此功能了。

最后來一張截圖,展示此公眾號提供的附近搜索功能。

查詢附近咖啡廳返回的圖文消息:

image

點擊進入全圖的樣例:

image

 

至此此功能就算完成了,

參考:http://www.cnblogs.com/zhaohuionly/archive/2013/06/18/3142623.html


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜

    大師兄 發表在 痞客邦 留言(0) 人氣()