| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- <?php
- namespace common\helpers\map;
- use common\helpers\CurlHelper;
- use Yii;
- class QqMapHelper
- {
- const HOST = 'https://apis.map.qq.com'; // 请求域名
- const TYPE_WS = '/ws/'; // api请求类型
- const KEY = 'GKRBZ-GJSKB-DASUY-N7XDN-3SNI7-KHFCK'; // 腾讯地图key
- const SECRET = 'cmQJc7AVEhc3FNoZfSX6WrTvL72Ycf0e'; // 签名密钥
- /**
- * 腾讯地图key
- *
- * @var string
- */
- protected static $key = '';
- /**
- * 签名密钥
- *
- * @var string
- */
- protected static $secret = '';
- /**
- * 获取腾讯地图配置
- *
- * @return void
- */
- protected static function getQQMapConfig()
- {
- $config = Yii::$app->services->setting->platform->get('map');
- self::$key = $config['qq_jsapi_key'] ? $config['qq_jsapi_key'] : self::KEY;
- self::$secret = $config['qq_jsapi_secret'] ? $config['qq_jsapi_secret'] : self::SECRET;
- }
- /**
- * 地址解析(由文字地址到经纬度的转换能力,并同时提供结构化的省市区地址信息)
- * @Author: lun
- * @DateTime: 2023/7/20 0020 14:13
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $address
- * @return mixed
- */
- public static function Geocoder($address)
- {
- static::getQQMapConfig();
- $require = self::TYPE_WS . 'geocoder/v1';
- $url = self::HOST . $require;
- $params['address'] = $address;
- $params['key'] = self::$key;
- $params['sig'] = self::getSign($require, $params);
- $response = CurlHelper::get($url, $params);
- return $response;
- }
- /**
- * 经纬度转为地址
- * @Author: lun
- * @DateTime: 2023/7/21 0021 14:36
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $latitude
- * @param $longitude
- * @return mixed
- */
- public static function ReverseGeocoder($latitude, $longitude)
- {
- static::getQQMapConfig();
- $require = self::TYPE_WS . 'geocoder/v1';
- $url = self::HOST . $require;
- $params['location'] = $latitude . ',' . $longitude;
- // $params['get_poi'] = 1;
- $params['key'] = self::$key;
- $params['sig'] = self::getSign($require, $params);
- $response = CurlHelper::get($url, $params);
- return $response;
- }
- /**
- * 周边搜索(作用于店铺)
- * 示例:https://apis.map.qq.com/ws/place/v1/explore?boundary=nearby(40.040394,116.273523,1000)&policy=1&page_size=10&page_index=1&key=OB4BZ-D4W3U-*****
- * @Author:lun
- * @Date:2025-01-14 14:13
- * @Copyright:copyright(c)2024 广东七件事集团
- * @param $latitude
- * @param $longitude
- * @param $radius
- * @param $auto_extend
- * @return mixed
- */
- public static function explore($latitude, $longitude, $radius = 500, $auto_extend = 1)
- {
- static::getQQMapConfig();
- $require = self::TYPE_WS . 'place/v1/explore';
- $url = self::HOST . $require;
- $params['boundary'] = "nearby({$latitude},{$longitude},{$radius},{$auto_extend})";
- $params['key'] = self::$key;
- $params['sig'] = self::getSign($require, $params);
- // 对所有参数进行URL编码
- foreach ($params as $key => $value) {
- $params[$key] = urlencode($value);
- }
- $response = CurlHelper::get($url, $params, ['x-legacy-url-decode' => 'no']);
- $data['result'] = $response['data'] ?? [];
- return $data;
- }
- /**
- * 周边搜索(作用于路标,此功能相对实用)
- * @Author:lun
- * @Date:2025-01-14 16:27
- * @Copyright:copyright(c)2024 广东七件事集团
- * @param $latitude
- * @param $longitude
- * @param $radius
- * @param $auto_extend
- * @return array|mixed
- */
- public static function here($latitude, $longitude, $radius = 1000, $auto_extend = 1)
- {
- static::getQQMapConfig();
- $require = self::TYPE_WS . 'place/v1/here';
- $url = self::HOST . $require;
- $params['boundary'] = "nearby({$latitude},{$longitude},{$radius},{$auto_extend})";
- $params['key'] = self::$key;
- $params['sig'] = self::getSign($require, $params);
- // 对所有参数进行URL编码
- foreach ($params as $key => $value) {
- $params[$key] = urlencode($value);
- }
- $response = CurlHelper::get($url, $params, ['x-legacy-url-decode' => 'no']);
- $data['result'] = $response['data'] ?? [];
- return $data;
- }
- /**
- * 根据ip获取定位
- * @Author: lun
- * @DateTime: 2023/7/20 0020 14:43
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $ip
- * @return mixed
- */
- public static function Iplocation($ip)
- {
- static::getQQMapConfig();
- $require = self::TYPE_WS . 'location/v1/ip';
- $url = self::HOST . $require;
- $params['address'] = $ip;
- $params['key'] = self::$key;
- $params['sig'] = self::getSign($require, $params);
- $response = CurlHelper::get($url, $params);
- return $response;
- }
- /**
- * 生成get请求签名
- * @Author: lun
- * @DateTime: 2023/7/20 0020 11:44
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $require
- * @param array $params
- * @return string
- */
- public static function getSign($require, array $params)
- {
- $str = $require . '?';
- ksort($params); // 对键进行升序排序
- foreach ($params as $key => $value) {
- $str .= $key . '=' . $value . '&';
- }
- $str = trim($str, '&') . self::$secret;
- return strtolower(md5($str));
- }
- /**
- * 获取距离经纬度最近的地标
- * @Author:lun
- * @Date:2025-01-14 17:44
- * @Copyright:copyright(c)2024 广东七件事集团
- * @param $latitude
- * @param $longitude
- * @return array|mixed
- */
- public static function getNearPlace($latitude, $longitude)
- {
- $places = self::here($latitude, $longitude);// 获取附近的地点
- $current_distance = 0;// 当前距离
- $min_key = 0;// 最小距离的key
- if (!empty($places['result'])) {
- // 腾讯接口返回的_distance(与boundary传入的经纬度的距离,单位:米)参数距离不准确,所以需要重新计算
- foreach ($places['result'] as $key => $place) {
- $distance = self::getDistance($latitude, $longitude, $place['location']['lat'], $place['location']['lng']);
- if ($key == 0) {
- $current_distance = $distance;
- $min_key = $key;
- } else {
- if ($distance < $current_distance) {
- $current_distance = $distance;// 取最小的
- $min_key = $key;
- }
- }
- }
- }
- return $places['result'][$min_key] ?? [];
- }
- /**
- * 计算两个经纬度之间的距离,单位:米
- * @Author:lun
- * @Date:2025-01-14 16:29
- * @Copyright:copyright(c)2024 广东七件事集团
- * @param $lat1
- * @param $lon1
- * @param $lat2
- * @param $lon2
- * @return float|int
- */
- public static function getDistance($lat1, $lon1, $lat2, $lon2) {
- $R = 6371000; // 地球半径,单位为米
- // 将角度转换为弧度
- $lat1 = deg2rad($lat1);
- $lon1 = deg2rad($lon1);
- $lat2 = deg2rad($lat2);
- $lon2 = deg2rad($lon2);
- // 计算纬度和经度的差值
- $dlat = $lat2 - $lat1;
- $dlon = $lon2 - $lon1;
- // 哈弗赛因公式
- $a = sin($dlat/2) * sin($dlat/2) + cos($lat1) * cos($lat2) * sin($dlon/2) * sin($dlon/2);
- $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
- // 计算距离
- $distance = $R * $c;
- return $distance;
- }
- }
|