文章來源: 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']); } }