百度開放平臺-地理編碼服務

 地理編碼服務

地理編碼服務(又名Geocoder)是一類Web API接口服務;
正地理編碼服務提供將結構化地址數據(如:北京市海淀區上地十街十號)轉換爲對應座標點(經緯度)功能;
地理編碼服務當前未推出國際化服務,解析地址僅限國內;

功能介紹

地理編碼服務

用戶可通過該功能,將結構化地址(省/市/區/街道/門牌號)解析爲對應的位置座標。地址結構越完整,地址內容越準確,解析的座標精度越高。

URL:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

以下是開發的代碼,主要調取 getMap(); 方法:

<?php

/**
 * 百度地圖-根據詳細地址獲取經緯度
 * 文檔URL:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
 *
 * @since 20190117
 */
class Baidu_geocoderLib
{
    /**
     * 訪問應用(AK)
     * API控制檯申請得到的ak
     */
    const REQ_AK = '寫你的AK'; 

    /**
     * 請求校驗方式爲sn校驗方式時,系統會自動生成sk
     * 可以在應用配置-設置中選擇Security Key顯示進行查看
     * 文檔URL:http://lbsyun.baidu.com/index.php?title=webapi/appendix
     */
    const SECURITY_KEY = '寫你的SK';

    /**
     * 請求地址,GET
     * @var string
     * ?address=北京市海淀區上地十街10號&output=json&ak=您的ak&callback=showLocation //GET請求
     */
    const REQ_URL = 'http://api.map.baidu.com/geocoder/v2/';
    const REQ_URI = '/geocoder/v2/';

    /**
     * 錯誤信息
     * @var string|array
     */
    private $errMsg = null;

    /**
     * 是否使用sn簽名的驗證方式
     * @var bool
     */
    private $isSn = false;

    /**
     * sk碼
     * @var null|string
     */
    private $sk = self::SECURITY_KEY;

    /**
     * 請求參數,默認值
     * @var array
     */
    private $reqParam = array(
        'address' => '', // 待解析的地址,最多支持84個字節,(必須)
        'output' => 'json', // 輸出格式爲json或者xml
        'ak' => self::REQ_AK, // 用戶申請註冊的key,(必須)
        'callback' => '', // 將json格式的返回值通過callback函數返回以實現jsonp功能,(我們不需要)
        'city' => '', // 地址所在的城市名
        'ret_coordtype' => 'gcj02ll', // 添加後返回國測局經緯度座標或百度米制座標,(gcj02ll:國測局座標、bd09mc:百度墨卡託座標)
        'sn' => '', // 若用戶所用ak的校驗方式爲sn校驗時該參數必須
    );

    public function __construct()
    {
    }

    /**
     * 重置所有請求參數
     * @param array $config 請求參數
     * @param bool $isSn 是否使用sn校驗
     * @param string $sk
     */
    public function setReqParam($config, $isSn = false, $sk = null)
    {
        if (is_array($config) && !empty($config)) {
            foreach ($config as $key => $val) {
                !empty($val) && $this->reqParam[$key] = $val;
            }
        }

        if ($isSn) {
            $this->isSn = true;
            !empty($sk) && $this->sk = $sk;
        }
    }

    /**
     * 獲取經緯度信息
     * @param null|string $address 詳細地址
     * @param null|string $city 詳細地址所屬城市名,有利於精確返回信息
     * @return bool|mixed 經緯度座標:[... "location":{"lat":"緯度值","lng":"經度值"} ...]
     */
    public function getMap($address = null, $city = null)
    {
        // 設置地址信息
        !empty($address) && $this->reqParam['address'] = $address;
        !empty($city) && $this->reqParam['city'] = $city;

        if ($this->isSn) {
            // 調用sn計算函數,默認get請求
            $queryStringArrays = $this->reqParam;
            unset($queryStringArrays['sn']);
            $this->reqParam['sn'] = self::caculateAKSN($this->reqParam['ak'], $this->sk, self::REQ_URI, $queryStringArrays);
        }

        // 請求數據
        $data = $this->send(self::REQ_URL, $this->reqParam);

        // 處理請求數據
        $data = str_replace('renderOption&&renderOption(', '', $data);
        $data = str_replace(')', '', $data);
        $data = json_decode($data, true);

        // 返回數據
        if (!empty($data)) {
            if ($data['status'] == 0) {
                return $data;
            } else {
                $this->errMsg = $data;
            }
        } else {
            $this->errMsg = '請求出錯了';
        }
        return false;
    }

    /**
     * 返回錯誤信息
     * @return array|string
     */
    public function errMsg()
    {
        return $this->errMsg;
    }

    /**
     * 發送請求
     * @param $url
     * @param $params
     * @return mixed
     */
    private function send($url, $params = null)
    {
        if (!empty($params)) {
            if (is_array($params)) {
                $paramStr = '';

                foreach ($params as $k => $val) {

                    // 請求參數中有中文、特殊字符等需要進行urlencode,確保請求串與sn對應
                    if ($this->isSn && $k != 'sn') {
                        if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $val) > 0) {
                            $val = urlencode($val);
                        }
                    }
                    $paramStr .= "{$k}={$val}&";
                }
                $paramStr = rtrim($paramStr,'&');
            } else {
                $paramStr = $params;
            }
            $url .= (strpos($url, "?") === false ? '?' : '&');
            $url .= $paramStr;
        }

        // 記錄一下url
        $this->errMsg = $url;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // 執行並獲取HTML文檔內容
        $result = curl_exec($ch);

        // 釋放curl句柄
        curl_close($ch);

        return $result;
    }

    /**
     * sn計算函數,默認get請求
     * 百度地圖提供
     * 文檔URL:http://lbsyun.baidu.com/index.php?title=webapi/appendix
     * @param $ak
     * @param $sk
     * @param $url
     * @param $querystring_arrays
     * @param string $method
     * @return string
     */
    private static function caculateAKSN($ak, $sk, $url, $querystring_arrays, $method = 'GET')
    {
        if ($method === 'POST') {
            ksort($querystring_arrays);
        }
        $querystring = http_build_query($querystring_arrays);
        return md5(urlencode($url . '?' . $querystring . $sk));
    }
}

相關參數說明看文檔:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章