dcloud混合开发-定位和百度地图

本文介绍如何在移动端应用中使用百度地图SDK实现定位功能,并通过反向地址解析获取详细的地理位置信息。主要内容包括:申请百度地图API密钥、集成SDK、实现定位及监听位置更新、使用百度地图API进行反向地址解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、去百度地图开放申请应用
这里写图片描述

二、在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坐标系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值