通过浏览器获取经纬度及城市信息(百度地图&高德地图JavaScript API)

/ javascript / 没有评论 / 2037浏览

通过浏览器获取经纬度及城市信息(百度地图&高德地图JavaScript API)

资源:

百度地图开放平台JavaScript API v2.0类参考 百度地图开放平台JavaScript API 百度地图开放平台论坛 高德开放平台-地图-JS API-参考手册 高德开放平台 Jacascript API

高德地图定位插件

定位
插件名称说明
AMap.Geolocation定位插件,整合了浏览器定位、精确IP定位、sdk辅助定位多种手段位
AMap.CitySearchy城市查询,IP定位获取当前城市信息
AMap.Geolocation 插件

AMap.Geolocation定位服务插件。融合了浏览器定位、高精度IP定位、安卓定位sdk辅助定位等多种手段,提供了获取当前准确位置、获取当前城市信息、持续定位(浏览器定位)等功能。用户可以通过两种当时获得定位的成败和结果,一种是在getCurrentPosition的时候传入回调函数来处理定位结果,一种是通过事件监听来取得定位结果。

注:默认情况下,PC端优先使用精确IP定位,解决多数浏览器无法完成定位的现状,IP定位失败后使用浏览器定位;手机端优先使用浏览器定位,失败后使用IP定位;对于安卓WebView页面的开发者,可以结合定位sdk进行辅助定位,详细说明见useNative参数。IP定位的精度值为'null'。

由于Chrome、IOS10等已不再支持非安全域的浏览器定位请求,为保证定位成功率和精度,请尽快升级您的站点到HTTPS。

代码示例
mapObj = new AMap.Map('iCenter');
mapObj.plugin('AMap.Geolocation', function () {
    geolocation = new AMap.Geolocation({
        enableHighAccuracy: true,//是否使用高精度定位,默认:true
        timeout: 10000,          //超过10秒后停止定位,默认:无穷大
        maximumAge: 0,           //定位结果缓存0毫秒,默认:0
        convert: true,           //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
        showButton: true,        //显示定位按钮,默认:true
        buttonPosition: 'LB',    //定位按钮停靠位置,默认:'LB',左下角
        buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
        showMarker: true,        //定位成功后在定位到的位置显示点标记,默认:true
        showCircle: true,        //定位成功后用圆圈表示定位精度范围,默认:true
        panToLocation: true,     //定位成功后将定位到的位置作为地图中心点,默认:true
        zoomToAccuracy:true      //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
    });
    mapObj.addControl(geolocation);
    geolocation.getCurrentPosition(); //精准定位
    // geolocation.getCityInfo();  //定位到城市
    AMap.event.addListener(geolocation, 'complete', onComplete);//返回定位信息
    AMap.event.addListener(geolocation, 'error', onError);      //返回定位出错信息
});

Geolocation的定位流程以及定位失败的原因?

JS-API的Geolocation定位插件,融合了HTML5 Geolocation定位接口、精确IP定位服务,以及安卓定位sdk定位。其中与安卓定位sdk的结合使用适用于开发安卓系统的H5应用,需同时使用安卓定位sdk和JS-API。

A. Geolocation.getCurrentPosition获取精确位置的流程是什么样的?
  1. 在PC端,因为原生接口成功率很低,JS-API会优先调用精确IP定位服务,在IP定位失败的时候,尝试使用浏览器原生定位接口进行定位,如果原生定位接口也定位失败,则返回error事件或回调error信息。定位成功之后我们会对浏览器定位的经纬度结果进行向高德坐标的转化,并对所有有效定位结果融合地址信息后返回complete事件或者回调complete信息。
  2. 在移动端,如果开发者开启了sdk辅助定位,那么安卓手机上我们会优先尝试调用sdk的定位接口,失败之后优先调用浏览器原生定位接口进行定位,浏览器定位失败之后尝试进行精确IP定位,如果以上三种定位全部尝试失败则返回error事件或回调error信息,否则和PC端的一样,定位成功之后进行高德坐标转化和地址融合。
  3. 我们在定位的回调或者事件响应中返回了message字段,message字段明确指出了每一步的成功和失败原因。
B. 如果没有拿到message如何获取定位失败错误信息?

可以通过如下方法获取定位失败信息,之后根据定位错误信息参考下一节的说明

//可以拷贝如下代码,使用alert输出定位失败信息
//解析定位错误信息
function onError(data) {
    alert(JSON.stringify(data));
    document.getElementById('tip').innerHTML = '定位失败';
}
C. getCurrentPosition返回的message原因解析:
  1. Get ipLocation failed:IP精确定位失败,精确IP定位服务目前无法完全覆盖所有用户IP,失败率在5%左右;
  2. sdk定位失败:请检查sdk的key是否设置好,以及webview的定位权限及应用和系统的定位权限是否开启。
  3. 浏览器定位失败,有多种情况:

Browser not Support html5 geolocation:浏览器不支持原生定位接口,如IE较低版本的浏览器等 Geolocation permission denied:用户禁用了定位权限,需要用户开启设备和浏览器的定位权限,并在浏览器弹窗中点击“允许使用定位”选项。 Geolocation permission denied:浏览器禁止了非安全域的定位请求,比如Chrome、IOS10已陆续禁止,这时候需要升级站点到HTTPS。注意Chrome不会禁止localhost等域名HTTP协议下的定位 Get geolocation time out:浏览器定位超时,包括原生的超时,可以适当增加超时属性的设定值以减少这一现象,另外还有个别浏览器(如google Chrome浏览器等)本身的定位接口是黑洞,通过其请求定位完全没有回应,也会超时返回失败。 Get geolocation failed:定位失败,Chrome、火狐以及部分套壳浏览器接入的定位服务在国外,有较大限制,失败率高。

注释:如果定位到城市即可满足需求,建议大家改用Geolocation.getCityInfo方法,可以根据IP返回用户所在城市的基本信息,包括省、市名称、adcode、citycode、城市中心点,城市矩形边界等信息。

百度地图JavaScript API

简介

JavaScript API提供在Web端获取当前位置信息的方法,融合了浏览器定位、IP定位、安卓定位SDK辅助定位等多种手段,提供了获取当前准确位置、获取当前城市信息等功能。

浏览器定位精度依赖浏览器自身特性,IP定位的精度值为城市级别。

对于安卓WebView页面的开发者,可以结合定位SDK进行辅助定位,使用方法参见定位SDK相关章节。

注:由于Chrome、iOS10等已不再支持非安全域的浏览器定位请求,为保证定位成功率和精度,请尽快升级您的站点到HTTPS。

提供的定位服务
接口类名简介
浏览器定位Geolocation优先调用浏览器H5定位接口,如果失败会调用IP定位
IP定位LocalCity根据用户IP 返回城市级别的定位结果
定位SDK辅助定位Geolocation......
定位方法代码示例
//浏览器定位
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.331398,39.897445);
map.centerAndZoom(point,12);

var geolocation = new BMap.Geolocation();
geolocation.getCurrentPosition(function(r){
    if(this.getStatus() == BMAP_STATUS_SUCCESS){
        var mk = new BMap.Marker(r.point);
        map.addOverlay(mk);
        map.panTo(r.point);
        alert('您的位置:'+r.point.lng+','+r.point.lat);
    }
    else {
        alert('failed'+this.getStatus());
    }        
});
其他
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=XX"></script>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=XXX"></script>` 

上面这段代码执行完后百度会返回一段代码并插入到你的DOM中执行

(function() {
    window.BMap_loadScriptTime = (new Date).getTime();
    document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=2.0&ak=XX&services=&t=20160513110936"></script>');
})();

在函数执行的时候,经过测试不管是否允许地理位置的授权,都能获取到定位位置,只不过不授权时候获取的应该是IP地址的定位,授权是精确的GPS定位而已。所以在任何一段Javascript脚本中执行上述代码,用户在知道弹出询问是否允许获取地理位置授权这个提示之后,不管是否允许都能获取到使用者的定位的。

注意是geolocation是HTML5的东西,判断一下浏览器是否支持

if ("geolocation" in navigator) {
    alert("支持geolocation");
} else {
    alert("不支持geolocation");
}

百度geolocation.getCurrentPosition()这个函数里面的第一个参数是回调成功后执行的,第二个参数是回调后失败执行的,官网的地址貌似没有写明白第二个参数是可以传一个对象或者匿名函数进去,所以导致很多人不知道getCurrentPosition失效的时候怎么捕捉到这个失败的回调,下面的例子就是传入一个失败时候要执行回调函数,让后面代码能顺利执行下去

var setCookie = function(name, value) {
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
    document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
};
var geolocation = new BMap.Geolocation();
//弹出地理授权  
geolocation.getCurrentPosition(function(r) {
    if (this.getStatus() == BMAP_STATUS_SUCCESS) {
        alert('定位成功');
        console.log(r.point);
    } else {
        alert("baidu return failed");
    }
},function(r) {
    //获取失败时候的回调  
    console.log(r);
    alert('定位失败');
    return {
        //设置高精度  
        enableHighAccuracy: true
    };
});

如果确实因为各种原因而获取不到回调,建议这里加个定时器比较保险

setTimeout(function() {
    alert("获取超时");
    setCookie("longitude", '113.333333');
    setCookie("latitude", '23.333333');
    setCookie("city", 'autumnswind');
    setCookie("cityCode", '543210');
    load();
}, 4000)

无法获取定位的原因:应该是鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的。还有可能是因为某些浏览器调用了谷歌的服务,所以这里会被卡。