uniapp中通过webview实现百度地图Javascript Api 定位、路线规划、标记、导航

场景:使用uniapp的chooseLocation获取位置以及附近地址信息,但是HBuilderX 2.4.0+ 非 weex 编译模式 暂不支持 百度地图
解决思路:使用webview打开本地html,html内使用百度地图提供的 JavaScript Api 实现定位,路线规划

1.在百度地图开放平台 控制台新建应用,应用类型为 浏览器端,生成AK


image.png

2.实现 标记当前位置,点击获取附近数据并标记 Marker ,地点检索,数据传输到uniapp。配有详细注释,效果如下图:


e30e741d50ffa0b16340feb72e736dd.png

代码:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body,html {width: 100%;height: 100%; margin: 0;font-family: "微软雅黑";}
        #allmap {height: 500px; width: 100%;overflow: hidden;}
        #result {height: calc(100% - 610px);width: 100%;font-size: 12px;}
        #resultText { height: 70px;font-size: 18px;padding: 6px;}
        #r-result {height: 40px;width: 100%;display: flex;align-items: center;justify-content: center;
            border-bottom: #A9A9A9 1px solid;margin-bottom: 2px;margin-top: 3px;}
        .btn {width: 100px;height: 34px;border: 1px solid #999;border-radius: 5px;margin: 0 auto;
            font-size: 18px;text-align: center;line-height: 34px;color: #333;background: #E8E7E3;}
    </style>
    <!-- 引入百度地图api 携带 AK -->
    <script type="text/javascript"
        src="http://api.map.baidu.com/api?v=2.0&ak=你的AK"></script>
        <!-- 引入搜索功能 -->
    <script type="text/javascript"
        src="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.js"></script>
    <link rel="stylesheet" href="http://api.map.baidu.com/library/SearchInfoWindow/1.5/src/SearchInfoWindow_min.css" />
    <!-- 引入 uni-app 的 SDK -->
    <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
    <title>订单定位</title>
</head>

<body>
    <!-- 顶部搜索栏 -->
    <div id="search">
        <div id="r-result"><input type="text" id="suggestId" size="20" placeholder="位置搜索" value="百度"
                style="width:100%;height:40px;" /></div>
        <div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div>
    </div>
    <!-- 地图 -->
    <div id="allmap"></div>
    <!-- 选中的位置回显 -->
    <div id="result">
        <div id="resultText"></div>
        <div class="btn">确定地点</div>
    </div>

    <script type="text/javascript">
        var map = new BMap.Map('allmap');
        var poi = new BMap.Point(116.307852, 40.057031); //罗马的坐标

        var addressPost; //存储附近信息数据
        var CURRENT_LNG; //记录坐标
        var CURRENT_LAT; //记录坐标
        var lng, lat; //记录坐标

        map.centerAndZoom(poi, 18); //设置地图中心点 和 缩放等级
        map.enableScrollWheelZoom();//开启鼠标滚轮

        function G(id) {
            return document.getElementById(id);
        }
        //获取当前位置附近地址信息 --- geoc.getLocation
        var geoc = new BMap.Geocoder();
        var getCurrentLocation = function (lg, lt) {
            //geoc.getLocation 获取到 坐标 以及 包含附近地址信息的数组
            geoc.getLocation(new BMap.Point(lg, lt), function (rs) {
                //取数组第一个地址信息为选中的位置,也可现为地址列表
                var nearbyAddeessArr = rs.surroundingPois[0];
                document.getElementById('resultText').innerText = '当前位置 :' + nearbyAddeessArr.title + '——' + nearbyAddeessArr.address;
                addressPost = nearbyAddeessArr.title + '——' + nearbyAddeessArr.address;
                CURRENT_LNG = lg;
                CURRENT_LAT = lt;
            });
        }

       
        //通过浏览器获取当前定位的坐标
        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);
                lng = r.point.lng
                lat = r.point.lat
                getCurrentLocation(lng, lat)
            }
            else {
                alert('failed' + this.getStatus());
            }
        }, { enableHighAccuracy: true })

         //给地图添加点击事件 标记 marker
        map.addEventListener("touchstart", function (e) {   
            map.clearOverlays();//清除地图上所有覆盖物 marker
            //获取坐标
            var lng = e.point.lng;
            var lat = e.point.lat;

            //创建marker标注位置
            var pt = new BMap.Point(lng, lat);
            //new BMap.Icon("本地marker图标路径",图标的尺寸,{marker偏移量,窗口的偏移量})
            var myIcon = new BMap.Icon("本地marker图标路径", new BMap.Size(20, 25), { anchor: new BMap.Size(5, 20), infoWindowAnchor: new BMap.Size(10, 0) });
            var marker2 = new BMap.Marker(pt, { icon: myIcon });  // 创建标注实例
            map.addOverlay(marker2); //将标注添加到地图中
            getCurrentLocation(lng, lat)
        });

        // 以下是地点检索功能

        //创建一个search实例
        var ac = new BMap.Autocomplete(
            {
                "input": "suggestId",
                "location": map
            });

        
        var myValue;//存储地址检索结果
        ac.addEventListener("onconfirm", function (e) {    //鼠标点击下拉列表后的事件
            var _value = e.item.value;
            myValue = _value.province + _value.city + _value.district + _value.street + _value.business;
            G("searchResultPanel").innerHTML = "onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue;
            setPlace();
        });

        // 地图移动到检索的位置,并且标记 
        function setPlace() {
            map.clearOverlays();    //清除地图上所有覆盖物
            function myFun() {
                var pp = local.getResults().getPoi(0).point;    //获取第一个智能搜索的结果
                map.centerAndZoom(pp, 18);
                map.addOverlay(new BMap.Marker(pp));    //添加标注
                getCurrentLocation(pp.lng, pp.lat)
            }
            var local = new BMap.LocalSearch(map, { //智能搜索
                onSearchComplete: myFun
            });
            local.search(myValue);
        }

        //确定地址 将数据传输到 uniapp 的 webview内
        document.addEventListener('UniAppJSBridgeReady', function () {
            //uniapp 挂载完毕,在内部可以使用uniapp 部分 api,具体看 官方文档 webview
            document.querySelector('.btn').addEventListener('touchstart', function () {
                uni.postMessage({
                    data: {
                        addressPost,
                        CURRENT_LNG,
                        CURRENT_LAT
                    }
                });
                uni.navigateBack({
                    delta: 1
                });
            })

        });

    </script>
</body>

</html>

2.根据坐标规划路线 轮循创建当前位置标记 实现“导航”,效果如下图:


60e25a8752e08f270c3d06251573490.png

代码如下:

<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        body,
        html,
        #allmap {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }
    </style>
    <script type="text/javascript"
        src="http://api.map.baidu.com/api?v=2.0&ak=你的AK"></script>
    <title>路线规划</title>
</head>

<body>
    <div id="allmap"></div>
</body>

</html>
<script type="text/javascript">
    // 获取到webview 通过 url 携带的坐标参数
    var paramsArr = window.location.search.substring(1).split(',')

    // 百度地图API功能
    var map = new BMap.Map("allmap");
    map.centerAndZoom(new BMap.Point(41.889899, 12.475339), 18);//设置
    var lng, lat;
    var geolocation = new BMap.Geolocation();
    geolocation.getCurrentPosition(function (r) {
        if (this.getStatus() == BMAP_STATUS_SUCCESS) {
            map.clearOverlays();//清除地图上所有覆盖物
            lng = r.point.lng
            lat = r.point.lat
            var p1 = new BMap.Point(lng, lat);
            var p2 = new BMap.Point(paramsArr[0], paramsArr[1]);

            var driving = new BMap.DrivingRoute(map, { renderOptions: { map: map, autoViewport: true } });
            driving.search(p1, p2);
        }
        else {
            alert('failed' + this.getStatus());
        }
    }, { enableHighAccuracy: true })
  
    ##导航功能 --- 轮循重新规划路线,但是会重置地图的缩放等级。轮循在当前位置创建标记,删除上一个标记
    window.setInterval(function () {
        geolocation.getCurrentPosition(function (r) {
            if (this.getStatus() == BMAP_STATUS_SUCCESS) {
                // map.clearOverlays();//清除地图上所有覆盖物
                lng = r.point.lng
                lat = r.point.lat
                //创建标注位置
                var pt = new BMap.Point(lng, lat);
                var myIcon = new BMap.Icon("../../static/img/Location1.png", new BMap.Size(20, 25), { anchor: new BMap.Size(5, 20), infoWindowAnchor: new BMap.Size(10, 0) });
                var marker2 = new BMap.Marker(pt, { icon: myIcon });  // 创建标注
                //移除上一个标记
                map.removeOverlay(allOverlay[3])
                map.addOverlay(marker2); //方法向地图中添加单个覆盖物时会触发此事件,将标注添加到地图中
            }
            else {
                alert('failed' + this.getStatus());
            }
        }, { enableHighAccuracy: true })
        var allOverlay = map.getOverlays();
    }, 10000)

</script>

3.uniapp 和 webview 通信

  • 根据uniapp官方的说明 将需要跳转的 html 文件放在 hybrid 内
image.png
  • uniapp向H5传参
<template>
  <view>
    <web-view :webview-styles="webviewStyles" @message="getData" :src="src"></web-view>
  </view>
</template>
<script>
export default {
  data() {
    return {
      src:'',
    }
  },
  onLoad(option) {
    this.src = '../../hybrid/html/router.html?' + option.data
  }
};
</script>
  • H5传参到uniapp
//引入uniapp SDK
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uniapp/uni.webview.1.5.2.js"></script>

document.addEventListener('UniAppJSBridgeReady', function () {
                uni.postMessage({
                    data: {} //参数必须是data对象
                });
        });

在webview内接收参数

<template>
  <view>
    <web-view :webview-styles="webviewStyles" @message="getData" src="/hybrid/html/map.html"></web-view>
  </view>
</template>
<script>
export default {
  data() {return {}},
  methods: {
   //event 拿到参数
    getData(event) {
      let data = event.detail.data;
      this.addressClass(this.class);
      this.addressData(data)
    }
  }
};
</script>

如果应用场景在国外,在 腾讯、高德、百度海外服务都收费的状况下使用谷歌地图API,安卓平台需要后台配合打一个https的签名。
【有收获请点个赞哦~~】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343