获取位置信息:
- 请求一个位置信息,如果用户同意,浏览器就会返回位置信息(由经纬度和其他元数据组成),该信息是通过支持html5地理定位功能的底层设备提供给浏览器的;该API不指定设备用哪种底层技术来定位,所以,返回的元数据不确定;同时不能保证设备返回的实际位置是精确的;
- 数据源:
- IP地址地理定位:自动查找ip地址,然后检索其注册的物理地址;//许多网站会根据ip地址的信息来做广告;
- 优点:任何地方都可以在服务器端处理;
- 缺点:不精确,一般精确到城市级;运算代价大;
- GPS地理定位:通过搜集运行在地球周围的多个gps卫星的信号实现的;
- 优点:很精确
- 缺点:定位时间长,室内效果不好,需要额外硬件设备;
- wifi地理定位:通过三角距离计算(用户当前位置到已知的多个wifi接入点的距离)得出的;
- 优点:精确,可以在室内使用;可以简单,快捷定位;
- 缺点:在乡村这些无线接入点较少的地区效果不好;
- 手机地理定位:通通过用户到一些基站的三角距离确定;
- 优点:相当准确,可以在室内使用,可以简单,快捷定位;
- 缺点:需要能够访问手机或其他moden的设备;
- 用户自定义地理定位:通过编程计算出用户的位置或用户自定义位置
- 优点:用户可以获得比程序定位服务更精确的位置数据;允许地理定位服务的结果作为备用位置信息;
- 缺点:可能不准确,特别是当用户位置变更后;
- IP地址地理定位:自动查找ip地址,然后检索其注册的物理地址;//许多网站会根据ip地址的信息来做广告;
隐私机制:
- 用户从浏览器中打开位置感知应用程序;
- 应用程序web页面加载,然后通过Geolocation函数调用请求位置坐标;浏览器拦截这一请求,然后请求用户授权;
- 用户同意后,浏览器从其宿主设备中检索坐标信息;
- 浏览器将坐标发送给受信任的外部定位服务,它返回一个详细信息,并将位置信息发回给html5 geolocation应用程序;
使用API:
- 浏览器支持性检查:通过navigator.geolocation
- 位置请求:
- 单次定位请求: 核心函数,navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError);
- updateLocation:只要浏览器具备访问位置信息的条件,就会调用此函数;该函数接受一个位置对象参数,包括坐标(coords)和一个时间戳;
- handleLocationError:处理错误信息,会返回一个描述错误的对象包括错误编码与描述
- 1:用户选择拒绝;
- 2:尝试获取用户信息,但失败来;
- 3:设置了可选timeout值后超时
- 可选的请求特性:
- enableHeightAccuracy:启用该参数即通知浏览器启用HTML5 Geolocation服务的高度精确模式;注意启用后可能没有差别,也可能导致更多的时间计算;
- timeout:单位ms,告诉浏览器计算当前位置允许的最长时间,默认为infinity;
- maxmumAge:单位ms,表示浏览器重新计算位置的时间间隔,默认为0;
function loadDemo() { if(navigator.geolocation) { document.getElementById('support').innerHTML = 'Geolocation supported'; } else { document.getElementById('support').innerHTML = 'Geolocation is not supported in your browser'; } } function updateLocation(position) { var latitude = position.coords.latitude; //经度 var longitude = position.coords.longitude; //纬度 var accuracy = position.coords.accuracy; //准确度 var timestamp = position.timestamp; //时间戳 document.getElementById('latitude').innerHTML = latitude; document.getElementById('longitude').innerHTML = longitude; document.getElementById('accuracy').innerHTML = accuracy; document.getElementById('timestamp').innerHTML = timestamp; } function handleLocationError(error) { var msg = error.message; switch(error.code) { case 0: updateErrorStatus('There was an error while retrieving your location.Additional details: ' + msg); break; case 1: updateErrorStatus('The user opted not to share his or her location'); break; case 2: updateErrorStatus('The browser was unable to determine your location.Additional details: ' + msg); break; case 3: updateErrorStatus('The browser timed out before retrieving the location'); break; } } function updateErrorStatus(msg) { console.log(msg); document.getElementById('msg').innerHTML = msg; } window.onload = loadDemo; var btn = document.getElementById('btn'); btn.onclick = function () { navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError, {timeout: 100000}); }
- 单次定位请求: 核心函数,navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError);
-
- 重复性的位置更新请求:核心函数,navigator.geolocation.watchPosition(updateLocation, handleLocationError);
- 只要用户位置发生变化就会调用updateLocation;
- 停止监听:
var watchId = navigator.geolocation.watchPosition(updateLocation, handleLocationError); navigator.geolocation.clearWatch(watchId);
- 重复性的位置更新请求:核心函数,navigator.geolocation.watchPosition(updateLocation, handleLocationError);
构建应用:(距离跟踪器):
<body onload='loadDemo()'> <header> <h1>Odometer Demo</h1> <h4>Live Race Data!</h4> </header> <div id='container'> <section> <article> <header> <h1>Your Location</h1> </header> <div class='info' id='status'>Geolocation is not supported in your browser</div> <div class='geostatus'> <p id='latitude'>Latitude: </p> <p id='longitude'>Longitude: </p> <p id='accuracy'>Accuracy: </p> <p id='timestamp'>Timestamp: </p> <p id='currDist'>Current distance traveled: </p> <p id='totalDist'>Total distance traveled: </p> </div> </article> </section> <footer> <h2>Powered by HTML5, and your feet!</h2> </footer> </div> <script type="text/javascript"> var totalDistance = 0.0; var lastLat; var lastLong; Number.prototype.toRadians = function() { return this * Math.PI / 180; } function distance(latitude1, longitude1, latitude2, longitude2) { //r是地球半径,单位km; var R = 6371; var deltaLatitude = (latitude2 - latitude1).toRadians(); var deltaLongitude = (longitude2 - longitude1).toRadians(); latitude1 = latitude1.toRadians(), latitude2 = latitude2.toRadians(); var a = Math.sin(deltaLatitude/2) * Math.sin(deltaLatitude/2) + Math.cos(latitude1) * Math.cos(latitude2) * Math.sin(deltaLongitude/2) * Math.sin(deltaLongitude/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; return d; } function updateErrorStatus(message) { document.getElementById('status').style.background = 'papayaWhip'; document.getElementById('status').innerHTMl = '<strong>Error</strong>: ' + message; } function updateStatus(message) { document.getElementById('status').style.background = 'paleGreen'; document.getElementById('status').innerHTMl = message; } function updateLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var accuracy = position.coords.accuracy; var timestamp = position.timestamp; document.getElementById('latitude').innerHTML = 'latitude: ' + latitude; document.getElementById('longitude').innerHTML = 'longitude: ' + longitude; document.getElementById('accuracy').innerHTML = 'accuracy: ' + accuracy; document.getElementById('timestamp').innerHTML = 'timestamp: ' + timestamp; //如果accuracy值太大,就不要计算距离 if(accuracy >= 30000) { updateStatus('Need more accuracy values to calculate distance'); return; } //计算距离 if((lastLat != null) && (lastLong != null)) { var currentDistance = distance(latitude, longitude, lastLat, lastLong); alert(0); document.getElementById('currDist').innerHTMl = 'Current distance traveled: ' + currentDistance.toFixed(2); + ' km'; totalDistance += currentDistance; document.getElementById('totalDist').innerHTMl = 'Total distance traveled: ' + currentDistance.toFixed(2) + ' km'; updateStatus('Location successfully updated'); } lastLat = latitude; lastLong = longitude; } function handleLocationError(error) { var msg = error.message; switch(error.code) { case 0: updateErrorStatus('There was an error while retrieving your location.Additional details: ' + msg); break; case 1: updateErrorStatus('The user opted not to share his or her location'); break; case 2: updateErrorStatus('The browser was unable to determine your location.Additional details: ' + msg); break; case 3: updateErrorStatus('The browser timed out before retrieving the location'); break; } } function loadDemo() { document.getElementById('status').innerHTMl = 'HTMl5 Geolocation is supported in your browser'; navigator.geolocation.watchPosition(updateLocation, handleLocationError, {timeout: 10000}); } </script> </body>
结合GoogleMap使用:
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> #map{ 500px; height: 400px; } </style> </head> <body> <div id='map'></div> <div id='status'></div> <script type="text/javascript" src='http://maps.google.com/maps/api/js?sensor=false'></script> <script type="text/javascript"> function updateLocation(position) { var latitude = parseFloat(position.coords.latitude); var longitude = parseFloat(position.coords.longitude); var latlng = new google.maps.LatLng(latitude, longitude); var mapOptions = { zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById('map'),mapOptions); map.setCenter(latlng); var marker = new google.maps.Marker({ map: map, position: latlng, }); } navigator.geolocation.getCurrentPosition(updateLocation,handleLocationError); function handleLocationError(error) { document.getElementById('status').innerHTMl = '<strong>Error</strong>: ' + error.message; } </script> </body> </html>