地理位置(Geolocation)是 HTML5 的重要特性之一,提供了肯定用户位置的功能,借助这个特性可以开发基于位置信息的应用。今天这篇文章向你们介绍一下 HTML5 地理位置定位的基本原理及各个浏览器的数据精度状况。git
在 访问位置信息前,浏览器都会询问用户是否共享其位置信息,以 Chrome 浏览器为例,若是您容许 Chrome 浏览器与网站共享您的位置,Chrome 浏览器会向 Google 位置服务发送本地网络信息,估计您所在的位置。而后,浏览器会与请求使用您位置的网站共享您的位置。chrome
HTML5 Geolocation API 使用很是简单,基本调用方式以下:json
if (navigator.geolocation) { 浏览器
navigator.geolocation.getCurrentPosition(locationSuccess, locationError,{ 缓存
// 指示浏览器获取高精度的位置,默认为false 服务器
enableHighAcuracy: true, 网络
// 指定获取地理位置的超时时间,默认不限时,单位为毫秒
timeout: 5000,
// 最长有效期,在重复获取地理位置时,此参数指定多久再次获取位置。
maximumAge: 3000
});
}else{
alert("Your browser does not support Geolocation!");
}
locationError为获取位置信息失败的回调函数,能够根据错误类型提示信息:
locationError: function(error){
switch(error.code) {
case error.TIMEOUT:
showError("A timeout occured! Please try again!");
break;
case error.POSITION_UNAVAILABLE:
showError('We can\'t detect your location. Sorry!');
break;
case error.PERMISSION_DENIED:
showError('Please allow geolocation access for this to work.');
break;
case error.UNKNOWN_ERROR:
showError('An unknown error occured!');
break;
}
}
locationSuccess为获取位置信息成功的回调函数,返回的数据中包含经纬度等信息,结合Google Map API 便可在地图中显示当前用户的位置信息,以下:
locationSuccess: function(position){
var coords = position.coords;
var latlng = new google.maps.LatLng(
// 维度
coords.latitude,
// 精度
coords.longitude
);
var myOptions = {
// 地图放大倍数
zoom: 12,
// 地图中心设为指定坐标点
center: latlng,
// 地图类型
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// 建立地图并输出到页面
var myMap = new google.maps.Map(
document.getElementById("map"),myOptions
);
// 建立标记
var marker = new google.maps.Marker({
// 标注指定的经纬度坐标点
position: latlng,
// 指定用于标注的地图
map: myMap
});
//建立标注窗口
var infowindow = new google.maps.InfoWindow({
content:"您在这里<br/>纬度:"+
coords.latitude+
"<br/>经度:"+coords.longitude
});
//打开标注窗口
infowindow.open(myMap,marker);
}
通过测试,Chrome/Firefox/Safari/Opera四个浏览器获取到的位置信息都是一摸同样的,估计都是用的同一个位置服务,数据以下:
位置服务用于估计您所在位置的本地网络信息包括:有关可见 WiFi 接入点的信息(包括信号强度)、有关您本地路由器的信息、您计算机的 IP 地址。位置服务的准确度和覆盖范围因位置不一样而异。
总的来讲,在PC的浏览器中 HTML5 的地理位置功能获取的位置精度不够高,若是借助这个 HTML5 特性作一个城市天气预报是绰绰有余,但若是是作一个地图应用,那偏差仍是太大了。不过,若是是移动设备上的 HTML5 应用,能够经过设置 enableHighAcuracy 参数为 true,调用设备的 GPS 定位来获取高精度的地理位置信息。
原文:http://www.cnblogs.com/lhb25/archive/2012/07/10/html5-geolocation-api-demo.html
navigator.geolocation.getCurrentPosition(on_success, on_error, options);
getCurrentPosition
包含三个参数,前两个为函数名,第三个为一个对象。其中只有第一个是必须的。当你执行上面的 JavaScript 语句后,浏览器一般会弹出一个提示,询问用户是否容许网站跟踪位置信息;同时getCurrentPosition
函数会当即返回。若是用户选择了容许,则会执行上述on_success
函数,这时你才真正获得位置信息(这就是这件事情为何要分两步的缘由——用户须要必定时间才能对请求做出反应,同时地理位置信息可能须要必定时间才能生成,而函数须要当即返回)。
其中error.code
为一个枚举类型,可能的取值以下:
PERMISSION_DENIED
:用户拒绝
POSITION_UNAVAILABLE
:地理位置获取失败(多是用户没网或卫星搜不到等缘由)
TIMEOUT
:地理位置获取超时
而error.message
则为一个能够帮助开发者调试的错误信息(此信息通常不适合直接显示在网页中给用户查看)。
事实上,上述getCurrentPosition
函数还支持第三个可选的参数,是一个 Option Object,一共有三个选项能够设定:
var options = {
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 60000
}
其中timeout
是设定地理位置获取的超时时间(单位为毫秒,用户选择容许的时间不计算在内);而maximumAge
表示容许设备从缓存中读取位置,缓存的过时时间,单位是毫秒,设为0
来禁用缓存读取。若是返回的是缓存中的时间,会在timestamp
中反映出来。
支持 Geolocation API 的浏览器/终端/操做系统:
Firefox 3.5+
Google Chrome 5.0+
Safari 5.0+
Opera 10.60+
Internet Explorer 9.0+
Android 2.0+
iOS 3.0+
Opera Mobile 10.1+
Blackberry OS 6
上周项目不忙,抽时间研究了一下HTML5的geolocation。
在HTML5中,geolocation做为navigator的一个属性出现,它自己是一个对象,拥有三个方法:
- getCurrentPosition
- watchPosition
- clearWatch
具体用法以下:
//判断浏览器是否支持geolocation
if(navigator.geolocation){
// getCurrentPosition支持三个参数
// getSuccess是执行成功的回调函数
// getError是失败的回调函数
// getOptions是一个对象,用于设置getCurrentPosition的参数
// 后两个不是必要参数
var getOptions = {
//是否使用高精度设备,如GPS。默认是true
enableHighAccuracy:true,
//超时时间,单位毫秒,默认为0
timeout:5000,
//使用设置时间内的缓存数据,单位毫秒
//默认为0,即始终请求新数据
//如设为Infinity,则始终使用缓存数据
maximumAge:0
};
//成功回调
function getSuccess(position){
// getCurrentPosition执行成功后,会把getSuccess传一个position对象
// position有两个属性,coords和timeStamp
// timeStamp表示地理数据建立的时间??????
// coords是一个对象,包含了地理位置数据
console.log(position.timeStamp);
// 估算的纬度
console.log(position.coords.latitude);
// 估算的经度
console.log(position.coords.longitude);
// 估算的高度 (以米为单位的海拔值)
console.log(position.coords.altitude);
// 所得经度和纬度的估算精度,以米为单位
console.log(position.coords.accuracy);
// 所得高度的估算精度,以米为单位
console.log(position.coords.altitudeAccuracy);
// 宿主设备的当前移动方向,以度为单位,相对于正北方向顺时针方向计算
console.log(position.coords.heading);
// 设备的当前对地速度,以米/秒为单位
console.log(position.coords.speed);
// 除上述结果外,Firefox还提供了另一个属性address
if(position.address){
//经过address,能够得到国家、省份、城市
console.log(position.address.country);
console.log(position.address.province);
console.log(position.address.city);
}
}
//失败回调
function getError(error){
// 执行失败的回调函数,会接受一个error对象做为参数
// error拥有一个code属性和三个常量属性TIMEOUT、PERMISSION_DENIED、POSITION_UNAVAILABLE
// 执行失败时,code属性会指向三个常量中的一个,从而指明错误缘由
switch(error.code){
case error.TIMEOUT:
console.log('超时');
break;
case error.PERMISSION_DENIED:
console.log('用户拒绝提供地理位置');
break;
case error.POSITION_UNAVAILABLE:
console.log('地理位置不可用');
break;
default:
break;
}
}
navigator.geolocation.getCurrentPosition(getSuccess, getError, getOptions);
// watchPosition方法同样能够设置三个参数
// 使用方法和getCurrentPosition方法一致,只是执行效果不一样。
// getCurrentPosition只执行一次
// watchPosition只要设备位置发生变化,就会执行
var watcher_id = navigator.geolocation.watchPosition(getSuccess, getError, getOptions);
//clearwatch用于终止watchPosition方法
navigator.geolocation.clearWatch(watcher_id);
}
geolocation的使用方法并不复杂,可是其实现原理比较有意思。
经过观察geolocation的使用方法,能够发现这个api能够在用户容许的状况下调用不少系统设备,好比GPS、WIFI、蓝牙等。
W3C对geolocation的定义是这样的:
The Geolocation API defines a high-level interface to location information associated only with the device hosting the implementation, such as latitude and longitude. The API itself is agnostic of the underlying location information sources. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. No guarantee is given that the API returns the device's actual location.
这 里提到了,geolocation的位置信息来源包括GPS、IP地址、RFID、WIFI和蓝牙的MAC地址、以及GSM/CDMS的ID等等。规范 中没有规定使用这些设备的前后顺序,在HTML5的实现中,手机等移动设备固然优先使用GPS定位,而笔记本和部分平板,最准的定位是WIFI,至于网线 上网的台式机,通常就只能使用IP来定位了,这个准确度最低。
在这些方法里,GPS定位最好理解,卫星直接给出定 位数据。而WIFI和IP地址定位,都不是浏览器自己可以实现的。这两种方式都必须将IP地址或 WIFI信号收集到的周围路由信息,上传到某个服务器,由服务器的查询计算位置信息,而后返回给浏览器。那么这些查询服务由谁来提供呢?
首 先来看chrome,很明显,确定是google本身提供的服务。经过chrome自带的抓包方法(chrome://net-internals/) 能够看到,在使用geolocation时,chrome向www.googleapis.com/geolocation/v1/geolocate的 接口发送了请求,因为请求用spdy加密过,因此看不出具体内容,只有一点能够肯定,即wifi上网时,是post方式传数据,而使用网线时,使用的是 get。
firefox使用的也是google的服务,可是和chrome用的接口不一样,这个是https://maps.googleapis.com/maps/api/browserlocation/json
请 求数据是:browser=firefox&sensor=true&wifi=mac:xx-xx-xx-xx-xx- xx%7Cssid:xxxxxxx%7Css:-43&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-43&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-43&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-44&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-60&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-61&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-62&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-63&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-63&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-67&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-74&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-82&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-84&wifi=mac:xx-xx-xx-xx-xx-xx%7Cssid:xxxxxxx%7Css:-85
这个就很清晰了,是周边wifi设备的ssid、mac地址,以及信号强度。(公司网络,路由名和mac地址隐去。)
opera用的也是google的服务,接口url没弄到,不过从ip地址来看,也是google的ip。
对于不支持geolocation的浏览器,原本能够调用google的gears项目提供的接口来查询地理位置,可是该服务目前2011年已经中止,暂时也没有出现更好的替代方案。