【高德地图API】从零开始学高德JS API(七)——定位方式大揭秘
摘要:关于定位,分为GPS定位和网络定位2种。GPS定位,精度较高,可达到10米,但室内不可用,且超级费电。网络定位,分为wifi定位和基站定位,都是通过获取wifi或者基站信息,然后查询对应的wifi或者基站位置数据库,得到的定位地点。定位数据库可以不断完善不断补充,所以,越定位越准确。本文详细描述了,如果使用高德JS API来实现位置定位、城市定位的方法,包含了IP定位,浏览器定位,检索定位等多种网络定位方法。当然,如果您的手机有GPS功能,那么使用浏览器定位的时候,会自动获取GPS信息,使得定位更加准确。
--------------------------------------------------------------------------------
一、浏览器定位
浏览器定位插件,封装了标准HTML5定位,并且包含纠偏模块。
由于核心是HTML5定位,所以浏览器定位插件仅适用于支持HTML5的浏览器上,比如,Internet Explorer 9、Firefox、Chrome、Safari 以及 Opera 等。同时,需要浏览器允许该服务进行定位。如下图:
另外,浏览器定位插件也是混合定位,获取了wifi、基站信息用以定位,对于拥有 GPS 的设备,比如 iPhone,由于获得GPS信息,使得地理定位更加精确。
浏览器定位,最好使用在手机浏览器上,会更加准确,也更加符合使用场景。PC浏览器上,建议使用IP定位。
定位代码:
var geolocation; mapObj.plugin(["AMap.Geolocation"],function(){ //添加浏览器定位服务插件 var geoOptions={ enableHighAccuracy:true, //是否使用高精度 timeout:3000, //若在指定时间内未定位成功,返回超时错误信息。默认无穷大。 maximumAge:1000 //缓存毫秒数。定位成功后,定位结果的保留时间。默认0。 }; geolocation=new AMap.Geolocation(geoOptions); AMap.event.addListener(geolocation , ‘complete’,geolocationResult); //定位成功后的回调函数 });
效果图:
二、IP定位
通过网络获取IP信息,然后查询IP数据库,获取相应的地址信息。非常适用于城市切换的场景,比如团购、酒店、天气等。
IP数据库也是可以完善补充,越来越丰富的,所以也是越使用越准确的。
但如果IP有跳转,有篡改等,那么IP定位就会不准确了。
//加载IP定位插件 mapObj.plugin(["AMap.CitySearch"], function() { //实例化城市查询类 var citysearch = new AMap.CitySearch(); //自动获取用户IP,返回当前城市 citysearch.getLocalCity(); AMap.event.addListener(citysearch, "complete", function(result){ if(result && result.city && result.bounds) { var cityinfo = result.city; var citybounds = result.bounds; document.getElementById(‘result‘).innerHTML = "您当前所在城市:"+cityinfo+""; //地图显示当前城市 mapObj.setBounds(citybounds); } else { document.getElementById(‘result‘).innerHTML = "您当前所在城市:"+result.info+""; } }); AMap.event.addListener(citysearch, "error", function(result){alert(result.info);}); });
效果图:
还有一种“偷懒儿”的方法,是高德浏览器定位的后门,就是使用默认定位。即,在地图初始化时,不填入中心点center和地图级别level,那么高德会自动帮你定位。
但是这也有危险,就是如果定位失败了,也没啥提示。
自动定位代码:
function mapInit () {
mapObj = new AMap.Map(‘iCenter‘); //默认定位:初始化加载地图时,center及level属性缺省,地图默认显示用户所在城市范围
};
三、检索定位
当浏览器定位和IP定位都失败时,可以通过关键字查询,来定位城市甚至街道。
1、POI检索,关键词检索
通过一些简短的关键词,检索一个地点,使用AMap.PlaceSearch地点搜索服务插件。检索到地点后,默认显示第一个点的位置即可。
参数对象PlaceSearchOptions允许设置搜索城市、搜索数据类别、搜索结果详略、搜索结果排序规则等。
代码:
var MSearch; var key_1; function placeSearch() { //POI搜索,关键字查询 key_1 = document.getElementById("key_1").value; document.getElementById(‘result‘).innerHTML = "您输入的是:" + key_1; mapObj.plugin(["AMap.PlaceSearch"], function() { //构造地点查询类 MSearch = new AMap.PlaceSearch({ pageSize:10, pageIndex:1, city:"021" //城市 }); AMap.event.addListener(MSearch, "complete", function(data){ var poiArr = data.poiList.pois; var lngX = poiArr[0].location.getLng(); var latY = poiArr[0].location.getLat(); mapObj.setCenter(new AMap.LngLat(lngX, latY)); });//返回地点查询结果 MSearch.search(key_1); //关键字查询 }); }
2、地址解析
AMap.Geocoder地理编码服务插件,是指将地址信息和地理坐标点信息进行相互转化,包括将地址信息转换为地理坐标点的编码,将地理坐标点转换为地址信息的逆地理编码。
我们使用地址解析。地址解析,是通过将结构化地址信息,解析成经纬度,然后设置地图中心点。
代码:
var MGeocoder; var key_2; function geocoder() { //地理编码返回结果展示 key_2 = document.getElementById("key_2").value; document.getElementById(‘result‘).innerHTML = "您输入的是:" + key_2; mapObj.plugin(["AMap.Geocoder"], function() { //加载地理编码插件 MGeocoder = new AMap.Geocoder({ city:"010", //城市,默认:“全国” radius:1000 //范围,默认:500 }); //返回地理编码结果 AMap.event.addListener(MGeocoder, "complete", function(data){ var geocode = data.geocodes; var lngX = geocode[0].location.getLng(); var latY = geocode[0].location.getLat(); mapObj.setCenter(new AMap.LngLat(lngX, latY)); }); MGeocoder.getLocation(key_2); //地理编码 }); }
四、源代码与示例
全部源代码:
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>定位</title> <link rel="stylesheet" type="text/css" href="zero.css" /> <script language="javascript" src="http://webapi.amap.com/maps?v=1.3&key=【您的key】"></script> </head> <body onLoad="mapInit()"> <div id="iCenter"></div> <div id="iControlbox"> <ul> <li> <button onclick="javascript:getCurrentPosition();">浏览器定位</button> </li> <li> <button onclick="javascript:showCityInfo();">IP定位</button> </li> <li> <input type="text" id="key_1" value="上海市" /> <button onclick="javascript:placeSearch();">关键字定位</button> </li> <li> <input type="text" id="key_2" value="北京市朝阳区大屯路" /> <button onclick="javascript:geocoder();">地址定位</button> </li> </ul> </div> <div id="result"></div> </body> <script language="javascript"> var mapObj, geolocation; var result; function mapInit () { mapObj = new AMap.Map(‘iCenter‘); //默认定位:初始化加载地图时,center及level属性缺省,地图默认显示用户所在城市范围 }; function getCurrentPosition () { //调用浏览器定位服务 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); AMap.event.addListener(geolocation, ‘complete‘, onComplete);//返回定位信息 AMap.event.addListener(geolocation, ‘error‘, onError); //返回定位出错信息 }); }; function onComplete (data) { //解析定位结果 var str = ‘<p>定位成功</p>‘; str += ‘<p>经度:‘ + data.position.getLng() + ‘</p>‘; str += ‘<p>纬度:‘ + data.position.getLat() + ‘</p>‘; str += ‘<p>精度:‘ + data.accuracy + ‘ 米</p>‘; str += ‘<p>是否经过偏移:‘ + (data.isConverted ? ‘是‘ : ‘否‘) + ‘</p>‘; result.innerHTML = str; }; function onError (data) { //解析定位错误信息 var str = ‘<p>定位失败</p>‘; str += ‘<p>错误信息:‘ switch(data.info) { case ‘PERMISSION_DENIED‘: str += ‘浏览器阻止了定位操作‘; break; case ‘POSITION_UNAVAILBLE‘: str += ‘无法获得当前位置‘; break; case ‘TIMEOUT‘: str += ‘定位超时‘; break; default: str += ‘未知错误‘; break; } str += ‘</p>‘; result.innerHTML = str; }; function showCityInfo() { //IP定位 //加载IP定位插件 mapObj.plugin(["AMap.CitySearch"], function() { //实例化城市查询类 var citysearch = new AMap.CitySearch(); //自动获取用户IP,返回当前城市 citysearch.getLocalCity(); AMap.event.addListener(citysearch, "complete", function(result){ if(result && result.city && result.bounds) { var cityinfo = result.city; var citybounds = result.bounds; document.getElementById(‘result‘).innerHTML = "您当前所在城市:"+cityinfo+""; //地图显示当前城市 mapObj.setBounds(citybounds); } else { document.getElementById(‘result‘).innerHTML = "您当前所在城市:"+result.info+""; } }); AMap.event.addListener(citysearch, "error", function(result){alert(result.info);}); }); } var MSearch; var key_1; function placeSearch() { //POI搜索,关键字查询 key_1 = document.getElementById("key_1").value; document.getElementById(‘result‘).innerHTML = "您输入的是:" + key_1; mapObj.plugin(["AMap.PlaceSearch"], function() { //构造地点查询类 MSearch = new AMap.PlaceSearch({ pageSize:10, pageIndex:1, city:"021" //城市 }); AMap.event.addListener(MSearch, "complete", function(data){ var poiArr = data.poiList.pois; var lngX = poiArr[0].location.getLng(); var latY = poiArr[0].location.getLat(); mapObj.setCenter(new AMap.LngLat(lngX, latY)); });//返回地点查询结果 MSearch.search(key_1); //关键字查询 }); } var MGeocoder; var key_2; function geocoder() { //地理编码返回结果展示 key_2 = document.getElementById("key_2").value; document.getElementById(‘result‘).innerHTML = "您输入的是:" + key_2; mapObj.plugin(["AMap.Geocoder"], function() { //加载地理编码插件 MGeocoder = new AMap.Geocoder({ city:"010", //城市,默认:“全国” radius:1000 //范围,默认:500 }); //返回地理编码结果 AMap.event.addListener(MGeocoder, "complete", function(data){ var geocode = data.geocodes; var lngX = geocode[0].location.getLng(); var latY = geocode[0].location.getLat(); mapObj.setCenter(new AMap.LngLat(lngX, latY)); }); MGeocoder.getLocation(key_2); //地理编码 }); } </script> </html>
效果图:
demo地址:http://zhaoziang.com/amap/zero_7_1.html