国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > 关于百度地图GPS/IP定位的相关说明

关于百度地图GPS/IP定位的相关说明

来源:程序员人生   发布时间:2016-12-20 16:13:35 阅读次数:3091次

摘要:关于定位,分为GPS定位和网络定位2种。GPS定位,精度较高,可到达10米,但室内不可用,且超级费电。网络定位,分为wifi定位和基站定位,都是通过获得wifi或基站信息,然后查询对应的wifi或基站位置数据库,得到的定位地点。定位数据库可以不断完善不断补充,所以,越定位越准确。

1、常见的定位:

 ①GPS全球定位。

常见的GPS定位的原理可以简单这样理解:由24颗工作卫星组成,使得在全球任何地方、任什么时候间都可观测到4颗以上的卫星, 丈量出已知位置的卫星到用户接收机之间的距离,然后综合多颗卫星的数据便可知道接收机的具体位置。
在露天环境下效果较好,获得位置信息非常精确。合适移动装备。
缺点:在地铁等位置效果较差

 ②IP地址定位。

适用于接入互联网的装备,通过阅读器是将位置信息发送给 ISP 服务商来解析,其IP 地址与服务商所在位置有关,可能与用户所在位置不同,所以这类方式的解析容易出现偏差。
另外,由于国内大部份的省都是以省级为单位划分基站对外访问 IP ,也就是说,一样1个出口 IP,后面的对利用户
多是跨多个城市的。也有1部份省是依照市1级为单位划分的,但是位置偏僻。
备注:IP定位很方便,但是数据不准,需要及时更新,有很多商业化的服务。

 ③WiFi定位。

装备只要侦听1下附近都有哪些热门,检测1下每一个热门的信号强弱,然后把这些信息发送给网络上的服务端。服务器根据这些信息,查询每一个热门在数据库里记录的坐标,然落后行运算,就可以知道客户真个具体位置了。1次成功的定位需要两个先决条件:客户端能上网 ,侦听到的热门的坐标在数据库里有。

优点:这类方式与GPS效果一样精确,适用于室内环境的移动装备。
缺点:
你的这个wifi信号,如果在数据库中没有被记录在案,那就没法定位了。比如,如果你买了个新的无线路由器,靠它肯定是没法帮助你的移动装备定位的
数据更新有延迟,WIFI覆盖其实不大
原理说明:当你的移动装备需要使用wifi定位的时候,它会搜索周围的wifi信号,同时在数据库中搜索,得到地理位置的数据,加上定位提供商搜集的海量数据,能够构建出信号的“指纹”,比基站定位更精准。

④基站定位

我们把手机基站的覆盖范围想像成1个个以基站为圆心的圆,需要定位时,手机就向周边多座基站发送丈量信号,并计算这些丈量信号到达基站所需要的时间,推算出手机距离基站的直线距离,再经过数学运算,手机位置坐标便可由3个基站圆的交点来肯定。
优点:LBS定位的优势是方便、本钱低,由于它是通过手机进行定位的。理论上说,只要计算3个基站的信号差异,就能够判断出手机所在的位置,而且用户所持终端只需1部手机便可。因此,只要用户手机有信号,就能够随时进行位置定位,而不受天气、高楼、位置等影响。
缺点:定位精度随所处位置基站数不同会有变化。
百度地图等在web开发时其实不提供相干api

2、测试结果:

初步得到的结果:GPS>单点WiFi>基站>IP
  1. GPS和WIFI相对测试的结果较好。
  2. 局限性:WIFI效果较好,但是局限性很大。基站定位在web开发时比较麻烦
  3. 目前比较好的方式,就是读取GPS的相干信息(比如经纬度等等),再做进1步操作。
  4. 在精准度要求比较高的情况下,其实不推荐使用ip定位。ip定位好处是:其实不需要用户授权,方便。

3、业务说明:以百度地图为例

APP开发的话

百度定位sdk,综合了wifi定位、基站定位等(混合定位)

web开发的话

  1. 阅读器定位
    阅读器定位插件,封装了标准HTML5定位,并且包括纠偏模块。
    html5定位:拿到的是GPS的数据,定位准确
    备注:获得经纬度数据,想取得地址,需要纠偏,再使用接口取得。
    参考地址:http://www.w3school.com.cn/html5/html_5_geolocation.asp
    鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的。
    Internet Explorer 9、Firefox、Chrome、Safari 和 Opera 支持地理定位。
    注释:对具有 GPS 的装备,比如 iPhone,地理定位更加精确。
    另外,阅读器定位插件也是混合定位,获得了wifi、基站信息用以定位,对具有 GPS 的装备,比如 iPhone,由于取得GPS信息,使得地理定位更加精确。
    ★阅读器定位,最好使用在手机阅读器上,会更加准确,也更加符合使用处景。PC阅读器上,建议使用IP定位。
    demo :http://developer.baidu.com/map/jsdemo.htm#i8_1

  2. ip定位
    通过网络获得IP信息,然后查询IP数据库,获得相应的地址信息。
    IP数据库也是可以完善补充,愈来愈丰富的,所以也是越使用越准确的。
    但如果IP有跳转,有篡改等,那末IP定位就会不准确了。
    demo:http://developer.baidu.com/map/jsdemo.htm#i8_2

  3. web接口
    嫌开发不方便,可以直接调用web接口,体验更快,缺点是次数限制。

    关于JSAPI/webAPI的小小说明
    1、js是阅读器端,而web是服务端。
    2、在使用上Web更简单,若只想使用服务,直接通过调用接口获得结果的话,并且需求量其实不大的 时候,建议使用web。(百度js调用次数不限)
    3、想展现地图,或超过接口限制,比较复杂的web开发,想要的功能并没有提供相应的接口,会需要用到js。
    

在微信中使用

援用微信js便可使用

给的接口只有两类,1类是用内置阅读器(使用其实不多),1类是得到想要的配置

示例1:使用微信内置地图查看位置接口
wx.openLocation({
    latitude: 0, // 纬度,浮点数,范围为90 ~ ⑼0
    longitude: 0, // 经度,浮点数,范围为180 ~ ⑴80。
    name: '', // 位置名
    address: '', // 地址详情说明
    scale: 1, // 地图缩放级别,整形值,范围从1~28。默许为最大
    infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
});

示例2:获得地理位置接口
wx.getLocation({
    type: 'wgs84', // 默许为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
    var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ ⑼0
    var longitude = res.longitude; // 经度,浮点数,范围为180 ~ ⑴80。
    var speed = res.speed; // 速度,以米/每秒计
    var accuracy = res.accuracy; // 位置精度
    }
});

4、其他说明

1. 特殊说明:
1. 通过百度jsapi测试结果看,通过ip定位城市效果也会存在比较大的误差,更别提精肯定位。但是只要数据库足够丰富,定位结果会准确的多,但是本钱会特别高。如:https://www.ipip.net/ip.html
2. 对GPS坐标转换成使用百度api需要转换百度坐标(纠偏)

2、自己写的参考demo (ak需要自己申请)
1. js版(利用html5定位,再调用百度api,调用次数不限)
好处:去除地图展现等1些功能,直接显示位置。

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf⑻" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <script type="text/javascript" src="http://www.wfuyu.com/upload/caiji/20160922/http://api.map.baidu.com/api?v=2.0&ak=xxx"></script>
    <title>我要定位</title>
</head>
<body>
<p id="demo">点击这个按钮,取得您的坐标:</p>
<button onclick="getLocation()">试1下</button>
<script>
    // 检测阅读器是不是支持HTML5
    function supportsGeoLocation(){
        // return !!navigator.geolocation;
    }
    // 单次位置要求履行的函数
    function getLocation(){
        navigator.geolocation.getCurrentPosition(mapIt,locationError);
    }
    //定位成功时,履行的函数
    function mapIt(position){
        var lon = position.coords.longitude;
        var lat = position.coords.latitude;
        //var url = 'http://api.map.baidu.com/geoconv/v1/?coords='+lon+','+lat+'&from=1&to=5&ak=xxx&output=json';
        //alert("您位置的经度是:"+lon+" 纬度是:"+lat);
        var map = new BMap.Map("");
        var point = new BMap.Point(lon,lat);
        translateCallback = function (data){
            if(data.status === 0) {
                var geoc = new BMap.Geocoder();
                geoc.getLocation(data.points[0], function(rs){
                    var addComp = rs.addressComponents;
                    alert(addComp.province + ", " + addComp.city + ", " + addComp.district + ", " + addComp.street + ", " + addComp.streetNumber);
                });
            }
        }
        var convertor = new BMap.Convertor();
        var pointArr = [];
        pointArr.push(point);
        convertor.translate(pointArr, 1, 5, translateCallback);
    }
    // 定位失败时,履行的函数
    function locationError(error)
    {
        alert('定位失败');
        return false;
    }
</script>
</body>
</html>

2.web要求,这个比较简单,直接根据经纬度调用接口。
好处:少1次调用

        <?php
        /**
         * Created by PhpStorm.
         * User: Administrator
         * Date: 16⑵⑷
         * Time: 下午4:34
         */
        class map
        {
            private static $_instance;

            const REQ_GET = 1;
            const REQ_POST = 2;

            /**
             * 单例模式
             * @return map
             */
            public static function instance()
            {
                if (!self::$_instance instanceof self)
                {
                    self::$_instance = new self;
                }
                return self::$_instance;
            }

            /**
             * 履行CURL要求
             * @param $url
             * @param array $params
             * @param bool $encode
             * @param int $method
             * @return mixed
             */
            private function async($url, $params = array(), $encode = true, $method = self::REQ_GET)
            {
                $ch = curl_init();
                        if ($method == self::REQ_GET)
                {
                    $url = $url . '?' . http_build_query($params);
                    $url = $encode ? $url : urldecode($url);
                    curl_setopt($ch, CURLOPT_URL, $url);
                }
                else
                {
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_POST, true);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
                }
                curl_setopt($ch, CURLOPT_REFERER, 'http://map.baidu.com/');
                curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53');
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                $res = curl_exec($ch);
                curl_close($ch);
                return $res;
            }

            /**
             * ip定位
             * @param string $ip
             * @return array
             * @throws Exception
             */
            public function locationByIP($ip)
            {
                //检查是不是合法IP
                if (!filter_var($ip, FILTER_VALIDATE_IP))
                {
                    throw new Exception('ip地址不合法');
                }
                $params = array(
                    'ak' => 'xxx',
                    'ip' => $ip,
                    'coor' => 'bd09ll'//百度地图GPS坐标

                                                    );
                $api = 'http://api.map.baidu.com/location/ip';
                $resp = $this->async($api, $params);
                $data = json_decode($resp, true);
                //有毛病
                if ($data['status'] != 0)
                {
                    throw new Exception($data['message']);
                }
                //返回地址信息
                return array(
                    'address' => $data['content']['address'],
                    'province' => $data['content']['address_detail']['province'],
                    'city' => $data['content']['address_detail']['city'],
                    'district' => $data['content']['address_detail']['district'],
                    'street' => $data['content']['address_detail']['street'],
                    'street_number' => $data['content']['address_detail']['street_number'],
                    'city_code' => $data['content']['address_detail']['city_code'],
                    'lng' => $data['content']['point']['x'],
                    'lat' => $data['content']['point']['y']
                );
            }
            /**
             * GPS定位
             * @param $lng
             * @param $lat
             * @return array
             * @throws Exception
             */
            public function locationByGPS($lng, $lat)
            {
                $params = array(
                    'coordtype' => 'wgs84ll',
                    'location' => $lat.','.$lng,
                    'ak' => 'xxx',
                    'from'  => 1,
                    'to'    => 5,
                    'output' => 'json',
                                                      );
                $resp = $this->async('http://api.map.baidu.com/geocoder/v2/', $params, false);
                $data = json_decode($resp, true);
                if ($data['status'] != 0)
                {
                    throw new Exception($data['message']);
                }
                return array(
                    'address' => $data['result']['formatted_address'],
                    'province' => $data['result']['addressComponent']['province'],
                    'city' => $data['result']['addressComponent']['city'],
                    'street' => $data['result']['addressComponent']['street'],
                    'street_number' => $data['result']['addressComponent']['street_number'],
                    'city_code'=>$data['result']['cityCode'],
                    'lng'=>$data['result']['location']['lng'],
                    'lat'=>$data['result']['location']['lat']
                );
            }

5、参考资料和网站

  1. https://www.zhihu.com/question/21063874
  2. http://h-notes.com/notes/RVhVZVNJF1t9RFdZ/20160128/NRl5NZ1Zhp1ddVBthFtdxxh1NlpVttldh1hhtdBB5VBhxhh51RZ51V1x51V1Bx5t/index.html
  3. 百度开发平台:http://lbsyun.baidu.com/
  4. 微信开发者文档:http://mp.weixin.qq.com/wiki/home/index.html
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生