一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

php版微信JS-SDK地理位置与腾讯地图API实例

时间:2016-05-08 编辑:简简单单 来源:一聚教程网

根据前面几个地理位置教程,最终把腾讯地图的Web Service API 写完善的类,call不同接口时,注意不同的参数,因为每个差数都稍有不同,是直接影响到显示结果,所以详细请查看官方的文档 Web Service API文档
继续以TP为框架给代码和实例效果!
QQMapModel类:
namespace Home\Model;
class QQMapModel {
    const
        SEARCH_API = 'http://apis.map.qq.com/ws/place/v1/search',
        SUGGESTION_API = 'http://apis.map.qq.com/ws/place/v1/suggestion',
        GEOCODER_API = 'http://apis.map.qq.com/ws/geocoder/v1',
        LIST_API = 'http://apis.map.qq.com/ws/district/v1/list',
        TRANSLATE_API = 'http://apis.map.qq.com/ws/coord/v1/translate',
        PANO_API = 'http://apis.map.qq.com/ws/streetview/v1/getpano';
 
    public
        $error_number, $error, $appKey;
 
    protected static
        $_instance;
 
    static public function getInstance(array $options = array()) {
        if (empty(self::$_instance)) {
            self::$_instance = new static($options);
        }
        return self::$_instance;
    }
 
    public function __construct(array $options = array()) {
        if(count($options))
            $this->appKey = $options['appkey'];
    }
 
    public function call($url, array $params = array(), $format_result = true) {
        $param = array_merge(array('key' => $this->appKey), $params);
        $url = $url.'?'.http_build_query($param);
        $ch = curl_init($url);
        curl_setopt_array($ch, array(
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_AUTOREFERER => 1,
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_VERBOSE => 1,
        ));
        $res = curl_exec($ch);
        $this->error_number = curl_errno($ch);
        $this->error = curl_error($ch);
        if (curl_errno($ch)) {
            return false;
        }
        curl_close($ch);
        return ($format_result ? $this->parseResult($res) : $res);
    }
 
    protected function parseResult($res) {
        $res = json_decode($res, true);
        if ($res['status'] !== 0) {
            $this->error_number = $res['status'];
            $this->error = $res['message'];
            return false;
        }
        return $res;
    }
 
    //取街景图接口
    public function streetImage($pano, $otherParam = array()) { //max 960x640
        $param = array(
            'size' => '620x380',
            'pano' => $pano,
            'heading' => 0,
            'pitch' => 0,
            'key' => $this->appKey,
        );
        if(count($otherParam))
            $param = array_merge($param, $otherParam);
        return 'http://apis.map.qq.com/ws/streetview/v1/image?' . http_build_query($param);
    }
 
    //新静态图v2接口
    public function staticMap($point, $otherParam = array()) {
        $param = array(
            'size' => '620*380',
            'center' => $point,
            'zoom' => 13,
            'format' => 'png',
            'maptype' => 'roadmap',
            'markers' => $point,
            'key' => $this->appKey,
        );
        if(count($otherParam))
            $param = array_merge($param, $otherParam);
        return 'http://apis.map.qq.com/ws/staticmap/v2/?' . http_build_query($param);
    }
 
    //旧静态图v1版接口 $point参数 先经度再纬度与上面的相反
    public static function mapImage($point, $otherParam = array()) {
        $param = array(
            'size' => '620*380',
            'center' => $point,
            'zoom' => 13,
            'format' => 'png',
            'markers' => $point,
        );
        if(count($otherParam))
            $param = array_merge($param, $otherParam);
        return 'http://st.map.qq.com/api?' . http_build_query($param);
    }
}
ImageCacheModel类新封装一个缓存图片方法:
public static function getApiImg($points, $search, $slug = 'marker') {
        $fileName = md5($points);
        self::$FULL_CACHE_DIR = C('PUBLIC_FULL_DIR') . self::CACHE_DIR;
        $cacheImg = self::$FULL_CACHE_DIR . '/' . $fileName . self::$TYPE;
        if (file_exists($cacheImg)) {
            return self::CACHE_DIR . $fileName . self::$TYPE;
        } else {
            $map = QQMapModel::getInstance(array(
                'appkey' => 'CZQBZ-RC53V-2RQPX-UFNBE-VDH2J-DFBFJ'
            ));
            $res = $map->call(QQMapModel::SEARCH_API, array(
                'keyword' => $search,
                'boundary' => "nearby($points,1000)"
            ));
            if ($res) {
                $imageUrl = '';
                switch($slug) {
                    case 'marker' :
                        $label = array();
                        foreach ($res['data'] as $data) {
                            //API要求标题不要长过13字符
                            $label[] = mb_substr($data['title'], 0, 13, 'utf-8') . '|' . $data['location']['lat'] . ',' . $data['location']['lng'];
                        }
                        $labels = implode('|', $label);
                        $labels = 'border:1|size:10|color:brown|bgcolor:orange|' . $labels;
                        $imageUrl = $map->staticMap($points, array('labels' => $labels, 'zoom' => 15));
                        break;
                    case 'label' :
                        $marker = array();
                        foreach($res['data'] as $data) {
                            $lat = $data['location']['lat'];
                            $lng = $data['location']['lng'];
                            $marker[] = $lat.','.$lng;
                        }
                        $markers = implode('|', $marker);
                        $markers = 'color:blue|label:H|'.$markers;
                        $imageUrl = $map->staticMap($points, array('markers' => $markers, 'zoom' => 15));
                        break;
                }
                if($imageUrl) {
                    self::saveCacheImg($imageUrl, $fileName);
                    return self::CACHE_DIR . $fileName . self::$TYPE;
                }
            }
        }
        return self::CACHE_DIR.'default'.self::$TYPE;
    }
上面段代码,我主要调用了search接口,并根据参数让生成的地图是图标还是标签文字来显示。

Controller里加入跳转的URL:(因为Layout与之前差不多,这里就不写了)
    public function apimapAction() {
        layout('Layout/apimap');
        $this->display();
    }
 
    public function maphotelAction() {
        layout(false);
        if(I('pos','')) {
            $target = ImageCacheModel::getApiImg(I('pos'),'酒店','marker');
            $url = __ROOT__.$target;
            redirect($url);
        }
    }
 
    public function mapfoodAction() {
        layout(false);
        if(I('pos','')) {
            $target = ImageCacheModel::getApiImg(I('pos'), '美食', 'label');
            $url = __ROOT__.$target;
            redirect($url);
        }
    }
目前Web Service API提供了6个接口,包括根据地址解析或者逆解析,还有坐标转换,我做测试时发现腾讯上的经纬度转成百度后还是编差太大,似乎不同地图API间的经纬度转没什么意义。这些接口就由你们来试了,一通百通~

以酒店查询标签文本的效果图:


labels-map

 

以美食小图标的效果图:
marker-map

热门栏目