让我们假设这样一个场景,有一个web应用程序,它可以向用户提供附近不远处某商场的打折优惠信息。使用HTML5 Geolocation API(地理定位 API),可以请求用户共享他们的位置信息。

  HTML5 Geolocation 技术应用的场景比较多,比如构建计算行走路程、GPS导航的社交应用等。

  本文主要探讨 HTML5 Geolocation API,包括获取地理位置数据的途径,地理位置数据的隐私以及在实际中的应用等。

  目前存在两种地理定位请求:单次定位请求和重复性的位置更新请求。

一、地理位置数据的获取

  获取地理位置数据的方法有以下几种:

  • IP地址地理定位:自动查找用户的IP地址,然后检索其注册的物理地址;
  • GPS地理定位:通过收集运行在地球周围的多个GPS卫星信号来实现;
  • Wi-Fi地理定位:通过三角距离计算得出(三角距离:用户当前位置到已知的多个Wi-Fi接入点的距离);
  • 手机地理定位:通过用户到一些基站的三角距离确定;
  • 用户自定义地理定位:用户自己输入地址、邮政编码和其他一些详细信息。

二、地理位置数据的隐私

  HTML5 Geolocation 规范提供了一套保护用户隐私的机制,除非得到用户明确许可,否则不可能获取位置信息。

  HTML5 地理定位浏览器和设备之间的交互如下所述:

  1. 用户从浏览器中打开位置感知应用程序;
  2. 应用程序Web页面加载,然后通过Geolocation函数调用请求位置坐标。浏览器拦截这一请求,然后请求用户授权。我们假设用户同意;
  3. 浏览器从其宿主设备中检索坐标信息。例如,IP地址、Wi-Fi 或 GPS 坐标。这是浏览器内部功能;
  4. 浏览器将坐标发送给受信任的外部定位服务,它返回一个详细位置信息,并将该位置信息发回给 HTML5 Geolocation 应用程序。

三、HTML5 Geolocation API介绍

  在访问使用 HTML5 Geolocation API 的页面时,会触发隐私保护机制。但是如果仅仅是添加代码,而不被任何方法调用,则不会才触发隐私保护机制。

  要使用 HTML5 Geolocation API,首先要检查浏览器是否支持,代码如下:

1
2
3
4
5
6
7
function loadDemo(){
If(navigator.geolocation){
  document.getElementById("support").innerHTML = "HTML5 Geolocation supported.”
}else{
  ocument.getElementById("support”).innerHTML = "HTML5 Geolocation is not supported in your browser.” 
}
}

  单次定位请求API:

1
2
3
Void getCurrentPosition(in PositionCallback successCallBack,
                    in optional PositionErrorCallBack errorCallback,
                     in optiona PositionOptions options)

  上述的函数要通过navigator.geolocation来调用,各个参数解释如下:

  successCallBack:浏览器指明位置数据可用时调用的函数,即收到实际位置信息并进行处理的地方,此函数只接受一个参数:位置对象,包含坐标和一个时间戳;

  errorCallback:在获取位置数据出错时的处理地方,向用户说明失败原因,可选参数,但是建议使用;

  Options:此对象可调整 HML5 Geolocation服务的数据收集方式,可选;可以通过 JSON 对象进行传递,主要包括enableHighAccuracy(启用HML5 Geolocation服务的高精确度模式、timeout(当前位置所允许的最长时间)、maximumAge(浏览器重新计算位置的时间间隔)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function successCallBack(position){
   var latitude = position.coords.latitude;
   var longitude = position.coords.longitude;
   var accuracy = position.coords.accuracy;
   //此处可以添加代码,把上述三个值显示到页面中。
  
}
ffunction errorCallback(error){
    switch(error.code){
        //UNKNOWN_ERROR = 0 需要通过message参数查找错误的更多信息
        case 0:
            updateStatus("There was an error while retrieving your location:" + error.message);
            break;
        //PERMISSION_DENIED = 1 用户拒绝浏览器获得其共享位置
        case 1:
            updateStatus("The user prevented this page form retrieving a location!");
            break;
        //POSITION_UNAVAILABLE = 2 尝试获取用户位置,但失败
        case 2:
            updateStatus("The browser was unable to determine your location:" + error.message);
            break;
        //TIMEOUT = 3 设置了可选的timeout值,尝试确定用户位置的过程超时
        case 3:
            updateStatus("The browser timed out before retriveing the !");
            break;
    }
}

  重复性位置请求API:

1
2
3
4
var watchId = navigator.geolocation.watchPosition(updateLocation,handleLocationError);
   
//停止接收位置更新信息
 navigator.geolocation.clearWatch(watchId);

  

四、使用HML5 Geolocation构建应用

  使用上述讲解的HML5 Geolocation API来实现 一个简单有用的Web应用程序—距离追踪器,以了解HML5 Geolocation 的强大之处。

  本例主要讲述从网页被加载的地方到目前所在位置所经过的距离。使用众所周知的Haversine公式,其能够根据经纬度来计算地球上两点间的距离。如下:

  关于上述原理,请参考网上其他教程。使用js实现的Haversine公式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function toRadians(degree){
return degree * Math.PI / 180 ;
}
  
function distance(latitude1,longitude1,latitude1,longitude1){
//R是地球的半径,以km为单位
var R = 6371;
var deltaLatitude = toRadians(latitude2 - latitude1);
var deltaLongitude = toRadians(longitude2 - longitude1);
  
latitude1 = toRadians(latitude1);
latitude2 = toRadians(latitude2);
  
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;
}

  HTML网页代码入下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <title>HTML5 地理定位</title>
    <link rel="stylesheet" href="styles.css">
</head>
  
<body onload="loadDemo()">
  
<h1>HTML5 地理位置追踪器</h1>
  
<p id="status">你的浏览器不支持HTML5地理定位</p>
  
<h2>当前位置:</h2>
<table border="1">
<tr>
<th width="40" scope="col"><h5>纬度</h5></th>
<td width="114" id="latitude">?</td>
</tr>
<tr>
<td> 经度</td>
<td id="longitude">?</td>
</tr>
<tr>
<td>准确度</td>
<td id="accuracy">?</td>
</tr>
<tr>
<td>最近的时间戳</td>
<td id="timestamp">?</td>
</tr>
</table>
  
<h4 id="currDist">当前旅行的距离: 0.0 km</h4>
<h4 id="totalDist">总的旅行距离: 0.0 km</h4>
  
</body>
  
<script text="text/javascript">
  
var totalDistance = 0;
var lastLat;
var lastLong;
  
Number.prototype.toRadians = function() {
return this * Math.PI / 180;
}
  
function loadDemo(){
If(navigator.geolocation){
updateSatus("你的浏览器支持HTML5地理定位");
navigator.geolocation.watchPosition(updateLocation,handleLocationError,{maximumAge:20000});
}
}
  
function updateSatus(message){
document.getElementById("status").innerHTML = message;
}
  
function distance(latitude1,longitude1,latitude1,longitude1){
//R是地球的半径,以km为单位
var R = 6371;
var deltaLatitude = toRadians(latitude2 - latitude1);
var deltaLongitude = toRadians(longitude2 - longitude1);
  
latitude1 = toRadians(latitude1);
latitude2 = toRadians(latitude2);
  
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 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;
  
if(accuracy >= 500){
updateStatus("不需要计算精确距离");
return;
}
  
if((lastLat != null) && (lastLong !=null)){
var currentDistance = distace(latitude, longitude, lastLat, lastLong);
document.getElementById("currDist").innerHTML =
              "当前旅行的距离: " + currentDistance.toFixed(4) + " km";
  
            totalDistance += currentDistance;
  
            document.getElementById("totalDist").innerHTML =
              "总的旅行距离: " + currentDistance.toFixed(4) + " km";
}
  
lastLat = latitude;
lastLong = longitude;
  
updateStatus("成功更新位置。");
}
  
    function handleLocationError(error) {
        switch(error.code)
        {
        case 0:
          updateStatus("检索位置发生错误:" + error.message);
          break;
        case 1:
          updateStatus("用户阻止检索位置信息。");
          break;
        case 2:
          updateStatus("浏览器不能检索位置信息:" + error.message);
          break;
        case 3:
          updateStatus("浏览器检索位置信息超时。");
          break;
        }
    }
  
</script>
  
</html>
 

HTML5编程之旅系列一:HTML5 Geolocation 初探的更多相关文章

  1. 《HTML5编程之旅》系列三:WebSockets 技术解析

    本文主要研究HTML5 WebSockets的使用方法,它是HTML5中最强大的通信功能,定义了一个全双工的通信信道,只需Web上的一个Socket即可进行通信,能减少不必要的网络流量并降低网络延迟. ...

  2. 《HTML5编程之旅》系列二:Communication 技术初探

     本文主要探讨用于构建实时跨源通信的两个模块:跨文档消息通信(Cross Document Messaging)和XMLHttpRequestLevel2.通过这两个模块,我们可以构建不同域间进行安全 ...

  3. 『HTML5梦幻之旅』-缤纷多姿的烟花效果

    天花无数月中开,五采祥云绕绛台.堕地忽惊星彩散,飞空旋作雨声来.怒撞玉斗翻晴雪,勇踏金轮起疾雷.更漏已深人渐散,闹竿挑得彩灯回. ——明·瞿佑·<烟火戏> 记得每年过春节的那段时间,除了欣 ...

  4. 使用 jQuery Mobile 与 HTML5 开发 Web App 系列文章目录

    使用 jQuery Mobile 与 HTML5 开发 Web App 系列文章目录 时间:2012年9月20日 分类:JavaScript 标签:HTML5‚ jQuery Mobile‚ Web ...

  5. HTML5 学习总结(一)——HTML5概要与新增标签

    一.HTML5概要 1.1.为什么需要HTML5 HTML4陈旧不能满足日益发展的互联网需要,特别是移动互联网.为了增强浏览器功能Flash被广泛使用,但安全与稳定堪忧,不适合在移动端使用(耗电.触摸 ...

  6. HTML5 学习笔记(一)——HTML5概要与新增标签

    目录 一.HTML5概要 1.1.为什么需要HTML5 1.2.什么是HTML5 1.3.HTML5现状及浏览器支持 1.4.HTML5特性 1.5.HTML5优点与缺点 1.5.1.优点 1.5.2 ...

  7. html5文章 -- 使用 jQuery Mobile 与 HTML5 开发 Web App —— jQuery Mobile 基础

    这篇文章是使用 jQuery Mobile 与 HTML5 开发 Web App 系列的第二篇,在本文以及接下来的数篇文章 Kayo 将会介绍 jQuery Mobile 的组件.事件响应以及可以调用 ...

  8. VSTO之旅系列(五):创建Outlook解决方案

    原文:VSTO之旅系列(五):创建Outlook解决方案 本专题概要 引言 Outlook对象模型 自定义Outlook窗体 小结 一.引言 在上一个专题中,为大家简单介绍了下如何创建Word解决方案 ...

  9. HTML5是什么?如何鉴定HTML5产品?[转]

    转自:http://www.jscode.cn/web/v62484 Html 5开始大热标志性的事件是Apple 前CEO Steve Jobs 公开炮轰Flash,并指出Flash在移动终端的不利 ...

随机推荐

  1. SOJ 1210 二叉树

    1210. 二叉树 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description 在众多的数据结构中,二叉树是一种特殊而重要的结构,有 ...

  2. 模拟器SDK路径

    I'm guessing you already find it out, but just for the record: the UIKit.framework is available only ...

  3. Ambari中添加新服务

    官网: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=38571133 一.背景 栈的定义可以在源代码树中找到/am ...

  4. $and $not null 正则表达式

    查询MasterID大于1且MasterType等于TestType的文档: db.SysCore.find({$and:[{"MasterID":{$gt:1}},{" ...

  5. NOIP2014-普及组复赛-第一题-珠心算测验

    题目描述 Description 珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术.珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及. 某学校的珠心算老师 ...

  6. Openjudge-计算概论(A)-过滤多余的空格

    描述: 一个句子中也许有多个连续空格,过滤掉多余的空格,只留下一个空格. 输入一行,一个字符串(长度不超过200),句子的头和尾都没有空格.输出过滤之后的句子. 样例输入 Hello world.Th ...

  7. CURL访问url显示响应时间

    curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer}:%{time_total} http://www.baidu.com 时间指 ...

  8. HTML转PDF

    1)使用工具转换.如:wkhtmltopdf 2)Chrome浏览器打印功能中,有另存为PDF格式文件.(推荐最便捷)

  9. PHP class which generates PDF files from UTF-8 encoded HTML

    http://www.mpdf1.com/mpdf/index.php

  10. Javascript兑现图片预加载【回调函数,多张图片】 (转载)

    Javascript实现图片预加载[回调函数,多张图片] 使用JS实现一组图片动画效果或者使用HTML5 Canvas渲染一系列图片等案例中,需要图片全部加载完成方可运行动画效果.此时程序中就会涉及多 ...