Press "Enter" to skip to content

PHP调用百度地图公交路线规划API的流程和踩坑

最近做一个项目需要用到百度地图公交线路规划,于是分享一下。

一、申请API的权限

申请成功后在控制台会得到百度地图API的ak码。由于我选择的请求校验方式是sn校验方式,所以还有一个sk码。

二、使用PHP发起请求

本次示范的是请求公交路线规划api(GET请求) 

http://api.map.baidu.com/direction/v2/transit?origin=40.056878,116.30815&destination=31.222965,121.505821&ak=您的AK

参考文档:

http://lbsyun.baidu.com/index.php?title=webapi/direction-api-v2

PHP代码如下:

    // 获取公交路线
    public function gettransit() {
        //API控制台申请得到的ak(此处ak值仅供验证参考使用)
        $ak = 'yourak';

        //应用类型为for server, 请求校验方式为sn校验方式时,系统会自动生成sk,可以在应用配置-设置中选择Security Key显示进行查看(此处sk值仅供验证参考使用)
        $sk = 'yoursk';

        //get请求uri前缀
        $uri = '/direction/v2/transit';



        //起点坐标(必填)
        $origin = '22.693621,113.817503';

        //终点坐标(必填)
        $destination = '22.579575,114.143696';

        //已知起点的名字(选填)
        $origin_uid = '桥头-地铁站';
        
        //已知终点的名字(选填)
        $destination_uid = '太安-地铁站';
        
        //出发时间区间(选填)
        $departure_time = '10:00-12:00';
        
        //市内公交换乘策略(地铁优先,选填)
        $tactics_incity = 5;

        //时间戳(接口选择sn检验方式时必须)
        $timestamp = time();

        //构造请求串数组(除了$sk、$uri参数外全部要填入)
        $querystring_arrays = array (
            'origin' => $origin,
            'destination' => $destination,
            'origin_uid' => $origin_uid,
            'destination_uid' => $destination_uid,
            'departure_time' => $departure_time,
            'tactics_incity' => $tactics_incity,
            'timestamp' => $timestamp,
            'ak' => $ak
        );

        //调用sn计算函数,默认get请求
        $sn = $this->caculateAKSN($ak, $sk, $uri, $querystring_arrays);

        //以transit服务为例,地理编码的请求url,参数待填
        $url = "http://api.map.baidu.com/direction/v2/transit?origin=%s&destination=%s&origin_uid=%s&destination_uid=%s&departure_time=%s&tactics_incity=%s&ak=%s&sn=%s&timestamp=%s";

        //请求参数中有中文、特殊字符等需要进行urlencode,确保请求串与sn对应
        $target = sprintf($url,urlencode($origin),urlencode($destination),urlencode($origin_uid),urlencode($destination_uid),urlencode($departure_time), $tactics_incity,$ak, $sn, $timestamp);

        //获取请求结果
        $result = $this->httpto("$target",'','GET');
        $result = json_decode($result);
        //返回请求结果json
        return response()->json($result);
    }




    // 计算sn
    private 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请求
    function httpto($url, $params, $method = 'GET', $header = array(), $multi = false) {
        $opts = array(
            CURLOPT_TIMEOUT        => 30,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER     => $header
        );
        /* 根据请求类型设置特定参数 */
        switch(strtoupper($method)){
            case 'GET':
                $opts[CURLOPT_URL] = $url;
                break;
            case 'POST':
                //判断是否传输文件
                $params = $multi ? $params : http_build_query($params);
                $opts[CURLOPT_URL] = $url;
                $opts[CURLOPT_POST] = 1;
                $opts[CURLOPT_POSTFIELDS] = $params;
                break;
            default:
                throw new Exception('不支持的请求方式!');
        }
        /* 初始化并执行curl请求 */
        $ch = curl_init();
        curl_setopt_array($ch, $opts);
        $data  = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        if($error) throw new Exception('请求发生错误:' . $error);
        return $data;
    }

三、踩坑提示

问题:曾在完成接口后,测试接口遇到 {“status”:2,”message”:”参数错误”} 的报错,本人检查坐标也无异常,符合默认的报读bd09II坐标标准,问题出现在哪里呢?

解决方式:经过细心琢磨后,发现请求参数的origin、destination是使用(纬度,经度)的方式,并不是我们日常认知的(经度,纬度)的方式,所以说这是一个坑,稍不注意就出错。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注