地图坐标转换(火星、谷歌、百度、腾讯、高德等坐标)

时间:2024-04-15 20:56:35

 

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