微信公衆號開發地理位置座標的轉換

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

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

相關文章
相關標籤/搜索