文章来源: https://www.jianshu.com/p/c39a2c72dc65?from=singlemessage
利用位置服务获取特定设备和用户之间的距离:
用户位置: 微信H5, 用微信api的方式获取用户当前所在位置, 获取到的是: WGS84 (地理坐标系统)方式的坐标 【目前基本上所有定位空间位置的设备都使用这种坐标系统,例如手机的GPS系统。】
设备位置: 设备所在坐标用的是腾讯api https://lbs.qq.com/tool/getpoint/index.html 获取的坐标
直接计算有误差, 需要转化一下
WGS84转化为腾讯坐标示例:
$lon = \'116.4303894043\'; $lat = \'39.914321899414\'; $a = 6378245.0; $ee = 0.00669342162296594323; $pi = pi(); $res = gps84_To_Gcj02($lat, $lon); var_dump($res); function gps84_To_Gcj02($lat, $lon) { global $a, $ee, $pi; $dLat = transformLat($lon - 105.0, $lat - 35.0); $dLon = transformLon($lon - 105.0, $lat - 35.0); $radLat = $lat / 180.0 * $pi; $magic = sin($radLat); $magic = 1 - $ee * $magic * $magic; $sqrtMagic = sqrt($magic); $dLat = ($dLat * 180.0) / (($a * (1 - $ee)) / ($magic * $sqrtMagic) * $pi); $dLon = ($dLon * 180.0) / ($a / $sqrtMagic * cos($radLat) * $pi); $mgLat = $lat + $dLat; $mgLon = $lon + $dLon; return array($mgLat, $mgLon); } function transformLat($x, $y) { global $pi; $ret = -100.0 + 2.0 * $x + 3.0 * $y + 0.2 * $y * $y + 0.1 * $x * $y + 0.2 * sqrt(abs($x)); $ret += (20.0 * sin(6.0 * $x * $pi) + 20.0 * sin(2.0 * $x * $pi)) * 2.0 / 3.0; $ret += (20.0 * sin($y * $pi) + 40.0 * sin($y / 3.0 * $pi)) * 2.0 / 3.0; $ret += (160.0 * sin($y / 12.0 * $pi) + 320 * sin($y * $pi / 30.0)) * 2.0 / 3.0; return $ret; } function transformLon($x, $y) { global $pi; $ret = 300.0 + $x + 2.0 * $y + 0.1 * $x * $x + 0.1 * $x * $y + 0.1 * sqrt(abs($x)); $ret += (20.0 * sin(6.0 * $x * $pi) + 20.0 * sin(2.0 * $x * $pi)) * 2.0 / 3.0; $ret += (20.0 * sin($x * $pi) + 40.0 * sin($x / 3.0 * $pi)) * 2.0 / 3.0; $ret += (150.0 * sin($x / 12.0 * $pi) + 300.0 * sin($x / 30.0 * $pi)) * 2.0 / 3.0; return $ret; }
腾讯:逆地址解析(坐标位置描述)
https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder
坐标转换: https://lbs.qq.com/service/webService/webServiceGuide/webServiceTranslate
坐标拾取器: https://lbs.qq.com/tool/getpoint/index.html
<?php namespace Main\Module\Common; use KIF\Core\Config; use KIF\Curl; use KIF\Data\ResultWrapper; /** * 腾讯地图API */ class LbsQQ { const API = \'https://apis.map.qq.com\'; /** * 根据坐标 返回 地区信息 * @param $lon * @param $lat * @return ResultWrapper * @throws \Exception */ static public function getAddressByLocation($lon, $lat){ $api = \'/ws/geocoder/v1/\'; $data = [ \'location\' => $lat.\',\'.$lon, \'get_poi\' => 0, ]; $rs = self::request($api, $data); return $rs; } /** * 签名 * @param $api * @param array $data * @return array * @throws \Exception */ static protected function sign($api, $data = []){ $lbs = Config::getInstance()->get(\'lbs_qq\'); $app_id = $lbs[\'AppID\']; $app_key = $lbs[\'AppKey\']; $data[\'key\'] = $app_id; //签名步骤一:按字典序排序参数 ksort($data); //签名步骤二:生成签名字符串 在string后加入KEY $buffs = array(); foreach ($data as $k => $v) { if($v===\'\'){ continue; } if(is_array($v)){ $v = json_encode($v); } $buffs[] = $k.\'=\'.$v; } $string = $api.\'?\'.implode(\'&\', $buffs).$app_key; //签名步骤三:MD5加密 $string = md5($string); $data[\'sig\'] = $string; return $data; } /** * @param $api * @param $data * @return ResultWrapper * @throws \Exception */ static protected function request($api, $data){ $data = self::sign($api, $data); $api = self::API.$api.\'?\'.http_build_query($data); $objCurl = new Curl($api); $rs = $objCurl->get(); if (!$rs){ return ResultWrapper::fail(\'请求失败\'); } $rs = json_decode($rs, true); if ($rs[\'status\']!==0){ return ResultWrapper::fail(\'ERROR[\'.$rs[\'status\'].\']:\'.$rs[\'message\']); } return ResultWrapper::success($rs[\'result\']); } }