移动互联网开发之Geolocation(转)

移动设备与桌面设备的区别除了上周分享的触摸功能外(当然,随着Windows8的推出,越来越多的笔记本电脑也开始支持触摸屏),就是移动设备使用的地点,使用的方式总是在变化的。所以今天再分享移动设备的另一个特性,Geolocation。
Geolocation就是地理位置,大量的LBS网站和微博里的微博发布地点,都是基于Geolocation的应用。
1.获取地理位置坐标
先简单的看下如何使用Geolocation。(注:以下代码都是基于Chrome的)
支持Geolocation的浏览器会提供一个navigator.geolocation对象,来取得当前设备的地理位置,在Chrome浏览器的控制台中输入navigator.geolocation可以看到如下图所示

可以看到,navigator.geolocation提供了三个方法watchPosition,clearWatch,getCurrentPostion。
其中getCurrentPosition是单次获取地理位置的方法,watchPosition,clearWatch是用于持续获取地理位置的方法,有点类似setInterval和clearInterval。getCurrentPosition和watchPosition的使用方法大致相同,所以这里就主要介绍getCurrentPosition。

在使用getCurrentPosition之前,我们得意识到,物理位置是用户的隐私,未经用户允许,获取用户的地理信息是非法的。所以,在我们获取用户的地理位置的时候,浏览器会出现授权提示。如下

只用用户允许后,才能使用用户的地理信息。如果要取消授权,可以去chrome浏览器的 设置>高级设置>隐私设置>内容设置>位置>管理例外情况 中取消

正因为如此,getCurrentPosition需要一个回调函数,只有当用户允许后,才能在执行这个回调函数,取得地理位置。当然,还需要另一个回调函数用来处理用户拒绝,无法定位等错误状况。Demo地址:http://ali-47418w.hz.ali.com/geolocation/demo1.html

JS:
function getLocation(){
//是否支持geolocation
if(navigator.geolocation){
//handle_access是获取地理位置成功的回调,handle_error是获取失败的回调
navigator.geolocation.getCurrentPosition(handle_access,handle_error);
console.log('getCurrentPosition');
}else{
console.log('Your browser does not support HTML5 geoLocation');
}
}

function handle_access(position){
console.log(position);
}

function handle_error(err){
//err.code是错误码
switch(err.code){
case 1 :
console.log('permission denied');
break;
case 2:
console.log('the network is down or the position satellites can\'t be contacted');
break;
case 3:
console.log('time out');
break;
default:
console.log('unknown error');
break;
}
}

getLocation();

控制台输出如下:

可以看到,在回调函数中,成功的取得了当前的地理坐标,包括经度(longitude),纬度(latitude),精确度(accuracy),海拔(altitude),海拔精确度(altitudeAccuracy),速度(speed),方向(heading),其中速度和方向是只有watchPosition才能获得的。

2.地理位置名称
通过上面的代码,虽然成功的获得了用户的地理位置坐标,但是经纬度等信息除了地图应用以外,其他的应用都不能直接使用。怎么把经纬度转换成地理位置名称呢?浏览器没有办法,因为这需要大量的地理数据。幸好,有很多公司提供了这个查询的接口,最著名的就是Google Geocoding API了,文档地址:https://developers.google.com/maps/documentation/geocoding/?hl=zh-CN。我们要的就是反向地址解析(术语“地址解析”通常是指将人类可读的地址转换成地图上的位置。反之,将地图上的位置转换成人类可读的地址这一过程则称为“反向地址解析”)。这个接口很好很强大但是我们身在天朝,要有梯子,请注意这个接口的使用条款:Google Geocoding API 只能与 Google Maps 配合使用;不能只进行地址解析而不在地图上显示结果。那就只好看下国内的了,百度地图,文档地址:http://developer.baidu.com/map/geocoding-api.htm,高德地图,文档地址:http://code.mapabc.com/class.html?ajax。SOSO地图:http://api.map.soso.com/doc/guide-service.html#4_6,搜狗地图:http://map.sogou.com/api/documentation/javascript/api2.5/tutorial.html#geocoder,当然我们的阿里云地图也是有的!!!文档地址:http://ditu.aliyun.com/jsdoc/geocode_api.html。这些是我曾经用过的接口,应该还有其他的接口。我国拥有互联网地图服务资质的公司就只有30多家,大部分是中央和地方测绘局。比较了一下,我发现还是阿里云的使用方便啊,不需要注册,不需要APIKEY,不需要SDK,甚至没找到使用条款(请阿里云同学辟谣),所以就以阿里云API为例,使用反向地址解析。DEMO:http://ali-47418w.hz.ali.com/geolocation/aliyun.html
JS:
(function($){
function getLocation(){
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(geoDecode,handle_error);
}else{
console.log("Your browser does not support HTML5 geoLocation");
}
}

function geoDecode(position){
var
latitude = position.coords.latitude,
longitude = position.coords.longitude;
$.ajax('http://gc.ditu.aliyun.com/regeocoding',{
dataType:'jsonp',
jsonp:'b',
data:{
l:latitude+','+longitude,
type:'100'
}
})
.done(function(data){
console.log(data);
if(data&&data.addrList&&data.addrList[0].status===1){
$('body').append($('<p/>').text('你的位置:'+data.addrList[0].admName+','+data.addrList[0].name));
}
});
}

function handle_error(err){
switch(err.code){
case 1 :
console.log("permission denied");
break;
case 2:
console.log("the network is down or the position satellites can't be contacted");
break;
case 3:
console.log("time out");
break;
default:
console.log("unknown error");
break;
}
}

$(function(){
getLocation();
});
})(jQuery);

3.调试
虽然说Geolocation是移动设备的特性,但事实上,桌面浏览器也是支持的,所以,我们可以放心的用桌面版Chrome来测试我们的Geolocation代码。但是,由于桌面版没有GPS,没有手机基站甚至有些连wifi都没有,这样,他的定位就非常的不准。比如我这台台式机,实际上位于滨江,定位显示却在拱墅区;而我手里的Nexus 7,定位是滨江区中兴立交桥附近,还是比较接近的。还有一点,我们有时候需要测试不同地址定位的准确度。幸好桌面版Chrome提供了地理位置虚拟的功能。

设置如下:
点击Chrome开发者工具右下角的齿轮图标,选择override标签

勾选Override Geolocation,设置经纬度。
这个时候再访问第一个Demo,发现控制台输出

其中经纬度都变成了我们想要的那个值了。

4.实际应用
其实Geolocation实际应用已经很多了,LBS网站,微博,Google Map都在用。
这里我再提供一个应用的例子。如图所示,可以根据你所在的位置自动将你的省份提到下拉列表的第一位,避免从冗长的列表中寻找自己的所在的省份。Demo地址:http://ali-47418w.hz.ali.com/geolocation/province.html



5.题外话
I.如何计算两个坐标点之间的距离?
几乎所有的LBS应用都有这个功能,就是XXX地点距离你多远,XXX好友距离你多远。通过前面的介绍我们可以获得两个地点的坐标,那么怎么计算他们之间的距离呢?注意,地球是圆的……

其实这是个数学问题啦,我找了一下,有一个球面半正矢公式(haversine formula),详细介绍在这里:http://en.wikipedia.org/wiki/Haversine_formula,这个文章比较理论,看得我有点晕了,不过搬来用是没问题的。直接看代码的话这里有一个:http://www.movable-type.co.uk/scripts/latlong.html。

II.移动设备是怎样定位的?
1. 卫星定位:这个就不用多说了,大家都知道的。除了美国的GPS,还有俄罗斯的GLONASS,欧盟的Galileo和我国的北斗。这个定位是非常精确的,一般可以精确到10米左右。
2. 基站定位:这个定位方式通常在接入了移动通讯网络的设备上才有。这类设备会接入附近的一个通信基站,而每个通信基站的位置其实是固定和公开的(这个网站可以查询全球各个国家基站位置,以及各个运营商在不同地区的信号覆盖范围http://opensignal.com/)。所以说,我们只要知道了基站的编号,就可以粗略的确定你的位置。有HTC/Samsung/MOTO/Sony Ericsson/小米(其他品牌手机查询方式可能不同)Android手机的同学可以在拨号键盘输入 *#*#4636#*#* , 选择 “手机信息”查看自己的基站信息。把16进制的LAC和CELL ID转换为10进制,然后去这个网站搜索,就可与看到自己的粗略位置http://lbs.juhe.cn/cell.php。


3. WIFI定位:用过Google地图的同学都知道,打开google地图的同时,他要求你打开wifi。其实wifi定位原理和基站定位差不多,每个wifi路由器都有一个全球唯一的MAC地址。如果不是那种便携式的路由器,那么他的地理位置也基本是固定的。在使用Google地图时候打开wifi,一方面可以帮助你下载卫星数据,加速定位;一方面也可以通过MAC地址,在没有GPS信号的室内,辅助定位。如果你勾选了帮助google改善定位服务的选项的话,他Google会用你的其他地理位置数据来校准这个MAC地址对应路由器的地理位置。

4. IP定位:这个真不用多说了,最不靠谱就是这个,最通用的也是这个,只要能上网的设备都能用这个方法定位。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值