HTML5程序设计 Geolocation API
位置信息从何而来
设备可以使用下列数据源
- IP地址
- 三维坐标:GPS(Global Positioning System,全球定位系统);从RFID、Wi-Fi和蓝牙到Wi-Fi的MAC地址;GSM或CDMA手机的ID
- 用户自定义的数据
浏览器支持性检查
<div> <span class="info"> <p id="status"></p> </span> </div> <script type="text/javascript"> if (navigator.geolocation) { document.getElementById("status").innerHTML = "HTML5 Geolocation is supported in your browser."; } else { document.getElementById("status").innerHTML = "HTML5 Geolocation is not supported in your browser."; } </script>
位置请求
单次定位请求函数:void getCurrentPosition(in PositionCallback successCallBack,in optional PositionErrorCallback errorCallback,
in optional PositionOptios options)
这个函数是通过navigator.geolocation对象来调用的,所以在脚本中需要先取得此对象。这个函数接受一个必选参数和两个可选参数。
- successCallBack:为浏览器指明位置数据可用时应调用的函数,即收到实际位置信息并进行处理的地方。
- errorCallback:出错处理
- options:用来调整HTML5 Geolocation服务的数据收集方式。
示例
navigator.geolocation.getCurrentPosition(updateLocation,handleeLocationError);
这里updateLocation就是接收位置信息并进行重的函数,handleeLocationError是进行错误处理的函数。
updateLocation()函数
updateLocation只接受一个参数:位置对象。这个对象包含坐标(coords特性)和一个获取位置数据时的时间戳。以下是坐标的主要特性:
- latitude(纬度)
- longitude(经度)
- accuracy(准确度)
function updateLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; if (!latitude || !longitude) { document.getElementById("status").innerHTML = "HTML5 Geolocation is supported in your browser, but location is currently not available."; return; } document.getElementById("latitude").innerHTML = latitude; document.getElementById("longitude").innerHTML = longitude; }
handleeLocationError()函数
HTML5定义了一些错误编号:
- PERMISSION_DENIED(错误编号为1)——用户选择拒绝浏览器获得其位置信息。
- POSITION_UNAVAILABLE(错误编号为2)——尝试获取用户位置数据失败。
- TIMEOUT(错误编号为3)——设置了可选的timeout值,获取用户位置超时。
function handleeLocationError(error) { switch (error.code) { case 0: alert(error.message); break; case 1: alert(error.message); break; case 2: alert(error.message); break; case 3: alert(error.message); break; } }
options:可选的地理定位请求特性
enableHighAccuracy:如果启用该参数,则通知浏览器启用HTML5 Geolocation服务的高精度模式,参数的默认值为false.
timeout:可选值,单位为ms,告诉浏览器计算当前位置所允许的最长时间。默认值为Infinity,即为无穷大或无限制。
maximumAge:这个值表示浏览器重新计算位置的时间间隔。它也是一个以ms为单位的值,默认为零,这意味着浏览器每次请求时必须立即重新计算位置。
这三个参数可以使用JSON对象传递,这样更便于添加到HTML5 Geolocation请求调用中。
navigator.geolocation.getCurrentPosition(updateLocation, handleeLocationError, {timeout:10000});
重复性的位置更新请求
navigator.geolocation.watchPosition(updateLocation,handleLocationError);
这个函数只要用户位置发生变化,Geolocation服务就会调用updateLocation处理程序。它的效果就像是在监视用户的位置,并会在其变化时及时通知用户一样。
关闭函数
如果程序不再需要接收用户的位置信息,则可以调用
navigator.geolocation.clearWatch(watchId)
//持续更新位置信息 var watchId = navigator.geolocation.watchPosition(updateLocation, handleeLocationError); //停止更新 navigator.geolocation.clearWatch(watchId);
使用HTML5 Geolocation构建应用
这里我们使用多次请求特性构建一个简单有用的WEB应用程序——距离跟踪器,通过些应用程序可以了解到HTML5 Geolocation AIP的强大之处。
<!DOCTYPE html> <head> <meta charset="utf-8"> <title>HTML5 Geolocation Odometer</title> <link rel="stylesheet" href="styles.css"> </head> <body onload="loadDemo()"> <h1>HTML5 Geolocation Distance Tracker</h1> <p id="status">HTML5 Geolocation is <strong>not</strong> supported in your browser.</p> <h2>Current Position:</h2> <table border="1"> <tr> <th width="40" scope="col"><h5>Latitude</h5></th> <td width="114" id="latitude">?</td> </tr> <tr> <td> Longitude</td> <td id="longitude">?</td> </tr> <tr> <td>Accuracy</td> <td id="accuracy">?</td> </tr> <tr> <td>Last Timestamp</td> <td id="timestamp">?</td> </tr> </table> <h4 id="currDist">Current distance traveled: 0.0 km</h4> <h4 id="totalDist">Total distance traveled: 0.0 km</h4> <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 is the radius of the earth in kilometers 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 updateStatus(message) { document.getElementById("status").innerHTML = message; } function loadDemo() { if(navigator.geolocation) { updateStatus("HTML5 Geolocation is supported in your browser."); navigator.geolocation.watchPosition(updateLocation, handleLocationError, {maximumAge:20000}); } } 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; // sanity test... don't calculate distance if accuracy // value too large if (accuracy >= 500) { updateStatus("Need more accurate values to calculate distance."); return; } // calculate distance if ((lastLat != null) && (lastLong != null)) { var currentDistance = distance(latitude, longitude, lastLat, lastLong); document.getElementById("currDist").innerHTML = "Current distance traveled: " + currentDistance.toFixed(4) + " km"; totalDistance += currentDistance; document.getElementById("totalDist").innerHTML = "Total distance traveled: " + currentDistance.toFixed(4) + " km"; } lastLat = latitude; lastLong = longitude; updateStatus("Location successfully updated."); } function handleLocationError(error) { switch(error.code) { case 0: updateStatus("There was an error while retrieving your location: " + error.message); break; case 1: updateStatus("The user prevented this page from retrieving a location."); break; case 2: updateStatus("The browser was unable to determine your location: " + error.message); break; case 3: updateStatus("The browser timed out before retrieving the location."); break; } } </script> </body> </html>
在Google Map上显示“我在这里”
<div id="map"></div> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript"> var map = new google.maps.Map(document.getElementById("map")); function updateLocation(position) { map.setCenter(new google.maps.LatLng(parseFloat(position.coords.latitude), parseFloat(position.coords.longitude))); } navigator.geolocation.getCurrentPosition(updateLocation); </script>