一、去百度地图开放申请应用
二、在manifest.json中配置sdk和权限
三、使用定位的代码
//获取用户定位
plus.geolocation.getCurrentPosition( function ( p ) {
storagePosition(p);
}, function ( e ) {
mui.alert('定位失败:'+ e.message);
},{provider:'amap'});//gcj02ll坐标系
//监听设备位置变化信息
plus.geolocation.watchPosition( function ( p ) {
storagePosition(p);
}, function ( e ) {
mui.alert('实时定位失败:'+ e.message);
},{provider:'amap'});//gcj02ll坐标系
由于获取到的定位信息不是每次都有城市等信息,可能只有坐标,所以在一定需要城市等信息的情况下,可以再通过百度的一个接口反向地址解析一下,又因为这个是发送ajax的,而如果监听了设备位置变化plus.geolocation.watchPosition,就会变得访问很频繁,不是很好,所以加上计算当前获取到的经纬度与原来的经纬度之间的距离,离得太远了再反向地址解析也没问题。
/**
* 存储设备定位信息
* @param {Object} p
*/
function storagePosition(p){
if(!isValidObject(p)){
return false;
}
//如果地址没有定位到,再通过baidu地图js接口,参数经纬度,获取地址
if(!isValidObject(p.address) || !isValidString(p.address.city) || !isValidString(p.address.district)){
var op = localStorageGetJSON('position');//这里是获取原来保存的定位信息
if(!isValidObject(op)
|| distance(p.coords.longitude, p.coords.latitude,op.coords.longitude, op.coords.latitude)>1){//超过1公里,需要根据经纬度查一下地址
localStorageSetJSON('position', p);//先保存不带address的p,在storageAddress方法中会把城市信息补上
storageAddress(p.coords.longitude, p.coords.latitude);//这个方法中会取出不带address的p,获取到address后再添加保存回p
}
}else{//直接保存带address的p,再根据address信息保存系统地址代码表对应的地址与代码
localStorageSetJSON('position', p);
storagePositionSysAddress();
}
}
一个反向地址解析的方法:
/**
* 反向地址解析并存储设备地址信息
* 使用经纬度,通过百度js接口,再次获取地址信息
* @param {Object} p
*/
function storageAddress(longitude,latitude){
mui.ajax('https://api.map.baidu.com/geocoder/v2/',{
data:{
ak : '你的百度地图浏览器端ak',
location : latitude+','+longitude,
output : 'json',
pois : 0,
coordtype : 'gcj02ll'
},
async:true,
dataType:'json',//服务器返回json格式数据
type:'post',//HTTP请求类型
timeout:30000,//超时时间设置为10秒;
crossDomain:true,
success:function(data){
if(data.status == 0){
var p = localStorageGetJSON('position');
var address={
country:data.result.addressComponent.country,
province:data.result.addressComponent.province,
city:data.result.addressComponent.city,
district:data.result.addressComponent.district,
street:data.result.addressComponent.street
};
p.address = address;
localStorageSetJSON('position',p);//把城市信息补上
}else{
mui.toast('反向地址解析失败:'+data.status);
}
},
error:function(xhr,type,errorThrown){
// alert('反向地址解析失败:'+type+' '+errorThrown);
console.log('反向地址解析失败:'+type+' '+errorThrown);
}
});
}
四、使用百度地图
下面是html body中的代码:
<header class="mui-bar mui-bar-nav" id="header">
<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
<h1 class="mui-title">地图</h1>
</header>
<div class="mui-content">
<div id="map">
地图加载中...
</div>
</div>
关键的js代码来了:
var p = localStorageGetJSON('position');
var mMarker;
//地图
var map = new plus.maps.Map('map');
//把自己的位置标记在地图上
if(isValidObject(p)){
var mpoint = new plus.maps.Point(p.coords.longitude, p.coords.latitude);
plus.maps.Map.convertCoordinates(mpoint, {coordType:'gcj02'},
function(e){
mpoint = new plus.maps.Point(e.coord.longitude, e.coord.latitude);
map.setCenter(mpoint);
map.setZoom(12);
var img = 'img/logo.png';//只支持项目下的图片
mMarker = addMarker(mpoint,img,defaultString(userinfo.FullName),'我的位置');
}, function(e){
mui.toast(JSON.stringify(e));
}
);
}
五、计算两个纬度度之间的距离
/**
* 计算两点之间距离,返回包含单位的字符串类型(经度放前面一是为了符合中国的使用习惯)
* @param {Object} lng1
* @param {Object} lat1
* @param {Object} lng2
* @param {Object} lat2
*/
function distanceResult(lng1, lat1, lng2, lat2){
// 经典计算方式
if ((Math.abs(lat1) > 90 ) || (Math.abs(lat2) > 90 )) {
return "纬度错误";
}
if ((Math.abs(lng1) > 180 ) || (Math.abs(lng2) > 180 )) {
return "经度错误";
}
var result = distance(lng1, lat1, lng2, lat2) * 1000;//单位:米
// console.log(result);
// 整理显示方式
if(result < 50){
result = "50米以内";
}else if(result < 100){
result = Math.ceil(result/10) * 10 + "米以内";
}else if (result < 1000) {
result = Math.ceil(result/100) * 100 + "米以内";
} else if (result < 20000) {
result = Math.ceil(result/1000) + "公里以内";
} else {
result = "20公里以外";
}
return result;
}
/**
* 计算两个纬度度之间的距离
* @param {Object} lng1
* @param {Object} lat1
* @param {Object} lng2
* @param {Object} lat2
*/
function distance(lng1, lat1, lng2, lat2) {
// 经典计算方式
if ((Math.abs(lat1) > 90 ) || (Math.abs(lat2) > 90 )) {
return false;
}
if ((Math.abs(lng1) > 180 ) || (Math.abs(lng2) > 180 )) {
return false;
}
var radLat1 = rad(lat1);
var radLat2 = rad(lat2);
var a = radLat1 - radLat2;
var b = rad(lng1) - rad(lng2);
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * 6378.137;
// EARTH_RADIUS; 单位Km
return Math.round(s * 10000) / 10000;
};
另外注意我这边代码中都使用统一的gcj02坐标系。