最近项目中接到一个需求,需要使用百度地图API和HTML5定位特性。
对于百度地图API,没啥好说的,刨它的API就是了。
今天想说说JS定位特性。
浏览器支持
Internet Explorer 9、Firefox、Chrome、Safari 以及 Opera 支持地理定位。
访问地理位置
地理位置可以在JavaScript中通过浏览器的navigator.geolocation对象访问。
这个对象提供了3个方法:getCurrentPosition,watchPosition,clearWatch
getCurrentPosition(success_callback, error_callback, geolocationOptions)
success_callback,获取定位信息成功时的回调函数
error_callback,获取定位信息失败时的回调函数
geolocationOptions,定位设置,它是一个对象,包含3个属性:
enableHighAccuracy(Boolean型,默认为false,是否尝试更精确地读取纬度和经度,移动设备上,这可能要使用手机上的GPS,这会消耗移动设备更多的电量,定位所需时间也会更长)
timeout(单位为毫秒,默认值为0,在放弃并触发处理程序之前,可以等待的时间----用户选择期间是不计时的)
maximumAge(单位为毫秒,默认值为0。用来告诉浏览器是否使用最近缓存的位置数据,如果在maximumAge内有一个请求,将会返回它,而不请求新位置。maximumAge如果为Infinity,则总是使用一个缓存的位置,如果为0则必须在每次请求时查找一个新位置)
获取定位信息成功时getCurrentPosition()返回一个positon对象给success_callback。此对象包含如下属性:
coords.latitude(十进制数的纬度)
coords.longitude(十进制数的经度)
coords.accuracy(位置精度)
coords.altitude(海拔,海平面以上以米计)
coords.altitudeAccuracy(位置的海拔精度)
coords.heading(方向,从正北开始以度计)
coords.speed(速度,以米/每秒计)
timestamp(响应的日期/时间)
获取定位信息失败时getCurrentPosition()返回一个error对象给error_callback。此对象包含如下属性:
code(错误编码:“1”为用户禁止了定位信息获取,“2”为网络不可用或连接卫星失败,“3”为获取定位所花费的时间过长,“0”为出现未知错误)
message(错误信息)
var x = document.getElementById("demo"); var options = {
enableHighAccuracy: false, timeout: 5000,
maximumAge: 60000 }; function getLocation(){ if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(showPosition, showError, options); }else{ x.innerHTML="Geolocation is not supported by this browser."; } } function showPosition(position){ x.innerHTML = "Latitude: " + position.coords.latitude + "<br />Longitude: " + position.coords.longitude; } function showError(error){ switch(error.code){ case 1: x.innerHTML = "User denied the request for Geolocation."; break; case 2: x.innerHTML = "Location information is unavailable."; break; case 3: x.innerHTML = "The request to get user location timed out."; break; case 0: x.innerHTML = "An unknown error occurred."; break; } }
watchPosition像一个追踪器,返回的位置信息会随着用户移动而改变,与clearWatch成对。
watchPosition与clearWatch有点像setInterval和clearInterval的工作方式。
var watchPositionId = navigator.geolocation.watchPosition(success_callback, error_callback, geolocationOptions);
navigator.geolocation.clearWatch(watchPositionId);
定位功能的主要影响因素
定位功能的使用非常简单,一个对象三个方法。但在工作过程中,发现经常获取不到定位信息。经查找资料得知影响定位功能的主要因素是网络。
定位功能在移动网络环境里,是通过基站定位或者WIFI定位,获取定位信息成功率高,速度快。
若是在物理网络环境里,则有点复杂,首先,浏览器调用其对应的定位服务器的定位接口,然后定位服务器连接卫星,以用户的IP地址进行定位,再将定位信息返回浏览器传给用户。由于涉及浏览器与定位服务器连接是否成功、定位服务器与卫星连接是否成功两方面因素的影响,固定位成功率很难保证。
GPS定位由于信号比较薄弱的关系定位成功率比较低,就算成功定位,需要花费的时间也很长,一般使用GPS定位的同时都会使用基站和WIFI辅助定位。
定位精准度
关于定位精准度问题,由于绝大多数情况下,设备的定位信息是通过WIFI定位方式返回,误差一般在几十米之内。
(因为GPS定位耗时过长一般会被略过,基站定位精准度较低,优先级不如WIFI定位)
而getCurrentPosition的配置参数里的enableHighAccuracy设置为true,仅仅是启用GPS定位,根据GPS定位的特性,应用中使用的机会不多。所以一般都用默认flase就足够了。
关于实际应用的温馨提示
这里,需要和大家分享一下实际工作中遇到的一种情况,那就是百度地图API和html5原生的定位API搭配使用,会导致极大的精准误差的问题。
出现这个问题的原因在于,国内的地图产品,其地理位置大多数都进行了GCJ-02加密,即加入随机的偏差。
而html5原生的定位API获取到的地理位置,是未经加密的。
因此,为了保证html5原生的定位API获取到的地理位置在百度地图上较为准确的解析,就需要用官方提供的转换类。
由于国内地图产品的地理位置普遍进行了GCJ-02加密(身在天朝,没办法,我知道得太多了...)
因此,在用一种地图产品的API时,都应养成一个习惯,就是看看它们有没有提供地理位置信息转换的类。
下面是在百度地图API中的转换实例。
先在项目中引入类<script type="text/javascript" src="http://developer.baidu.com/map/jsdemo/demo/convertor.js"></script>
BMap.Convertor.translate(gpsPoint, 2, callback); //GPS坐标转成百度坐标 BMap.Convertor.translate(bdPoint, 0, callback); //百度坐标转成GPS坐标 var callback = function(point){ //参数point为转换后的point对象,GPS坐标生成的point对象转换成百度坐标point对象,在百度地图里才能解析成更准确的地址 //通过它的lng、lat属性分别获取经、纬度信息 }