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>

 

posted @ 2013-04-13 23:29  Gyoung  阅读(5842)  评论(0编辑  收藏  举报