HTML5 Geolocation 构建基于地理位置的 Web 应用

HTML5 中的新功能

HTML5 是最新一代的 HTML 规范,是 W3C 与 WHATWG 合作的结果,目前仍外于开发中。自从上一代 HTML4,Web 世界已经发生了巨大的变化,HTML5 的到来更大地促进了 Web 的发展,HTML5 提供了很多新的功能,主要有:

  • 新的 HTML 元素,例如 section, nav, header, footer, article 等
  • 用于绘画的 Canvas 元素
  • 用于多媒体播放的 video 和 audio 元素
  • 用于定位的 Geolocation API
  • 本地存储以及离线应用
  • Web Workers API

本文主要对 HTML5 用于定位的 Geolocation 功能进行讲解,并提供实例,介绍它在实际中的应用。

位置信息

在 HTML5 中,当请求一个位置信息时,如果用户同意,浏览器就会返回位置信息,该位置信息是通过支持地理定位功能的底层设备(比如笔记本电脑或手机)提供给浏览器的。位置信息由纬度、经度坐标和一些其他元数据组成。例如北京故宫的位置信息主要由一对纬度和经度坐标组成:纬度:北纬 39.9,经度:东经 116.4。

经纬度坐标有两种表示方式:十进制格式(例如 39.9)和 DMS(Degree Minute Second,角度)格式(例如 39 ° 54 ′ 20 ″)。HTML5 Geolocation API 返回的坐标格式为十进制格式。除了纬度和经度坐标,HTML5 Geolocation 还提供位置坐标的准确度。除此之外,它还会提供其他一些元数据,比如海拔、海拔准确度、行驶方向和速度等,具体情况取决于浏览器所在的硬件设备。

位置信息一般从如下数据源获得:

  • IP 地址
  • 三维坐标
    • GPS(Global Positioning System,全球定位系统)
    • Wi-Fi
    • 手机信号
  • 用户自定义数据

它们各有优缺点如表 1 所示,为了保证更高的准确度,许多设备使用多个数据源组合的方式。

表 1. 位置信息获取方式对比
数据源 优点 缺点
IP 地址 任何地方都可用 
在服务器端处理
不精确(经常出错,一般精确到城市级)
运算代价大
GPS 很精确 定位时间长,耗电量大 
室内效果差 
需要额外硬件设备支持
Wi-Fi 精确 
可在室内使用 
简单、快捷
在乡村这些 Wi-Fi 接入点少的地区无法使用
手机信号 相当准确 
可在室内使用 
简单、快捷
需要能够访问手机或其 modem 设备
用户自定义 可获得比程序定位服务更准确的位置数据 
用户自行输入可能比自动检测更快
可能很不准确,特别是当用户位置变更后

浏览器支持情况

各浏览器对 HTML5 Geolocation 的支持程度不同,并且还在不断更新中。好消息是:在 HTML5 的所有功能中,HTML5 Geolocation 是第一批被全部接受和实现的功能之一,相关规范已经达到一个非常成熟的阶段,不大可能做太大改变。如表 2 所示,很多浏览器已经支持 HTML5 Geolocation:

表 2. 浏览器对 HTML5 Geolocation 的支持情况
浏览器 支持情况
Firefox 3.5 及以上版本支持
Chrome 在带有 Gears 的第 2 版 Chrome 中被支持
Internet Explorer 通过 Gears 插件支持
Opera 在版本 10 中支持
Safari 在版本 4 中支持以实现在 iPhone 上可用

由于浏览器对它的支持程度不同,在使用之前最好先检查浏览器是否支持 HTML5 Geolocation API。后面将讲解如何检查浏览器是否支持此功能。本文中所有示例程序都在 Firefox 12.0 上运行测试成功。

隐私

HTML5 Geolocation 规范提供了一套保护用户隐私的机制。必须先得到用户明确许可,才能获取用户的位置信息。不过,从可接触到的 HTML5 Geolocation 应用程序示例中可以看到,通常会鼓励用户共享这些信息。例如,午餐时间到了,如果应用程序可以让用户知道附近餐馆的特色菜及其价格和评论,那么用户就会觉得共享他们的位置信息是可以接受的。

访问使用 HTML5 Geolocation API 的页面时,会触发隐私保护机制。图 1 显示了在 Firefox 12.0 中触发隐私保护机制的页面。

图 1. HTML5 Geolocation 在 Firefox 12.0 中触发隐私保护机制

因为位置数据属于敏感信息,所以接收到之后,必须小心地处理、存储和重传。如果用户没有授权存储这些数据,那么应用程序应该在相应任务完成后立即删除它。如果要重传位置数据,建议对其进行加密。

HTML5 Geolocation API

本节将详细介绍 HTML5 Geolocation API 的使用方法。

浏览器支持性检查

在调用 HTML5 Geolocation API 函数前,需要确保浏览器支持此功能。当浏览器不支持时,可以提供一些替代文本,以提示用户升级浏览器或安装插件(如 Gears)来增强现有浏览器功能。清单 1 是浏览器支持性检查的一种途径。

清单 1. 检查浏览器支持性
 function testSupport() {
    if (navigator.geolocation) {
        document.getElementById(“support”).innerHTML = "支持 HTML5 Geolocation。";
    } else {
    document.getElementById(“support”).innerHTML =
    "该浏览器不支持 HTML5 Geolocation !建议升级浏览器或安装插件(如 Gears)。";
    }
 }

在清单 1 中,testSupport() 函数检测了浏览器的支持情况。这个函数应该在页面加载的时候就被调用,如果浏览器支持 HTML5 Geolocation,navigator.geolocation 调用将返回该对象,否则将触发错误。预先定义的 support 元素会根据检测结果显示浏览器支持情况的提示信息。

位置请求

在 HTML5 Geolocation 功能中,位置请求有两种:

  • 单次定位请求
  • 重复性位置更新请求

单次位置请求

在许多应用中,只检索或请求一次用户位置即可。例如前面提到的,午餐时间到了,要查询用户附近餐馆的特色菜及其价格和评论,就可以使用清单 2 所示的 HTML5 Geolocation API。

清单 2. 单词定位请求 API
 void getCurrentPosition(updateLocation, optional handleLocationError, optional options);

这个函数接受一个必选参数和两个可选参数。

  • 必选参数 updateLocation 为浏览器指明位置数据可用时应调用的函数。获取位置操作可能需要较长时间才能完成,用户不希望在检索位置时浏览器被锁定,这个参数就是异步收到实际位置信息后,进行数据处理的地方。它同时作为一个函数,只接受一个参数:位置对象 position。这个对象包含坐标(coords)和一个获取位置数据时的时间戳,许多重要的位置数据都包含在 coords 中,比如:

    • latitude(纬度)
    • longitude(经度)
    • accuracy(准确度)

    毫无疑问,这三个数据是最重要的位置数据。latitude 和 longitude 包含 HTML5 Geolocation 服务测定的十进制用户位置。accuracy 以 m 为单位制定纬度和经度值与实际位置间的差距。局限于 HTML5 Geolocation 的实现方式,位置只能是粗略的近似值。在呈现返回值前请一定要检查返回值的准确度。如果推荐的所谓“附近的”餐馆,实际上要耗费用户几个小时的路程,那就不好了。

    坐标可能还包含其他一些数据,不能保证浏览器对其都支持,如果不支持则返回 null:

    • altitude – 海拔高度,以 m 为单位;
    • altitudeAccuracy – 海拔高度的准确度,以 m 为单位;
    • heading – 行进方向,相对于正北而言;
    • speed – 速度,以 m/s 为单位。

    清单 3 给出了 updateLocation() 函数的常用实现代码,该函数根据坐标信息执行具体的更新操作:用获得的位置信息分别更新 HTML 页面上三个空间元素的文本。

    清单 3. updateLocation() 函数使用示例
     function updateLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var accuracy = position.coords.accuracy; 
    
        document.getElementById(“纬度”).innerHTML = latitude;
        document.getElementById(“经度”).innerHTML = longitude;
        document.getElementById(“准确度”).innerHTML = accuracy + “米”;
     }
  • 可选参数 handleLocationError 为浏览器指明出错处理函数。位置信息请求可能因为一些不可控因素失败,这时,您需要在这个函数中提供对用户的解释。幸运的是,该 API 已经定义了所有需要处理的错误情况的错误编号。错误编号 code 设置在错误对象中,错误对象作为 error 参数传递给错误处理程序。这些错误编号有:
    • UNKNOWN_ERROR (0):不包括在其它错误编号中的错误,需要通过 message 参数查找错误的详细信息。
    • PERMISSION_DENIED (1):用户拒绝浏览器获得其位置信息。
    • POSITION_UNVAILABLE (2):尝试获取用户信息失败。
    • TIMEOUT (3):在 options 对象中设置了 timeout 值,尝试获取用户位置超时。

    在这些情况下,您可以通知用户应用程序运行出了什么问题,如清单 4 所示。

    清单 4. 使用错误处理函数
     function handleLocationError(error) {
        switch (error.code) {
        case 0:
            updateStatus(“尝试获取您的位置信息时发生错误:” + error.message);
            break;
        case 1:
            updateStatus(“用户拒绝了获取位置信息请求。”);
            break;
        case 2:
            updateStatus(“浏览器无法获取您的位置信息。”);
            break;
        case 3:
            updateStatus(“获取您位置信息超时。”);
            break;
        }
     }
  • 可选参数 options 对象可以调整 HTML5 Geolocation 服务的数据收集方式。该对象有三个可选参数:
    • enableHighAccuracy:如果启动该参数,浏览器会启动 HTML5 Geolocation 服务的高精确度模式,这将导致机器花费更多的时间和资源来确定位置,应谨慎使用。默认值为 false;
    • timeout:单位为 ms,告诉浏览器获取当前位置信息所允许的最长时间。如果在这个时间段内未完成,就会调用错误处理程序。默认值为 Infinity,即无穷大(无限制);
    • maximumAge:以 ms 为单位,表示浏览器重新获取位置信息的时间间隔。默认值为 0,这意味着浏览器每次请求时必须立即重新计算位置。

    使用可选参数 options 更新我们的位置请求,让其包含一个使用 JSON 对象表示的可选参数,如下所示:

    清单 5. 包含 options 的更新位置请求
     navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError,
     {timeout: 10000});

    这个调用告诉 HTML5 Geolocation,当获取位置请求的处理时间超过 10s(10000ms)时触发错误处理程序,这时,error code 应该是 3。

重复性位置更新请求

有时候,仅获取一次用户位置信息是不够的。比如用户正在移动,随着用户的移动,页面应该能够不断更新显示附近的餐馆信息,这样,所显示的餐馆信息才对用户有意义。幸运的是,HTML5 Geolocation 服务的设计者已经考虑到了这一点,应用程序可以使用如下 API 进行重复性位置更新请求,当监控到用户的位置发生变化时,HTML5 Geolocation 服务就会重新获取用户的位置信息,并调用 updateLocation() 函数处理新的数据,及时通知用户。

清单 6. 重复性位置更新请求 API
 void watchPosition(updateLocation, optional handleLocationError, optional options);

这个函数的参数跟前面提到的 getCurrentPosition 函数的参数一样,不再累赘介绍。

关闭更新也很简单,如果应用程序不需要再接收用户的位置更新消息,只需要使用 clearWatch() 函数。参照清单 7 给的例子。

清单 7. watchPosition 和 clearWatch 的使用
 var watchId = navigator.geolocation.watchPosition(updateLocation, handleLocationError);
 // 基于持续更新的位置信息实现一些功能…
 // 停止接收位置更新消息
 navigator.geolocation.clearWatch(watchId);

构建实用应用

本节将介绍如何用刚刚介绍的“重复性位置更新请求”构建一个简单有用的 Web 应用程序:距离跟踪器。通过此应用程序可以了解到 HTML5 Geolocation API 的强大之处。

想要快速确定在一定时间内的行走距离,通常可是使用 GPS 导航系统或计步器这样的专业设备。基于 HTML5 Geolocation 提供的强大服务,我们可以自己创建一个网页来跟踪从网页被加载的地方到目前所在位置所经过的距离。虽然它在台式机上不大实用,可在手机上运行时非常理想的。只要在手机浏览器中打开这个示例页面并授予其位置访问的权限,每隔几秒钟,应用程序就会更新计算走过的距离。如图 2 所示。

图 2. HTML5 Geolocation 示例应用程序在 Moto ME525 上的运行界面

在此实例中使用的 watchPosition() 函数刚刚在上一节中介绍过。每当有新的位置返回,就将其与上次保存的位置进行比较以计算距离。距离计算使用著名的 Haversine 公式来实现,这个公式能够根据经纬度计算地球上两点间的距离。它的 JavaScript 实现如清单 8 所示:

清单 8. Haversine 公式的 JavaScript 实现
 function toRadians(degree) {
    return this * Math.PI / 180;
 } 

 function distance(latitude1, longitude1, latitude2, longitude2) {
    // 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;
 }

其中 distance() 函数用来计算两个经纬度表示的位置间的距离,我们可以定期检查用户的位置,并调用这个函数来得到用户的近似移动距离。这里有一个假设,即用户在每个区间上都是直线移动的。

显示不准确的位置信息会给用户提供误导,给用户以极其坏的印象,认为我们的应用程序不可靠,我们应该尽量避免。因此,我们将通过 position.coords.accuracy 过滤掉所有低精度的位置更新数据。如清单 9 所示:

清单 9. 过滤不准确的位置更新数据
 // 如果 accuracy 的值太大,我们认为它不准确,不用它计算距离
 if (accuracy >= 500) {
    updateStatus("这个数据太不靠谱,需要更准确的数据来计算本次移动距离。");
    return;
 }

最后,我们来计算移动距离。假设前面已经至少收到了一个准确的位置,我们将更新移动的总距离并显示给用户,同时还存储当前数据以备后面的比较。代码如清单 10 所示:

清单 10. 计算移动距离
 // 计算移动距离
 if ((lastLat != null) && (lastLong != null)) {
    var currentDistance = distance(latitude, longitude, lastLat, lastLong);
    document.getElementById("本次移动距离").innerHTML =
        "本次移动距离:" + currentDistance.toFixed(4) + " 千米"; 

    totalDistance += currentDistance; 

    document.getElementById("总计移动距离").innerHTML =
        "总计移动距离:" + currentDistance.toFixed(4) + " 千米";
    } 

    lastLat = latitude;
    lastLong = longitude; 

    updateStatus("计算移动距离成功。");
 }

至此,本文已经给出了该示例的所有核心代码(完整代码请从附件中下载)。用这么简短的不到 150 行的 HTML 和脚本代码,我们就构建了一个能够持续监控用户位置变化的示例应用程序,几乎完整地演示了 Geolocation API 的使用。不妨把它放到您支持地理位置定位的手机或移动设备上,看看您一天大概能走多少路吧,这是不是很有趣呢?

原文地址

时间: 2024-08-04 23:16:08

HTML5 Geolocation 构建基于地理位置的 Web 应用的相关文章

构建基于Nginx的web服务器

构建基于Nginx的web服务器 一.简介 Nginx("engine x") 是一个高性能的HTTP 和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器. Nginx 是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站 点开发的,它已经在该站点运行超过四年多了.Igor 将源代码以类BSD许可证的形式发布.自Nginx 发布四年来,Nginx 已经因为它的占有内存少.并发能力强.稳定性.丰富的功能集.示例配置文件和低系统资源的消耗而闻名了.目前国内各大

maven-bundle-plugin插件, 用maven构建基于osgi的web应用

maven-bundle-plugin 2.4.0以下版本导出META-INF中的内容到MANIFEST.MF中 今天终于把maven-bundle-plugin不能导出META-INF中的内容到Export-Package中的问题解决了,因为产品用的是OSGI框架,用到的第三方JAR包需要加载META-INF/XX/XX.xml这个内容,但在运行的时候getResource返回null. 经一番调查发现META-XX.XX这个包名没有导出,手动去修改MANIFEST.MF可以解决问题.但产品的

Spring boot构建基于rest的Web服务

一.介绍:使用Spring Boot我们可以很容易的创建一个可独立运行的Rest web服务,其中内嵌tomact,我们只需“run”就可以查看效果了. Spring Boot利用Gradle或Maven构建引入第三方库的方式,所以我么不需要去担心我们改引入哪些库,而且使用Spring Boot省去了很多繁琐的配置. 接下来,我们将用Spring Boot实现和c# mvc一样的Rest Web服务. 二.效果:经典的Hello World. 这将是我么最终的效果,毋须配置部署tomact,我们

html5 geolocation API

清单 1. 检查浏览器支持性if (navigator.geolocation) 清单 2. 单次定位请求 API void getCurrentPosition(updateLocation, optional handleLocationError, optional options); 清单 3. updateLocation() 函数使用示例updateLocation() 函数是getCurrentPosition的必选参数,也是浏览器指明位置数据可用时应调用的函数.获取位置操作可能需

使用 HTML5 WebSocket 构建实时 Web 应用

作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas.本地存储.多媒体编程接口.WebSocket 等等.这其中有"Web 的 TCP "之称的 WebSocket 格外吸引开发人员的注意.WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道.Web 开发人员可以非常方便地使用 WebSocket 构建实时 web 应用,开发人员的手中从此又多了一柄神兵利器.本文首先介绍

HTML5 地理位置定位(HTML5 Geolocation)原理及应用

地理位置(Geolocation)是 HTML5 的重要特性之中的一个,提供了确定用户位置的功能,借助这个特性可以开发基于位置信息的应用. 今天这篇文章向大家介绍一下HTML5 地理位置定位的基本原理及各个浏览器的数据精度情况. 在訪问位置信息前,浏览器都会询问用户是否共享其位置信息,以 Chrome 浏览器为例,假设您同意 Chrome 浏览器与站点共享您的位置,Chrome 浏览器会向 Google 位置服务发送本地网络信息,预计您所在的位置. 然后,浏览器会与请求使用您位置的站点共享您的位

html5 Geolocation(地理位置定位)学习

1.html5 Geolocation html5 Geolocation API 使用很简单,请求一个位置信息,如果用户同意,浏览器会返回一个位置信息,该位置是通过用户的底层设备(手机,电脑) 提供给浏览器.位置信息一般包括经度和纬度信息! 经度和纬度坐标信息一般由两种方式表示 a.十进制表示:39.17222 b.DMS角度格式表示:39°10'20" 2.位置从哪里来 html5 Geolocation API不指定设备使用哪种底层技术来定位应用程序的用户,相反,它只是用于检索位置信息的A

Html5 Geolocation获取地理位置信息(转)

Html5中提供了地理位置信息的API,通过浏览器来获取用户当前位置.基于此特性可以开发基于位置的服务应用.在获取地理位置信息前,首先浏览器都会向用户询问是否愿意共享其位置信息,待用户同意后才能使用. Html5获取地理位置信息是通过Geolocation API提供,使用其getCurrentPosition方法,此方法中有三个参数,分别是成功获取到地理位置信息时所执行的回调函数,失败时所执行的回调函数和可选属性配置项. 如下Demo演示了通过Geolocation获取地理位置信息,并在百度地

[转]使用 HTML5 WebSocket 构建实时 Web 应用

HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例来充分展示 WebSocket 的强大和易用. 作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas.本地存储.多媒体编程接口.WebSocket 等等.这其中有“Web 的 TCP ”之称的 WebSocket 格外吸引开发人员的注意.WebSocket 的出现使得浏