浏览器地理位置(Geolocation)API 简介

这篇文章发布于 2011年06月30日,星期四,21:22,归类于 JS相关。 阅读 157600 次, 今日 8 次 16 条评论

 

一、开篇简述

Geolocation API(地理位置应用程序接口)提供了一个可以准确知道浏览器用户当前位置的方法。且目前看来浏览器的支持情况还算不错(因为新版本的IE支持了该API),这使得在不久之后就可以使用这一浏览器内置的API了。该API接口提供的用户地理位置信息还算蛮详细的,经纬度啊,海拔啊,精确度,移动速度啊都是可以获取的。

据我个人的了解,其位置的获取是通过收集用户周围的无线热点和您 PC 的 IP 地址。然后浏览器把这些信息发送给默认的位置定位服务提供者,也就是谷歌位置服务,由它来计算您的位置。最后用户的位置信息就在您请求的网站上被共享出来。

Geolocation还不是HTML5规范的一部分,不过W3C为其独立出了一份详细的规范,因此,该API的血统还算比较纯正,来路比较清白。

二、浏览器的支持情况

目前W3C地理位置API被以下桌面浏览器支持:

  • Firefox 3.5+
  • Chrome 5.0+
  • Safari 5.0+
  • Opera 10.60+
  • Internet Explorer 9.0+

W3C地理位置API还可以被手机设备所支持,如下:

  • Android 2.0+
  • iPhone 3.0+
  • Opera Mobile 10.1+
  • Symbian (S60 3rd & 5th generation)
  • Blackberry OS 6
  • Maemo

三、数据保护

显然,地理位置属于用户的隐私信息之一,尤其在做一些隐晦的事情时候,例如背着老婆去见EX,去雅典皇宫做按摩。因此浏览器不会直接把用户的地理位置信息呈现出来的,当需要获取用户地理位置信息的时候,浏览器会询问用户,是否愿意透露自己的地理位置信息,如下截图所示:
FireFox下是否愿意共享地址位置信息 张鑫旭-鑫空间-鑫生活

IE9下是否共享物理位置 张鑫旭-鑫空间-鑫生活

如果你选择不共享,则浏览器不会做任何事情。

如果你一不小心对某个站点共享了地理位置,可以随时将其取消的,方法如下:
对于IE9浏览器,Internet选项 → 隐私 → 位置(清除站点),如下截图:
IE清除共享位置 张鑫旭-鑫空间-鑫生活

对于FireFox浏览器,方法如下:
点击地址栏前面的网站小图标 → 点击更多信息 → 权限 → 共享方位信息 → 阻止,具体步骤参见下面几张截图。
FireFox浏览器取消位置共享步骤图 张鑫旭-鑫空间-鑫生活
FireFox浏览器取消地理位置共享步骤2 张鑫旭-鑫空间-鑫生活

如果是Chrome浏览器的话直接点击地址栏右边长得像轮船方向盘一样的小图标就会看到可以取消地理位置的小框框了:
Chrome浏览器清除用户地址位置信息 张鑫旭-鑫空间-鑫生活

四、地理位置资源

为获取用户的地理位置信息,需要使用多个资源,不同资源的对位置精确度的贡献是不一样的。对于桌面浏览器,通常使用WiFi(误差20米),或者IP位置(这受城市的档次影响,会出错)。对于手机设备倾向于使用测量学技术,例如GPS(误差10米,只能在户外使用),WiFi或者是GSM/CDMA的站点的ID(误差有1000米)。

五、API的使用

在使用地理位置API之前首先要检测浏览器是否支持,如下测试代码:

if (navigator.geolocation) {
  // 想干嘛就干嘛
}

当然,这个if判断也能用来进行浏览器的判断,可以区分IE6~8浏览器与IE9和其他现代浏览器。这在我们使用某些CSS3属性时非常有用,检测浏览器是否支持某些CSS3属性相对比较麻烦,可以折中下,即在知道浏览器对该CSS3属性的支持情况下检测浏览器,一般而言就是区分区分IE6~8浏览器和其他浏览器,这正好与navigator.geolocation的检测是一致的。

通过这个API,我们有两个方法变量可以用来获取用户的地理位置:
getCurrentPosition和watchPosition

这两个方法参数一致,支持三个参数,拿getCurrentPosition举例,navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options)

其中,successCallback为方法成功的回调,此参数必须;
errorCallback为方法失败时候的回调,此参数可选;
option参数为额外参数,也是可选参数,对象。option参数支持三个可选参数API,为:enableHighAccuracy, timeout, maximumAge.
1. enableHighAccuracy参数表示是否高精度可用,为Boolean类型,默认为false,如果开启,响应时间会变慢,同时,在手机设备上会用掉更多的流量,也就是money了。
2. timeout参数表示等待响应的最大时间,默认是0毫秒,表示无穷时间。
3. maximumAge表示应用程序的缓存时间。单位毫秒,默认是0,意味着每次请求都是立即去获取一个全新的对象内容。

在介绍getCurrentPositionwatchPosition方法之间的差异之前先讲一下clearWatch方法。clearWatch方法值接受一个参数,这是参数是由watchPosition方法返回的watchID

现在,讲差异。getCurrentPosition方法属于一次性取用户的地理位置信息,而watchPosition方法则不停地取用户的地理位置信息,不停地更新用户的位置信息,这在我们开汽车的时候实时获知自己的位置就显得比较受用了。watchPosition方法可以通过watchPosition方法停掉(停止不断更新用户地理位置信息),方法就是传递watchPosition方法返回的watchID了。

当用户的位置被返回的时候,会藏在一个位置对象中,该对象包括一些属性,具体见下表:

属性 释义
coords.latitude 纬度数值
coords.longitude 经度数值
coords.altitude 参考椭球之上的高度
coords.accuracy 精确度
coords.altitudeAccuracy 高度的精确度
coords.heading 设备正北顺时针前进的方位
coords.speed 设备外部环境的移动速度(m/s)
timestamp 当位置捕获到时的时间戳

上面这些属性中只有coords.latitude, coords.longitudecoords.accuracy铁定会有东西返回的,至于其他属性很可能返回的就是null。现在,我们就可以应用诸如这里返回的经纬度在Google地图上标出自己的位置。

六、使用实例

现在举一个应用Geolocation API的例子,应用的是getCurrentPosition,显示当前你在地图上的位置。

您可以狠狠地点击这里:Google地图显示您当前位置demo

下图为显示的我当前写该文章时的地理位置:
demo地图位置截图 张鑫旭-鑫空间-鑫生活

点击中间的圆泡泡的图标,会显示用户您当前经纬度,时间戳啊等,例如下图所示:
当前用户的一些信息 张鑫旭-鑫空间-鑫生活

不过,说实话,这距离的误差绝不是只有1000m,估计至少有2000~3000m,我在浦东新区,黄浦江这边,但是其却把我放到了江的另一边。

提示:要想看到效果,需要使用非IE6/IE7/IE8浏览器,否则,只会看到一行文字外带字符笑脸;在其他浏览器下需允许访问您的地理位置信息,因为这个东西可以随时取消,所以,可以放心大胆的允许。

因为脚本代码有差不多70行,放到页面上有撑篇幅之嫌,故这里仅展示一些核心的代码逻辑,至于详细,您可以查看页面的源代码,有注释,

<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
var eleGmap = document.getElementById("gmap");
var showMap = function(position) {
    //经纬度所在的位置对象
    var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    //根据pos对象中的经纬度显示Google地图了哈! 
    //...
};

if (navigator.geolocation) {
    eleGmap.innerHTML = '<div id="help"><img src="http://www.zhangxinxu.com/study/image/loading.gif" /></div>';
    //一次性获取位置的请求
    navigator.geolocation.getCurrentPosition(showMap);
} else {
    eleGmap.innerHTML = '<div id="help">您的浏览器不支持地理位置 O(∩_∩)O~</div>';
}
</script>

七、结束语

上面这个例子是相当的简单的,Geolocation API的功能与潜力显然不止这些,规范自身还提供一些应用实例,例如:

  • 发现并绘制用户所在区域的网络点
  • 在地图上,在用户所在的位置上标注一些信息
  • 使用watchPosition路线导航
  • 当你移动时更新最新的本地信息

毕竟目前,国内,对于桌面浏览器,不支持地理位置API的低版本IE依旧占据半壁江山,所以,在桌面浏览器上应用此API还需些日子。不过对于像是手机,ipad这类移动设备,我觉得是可以好好用用这个不错的API的,可以做出很多实用的功能的,不过我对手机开发完全不在行,所以,指点江山,还看他人了。

参考文章:Finding your position with Geolocation

(本篇完)

分享到:


发表评论(目前16 条评论)

  1. 丁伟说道:

    我想问一下 关于手机qq自带的浏览器 好像不支持这个api 每次打开都直接显示用户拒绝地理位置请求 怎么解决呢?

    • qw说道:

      我现在也碰到同样的问题,还有就是我在移动端IOS设备上的qq,微信自带的浏览器都打不开,直接包位置信息不可用,还有就是在安卓机上微信和其他浏览器是可以用的,但是在安卓的qq默认浏览器器就不行了;请问一下是qq不支持,还是怎么?还有就是在ios上,我单独的将html写成文件是可以用浏览器打开的

  2. clearbug说道:

    原来这东西早就有了,,尴尬现在才知道

  3. 12450说道:

    定位差这么远是因为谷歌地图在国内有偏移吧

  4. 业余草说道:

    学习了,多谢分享!

  5. 说道:

    QQ内置浏览器不支持H5地理位置怎么办

  6. 你猜说道:

    张兄 demo“请勿外链”闪瞎眼了也没干正经事 你逗我玩呢 辣么 误差有没有好的方法可以优化

  7. 同盟源说道:

    长见识了

  8. FunctionRun说道:

    为什么我打开http://www.zhangxinxu.com/study/201106/geolocation-get-position.html 之后一直没有或得到我的地理位置呢。

  9. siesteven说道:

    有用。有问题需要请假

  10. snowinmay说道:

    watchPosition方法可以通过watchPosition方法停掉

    应该是通过clearWatch停用把

  11. allhweb说道:

    这地理 坑爹啊 相差十万八千里~

  12. NetRube说道:

    桌面浏览器是通过宽带上网~
    取地理位置的方式跟很多网站的通过IP获取访客来源差不多~
    因此得到的地理位置一般是市政府的位置~
    除非在手机上并打开了GPS或电脑上外接了GPS外设才能准备获取当前地理位置~~

  13. Jin说道:

    还好,差了两个路口

  14. 说道:

    好像误差有点大。我在武昌,显示的是汉阳。