摸鱼日记2 定位测试

一、定位的思路

因为毕设想做的内容和定位必不可分,所以配置好服务器后,第一件尝试的就是html的定位,从网页端获取使用者的位置信息。这个功能本以为应该不难,因为日常使用手机网页访问时经常会出现网页希望获取您的位置这类的提示。事实上这里卡了两三天,代码是一方面,另一方面是一些思路的细节。

二、定位的代码实现

想要定位,主要有两类方法,一种是利用html5自带的定位接口,另一种是利用地图软件的接口。

对于第一种方法,需要使用navigator.geolocation.getCurrentPosition方法,这种方法使用手机的定位服务,先放代码:

function getLocation(){
    
    
    var options = {
    
    
      enableHighAccuracy: true,
      timeout: 5000,
      maximumAge: 0
    };
    if (navigator.geolocation){
    
     //用浏览器获取坐标地址
      navigator.geolocation.getCurrentPosition(showPosition,showError,options);
    }else{
    
    
      alert("浏览器不支持地理定位。");
    }
  }

  //获取浏览器GPS成功
  function showPosition(position){
    
    
    var x = position.coords.longitude; //经度
    var y = position.coords.latitude;//纬度
    //alert(x+" "+y);
    transTypesParam = getTransType(position.coords.accuracy);
    showMap(x, y, true);
  }

  function showError(error){
    
    
    alert('定位失败:'+this.getStatus());
  }

其中最重要的是下面这一行代码:

navigator.geolocation.getCurrentPosition(showPosition,showError,options);

这个接口有三个参数项,会根据是否调用地理位置成功选择对应的回调函数,成功时选择showPosition函数,而失败时调用showError函数,option是对调用的一些细节设置,包括精度之类的内容。
定位成功时就可以利用成功后的参数获得经纬度,之后将这个地理位置放到地图软件的显示接口里就可以了。
这种方法好处是精准,但是首先要求服务器必须是https协议,就是这一点卡住了,因为配置的服务器时http协议,安全性达不到要求,所以需要给服务器配置https,又挖一个坑。而且根据网上查的资料,可能谷歌浏览器会因为不可抗因素导致定位失败。

另一种是用地图软件的接口,随便哪个主流的地图软件,百度地图、高德地图这类的都有这种服务。先去官方申请一个密钥,之后再网页中加入引用的代码:

<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=申请的密钥"></script>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.0&type=webgl&ak=申请的密钥"></script>

这里我引用了两个,也是当初踩的坑。因为采用了百度地图的接口,百度地图大家都用过,现在的百度地图是可以3D浏览的,3D浏览就需要使用WebGL技术,针对这个技术百度地图后来又开发的接口就是上面的第二个,现在官网的开发文档也是推荐这个,因为向上兼容。而第一个是不支持WebGL的接口的最新一个版本,现在百度上搜到的代码都是这个接口的,因为大多数代码没有用到3D显示,2D的已经足够。实际测试发现最好还是用2D的,3D的在显示地图时虽然显得高大上但是效果上实在是一言难尽。实现代码如下:

var map = new BMapGL.Map("显示地图容器的ID"); 
  //var point = new BMapGL.Point(116.331398,39.897445);
  var geolocation = new BMap.Geolocation();
  geolocation.getCurrentPosition(function(r){
    
    
    if(this.getStatus() == BMAP_STATUS_SUCCESS){
    
    
      var mk = new BMapGL.Marker(r.point);
      map.addOverlay(mk);
      map.centerAndZoom(r.point,17);
      map.panTo(r.point);
      //map.setHeading(64.5);   
      //map.setTilt(73);     
    }else {
    
    
      alert('failed'+this.getStatus());
    }
  });

这段代码就是用百度接口获取地理位置,这种方法可以看出很简洁,首先获得要显示地图的html容器,之后所有获得的数据都是要放在这个容器中的。geolocation用来获取位置,和前面html5的获取思路一样,也是根据是否获取成功使用不同的回调函数,这里返回的是一个状态码,状态码如下:

//BMAP_STATUS_SUCCESS        检索成功。对应数值“0”。
//BMAP_STATUS_CITY_LIST        城市列表。对应数值“1”。
//BMAP_STATUS_UNKNOWN_LOCATION        位置结果未知。对应数值“2”。
//BMAP_STATUS_UNKNOWN_ROUTE        导航结果未知。对应数值“3”。
//BMAP_STATUS_INVALID_KEY        非法密钥。对应数值“4”。
//BMAP_STATUS_INVALID_REQUEST        非法请求。对应数值“5”。
//BMAP_STATUS_PERMISSION_DENIED        没有权限。对应数值“6”。(自 1.1 新增)
//BMAP_STATUS_SERVICE_UNAVAILABLE        服务不可用。对应数值“7”。(自 1.1 新增)
//BMAP_STATUS_TIMEOUT        超时。对应数值“8”。(自 1.1 新增)

根据对应的状态码,我们可以进行不同的操作,其实最主要的还是编写成功情况的处理方法。这里就需要参考百度地图的开发文档,里面的方法很多,这里也是里面很基础的操作,先根据获取的经纬度建立一个标志点,将这个标志点放在地图上,这样才能更好地表示你的位置,之后移动到经纬度所代表的位置上,设定好显示的比例尺大小,代码中注释的那两行就是利用WebGL来显示的3D效果,因为显示太花哨就去掉了。

这种方法个人感觉精度上很是个问题,测试了好几台手机,两台小米手机在给了定位权限之后能够成功定位,这里没有采用https却可以采用地理定位,个人猜测是小米隐私保护里面的具体实现上有差异,同样一部小米手机,采用系统自带的浏览器,打开网页设置之后可以看到获取位置是询问,也就是第一次访问时询问是否允许,而安装其他浏览器都是不可修改的状态,这里存疑,我也没搞明白。还测了一台华为,华为无论是否开启位置服务,都无法使用html自带的定位,只能用百度接口,但是偏差特别大,用iPad的chrome和Safari也是这种情况。
我又后续跟着多测了几次,我猜测大多数浏览器对http协议的地理位置获取都是不允许的,小米浏览器是个个例,在采用百度接口时,实际上也是一个混合的获取地址方式,会使用gps、无线网络、数据网络综合获取地理位置,在gps获取失败的情况下采用剩下两种方法补充,在测试过程中,对于不能获取gps的设备,如果连接了手机热点,都会定位到青岛,这里也许是因为手机的流量卡是青岛办的,如果将连接换成家里的无线,定位的位置就马上转换到潍坊,但是偏差很大。现在的猜测是在获取失败时,根据IP地址或者运营商信息来定位,这样的定位偏差就很大了。当然这些全都是猜测,因为不知道接口内部细节,现在也没办法解决。

三、后序修改计划

现在基本是处在一个卡住的状态,大多数手机都没办法精确定位,不使用gps,其他方法偏差简直离谱,所以下一步只能接着动服务器,去申请一下安全证书,将服务器换上https,这样也许就可以解决问题。

猜你喜欢

转载自blog.csdn.net/weixin_43849505/article/details/113799155