前端html,vue使用第三方地图详细教程,以百度地图为例,实现地图标注,导航,定位,路线规划,坐标转换

目录

示例:

准备:

?编辑

开始:

1、新建页面,在script标签中引入百度地图的api数据,把自己在控制台创建的应用的ak替换上去

2、创建一个dom对象,设置宽高

3、在js中初始化地图

进阶:

1、地图标注

2、定位

3、导航

?编辑

4、公交路线规划

6、坐标转化

完整demo代码:


示例:

完整demo截图:

准备:

1、注册百度地图api账号,地址:百度地图开放平台

2、进入控制台 - 应用管理 - 我的应用 - 创建应用,填写相关信息

开始:

1、新建页面,在script标签中引入百度地图的api数据,把自己在控制台创建的应用的ak替换上去
复制代码
    <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=这里替换成自己的ak">
    </script>
2、创建一个dom对象,设置宽高
复制代码
<div id="map" class="mapBox"></div>
3、在js中初始化地图
复制代码
// 初始化地图
initMap(){
    var map = new BMapGL.Map("map");//绑定创建的dom元素的id
    var point = new BMapGL.Point(116.404, 39.915);  // 创建点坐标 
    map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
    map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
},

完成以上步骤就能看到基础的一张地图了

进阶:

1、地图标注

实现效果,点击地图弹出弹框,输入信息,添加一个标注点。

要实现该效果首先要监听点击事件

复制代码
this.map.addEventListener('click', this.addLabel);

点击添加标注点

复制代码
// 添加地图标点
addLabel(e) {
    let that = this
    var point =  new BMapGL.Point(e.latlng.lng, e.latlng.lat)
    var mk = new BMapGL.Marker(point);
    console.log(mk);
    this.$prompt('请输入内容', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    }).then(({ value }) => {
        mk.id = Math.random()*100000000000000000
        mk.text = value?value:''
        console.log(mk);
        this.mkList.push({id:mk.id,text:mk.text,latLng:mk.latLng})
        this.map.addOverlay(mk);
        var opts = {
            width : 200,     // 信息窗口宽度
            height: 100,     // 信息窗口高度
            title : "" , // 信息窗口标题
            message:""
        }
        var infoWindow = new BMapGL.InfoWindow(value?value:'', opts);  // 创建信息窗口对象 
        mk.addEventListener("click", function(e){
            that.map.openInfoWindow(infoWindow, point); //开启信息窗口
        });
    }).catch(() => {
        
    });
},

删除标点(根据添加时生成的id去标点集合里匹配,删除对应id 的数据)

复制代码
// 删除地图标点
deleteLabelById(id){
    var allOverlay = this.map.getOverlays();
    for (var i = 0; i < allOverlay.length ; i++){
        if(allOverlay[i].id&&allOverlay[i].id==id){
            this.map.removeOverlay(allOverlay[i]);
        }
    }
},
2、定位
复制代码
// 获取定位
var geolocation = new BMapGL.Geolocation();
geolocation.getCurrentPosition(function(r){
    if(this.getStatus() == BMAP_STATUS_SUCCESS){
        map.centerAndZoom(r.point, 15); //r.point就是当前定位坐标,设置为地图中心点
        var mk = new BMapGL.Marker(r.point); 
        map.addOverlay(mk);//添加标点
        map.panTo(r.point);
        console.log('您的位置:' + r.point.lng + ',' + r.point.lat);
        that.city = r.address.city
        that.address = `${r.address.province}-${r.address.city}-${r.address.district}-${r.address.street}-${r.address.street_number}号` //中文 详细地址
    }
    else {
        alert('failed' + this.getStatus());
    } 
});
3、导航

(this.p1是终点坐标,this.p2是起点坐标)

复制代码
if(this.type==1){
    // 行车导航路线规划
    var output = ''
    this.driving = new BMapGL.DrivingRoute(this.map, {
        renderOptions:{map: this.map, autoViewport: true},
        onSearchComplete: function(results){
            if (that.driving.getStatus() != BMAP_STATUS_SUCCESS){
                return ;
            }
            var plan = results.getPlan(0);
            output += '总时长:' + plan.getDuration(true);  //获取时间
            output += '总路程:' + plan.getDistance(true);  //获取距离
            that.output = output
            console.log(output)
        },
    });
    // p2,p1为起点和目标点的坐标
    this.driving.search(this.p2, this.p1);
}else if(this.type==2){
    // 公交路线规划
    var output = ''
    this.transit = new BMapGL.TransitRoute(this.map,{
    renderOptions: {map: this.map,panel:'panel'},
    onSearchComplete: function(results){
            if (that.transit.getStatus() != BMAP_STATUS_SUCCESS){
                return ;
            }
            var plan = results.getPlan(0);
            output += '总时长:' + plan.getDuration(true);  //获取时间
            output += '总路程:' + plan.getDistance(true);  //获取距离
            that.output = output
            console.log(output)
        },
    });
    this.transit.search(this.p2, this.p1);
}else{
    // 步行路线规划
    var output = ''
    this.walking = new BMapGL.WalkingRoute(this.map, {
        renderOptions:{map: this.map, autoViewport: true},
        onSearchComplete: function(results){
            if (that.walking.getStatus() != BMAP_STATUS_SUCCESS){
                return ;
            }
            var plan = results.getPlan(0);
            output += '总时长:' + plan.getDuration(true);  //获取时间
            output += '总路程:' + plan.getDistance(true);  //获取距离
            that.output = output
            console.log(output)
        },
    });
    this.walking.search(this.p2, this.p1);
}
4、公交路线规划

注意:公交车导航可以配置以下参数获取公交路线规划

复制代码
<div id="panel"></div>

renderOptions: {map: this.map,panel:'panel'},
6、坐标转化

目前国内主要有以下三种坐标系:

WGS84:为一种大地坐标系,也是目前广泛使用的GPS全球卫星定位系统使用的坐标系。

GCJ02:又称火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。

BD09:为百度坐标系,在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标。

非中国地区地图,服务坐标统一使用WGS84坐标。

百度地图需要用BD09坐标,如果是天地图坐标(WGS84),则需要作转化

WGS84 -- 转--> BD09

复制代码
var convertor = new BMapGL.Convertor();
let point = new BMapGL.Point(intitude,latitude) //intitude,latitude为天地图坐标
convertor.translate([point], COORDINATES_WGS84, COORDINATES_BD09, (data)=>{
    if(data.status === 0) {
        let point = data.points[0]
        if(point){
            // 此时得到的就是百度地图坐标
            console.log(point)
        }
    }
})

完整demo代码:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>百度地图功能demo</title>
    <link rel="stylesheet" href="/css/element.css">
    <script src="/js/vue.min.js"></script>
    <script src="/js/element.js"></script>
    <!-- 这里替换成自己的ak -->
    <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&&type=webgl&ak='自己的ak'">
    </script>
    <style>
        body {
            margin: 0;
            box-sizing: border-box;
        }
        .mapBox {
            /* width: calc(100vw - 400px); */
            flex-grow: 1;
            height: 100vh;
        }
        .leftBox {
            width: 400px;
            height: 100vh;
            box-sizing: border-box;
            overflow-y: auto;
            overflow-x: hidden;
            transition: 0.6s;
        }
        .leftBoxHide {
            width: 0px;
            height: 100vh;
            box-sizing: border-box;
            overflow-y: auto;
            overflow-x: hidden;
            transition: 0.6s;
        }
        .tool {
            width: 400px;
            height: 270px;
            border-radius: 5px;
            font-size: 12px;
            padding: 10px;
            box-sizing: border-box;
        }
        .infoBox {
            padding: 0 5px;
        }
        .icon {
            position: fixed;
            bottom: 10px;
            left: 10px;
            width: 40px;
            height: 40px;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #fff;
            z-index: 99;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div id="app" style="display: flex;position: relative;">
        <div class="icon" @click="clickShowTool">
            <img src="./component.png" alt="" style="width: 30px;height: 30px;">
        </div>
        <div :class="toolStatus?'leftBox':'leftBoxHide'">
            <div class="tool">
                <div>
                    <span>当前位置:</span>
                    <span v-if="address">{{address}}</span>
                    <span v-else>暂无定位</span>
                </div>
                <div v-if="p2" style="padding-top: 10px;">地址坐标:({{p2.lng}},{{p2.lat}})</div>
                <div style="display: flex;align-items: center;padding-top: 10px;">
                    <div>目的地:</div>
                    <div>
                        <el-input v-model="keyWords" size="small"></el-input>
                    </div>
                    <div style="margin-left: 10px;">
                        <el-button type="primary" size="small" @click="searchArea">搜索</el-button>
                        <el-button type="primary" size="small" @click="searchArea('dh')">导航</el-button>
                    </div>
                </div>
                <div style="display: flex;align-items: center;padding-top: 10px;">
                    <div>规划导航路线:</div>
                    <div>
                        <el-select v-model="type" size="small" placeholder="请选择" @change="change">
                            <el-option
                                v-for="item in options"
                                :key="item.value"
                                :label="item.label"
                                :value="item.value">
                            </el-option>
                        </el-select>
                    </div>
                </div>
                <div style="display: flex;align-items: center;padding-top: 10px;">
                    <div>开启/关闭交通流量情况:</div>
                    <div>
                        <el-switch
                            v-model="switchVal"
                            size="small"
                            @change="changeSwitch"
                        />
                    </div>
                </div>
                <div style="display: flex;align-items: center;padding-top: 10px;">
                    <div>开启/关闭地图标注(
                        <font color="red">单击添加</font>
                        ):</div>
                    <div>
                        <el-switch
                            v-model="mapLabel"
                            size="small"
                            @change="changeSwitchLabel"
                        />
                    </div>
                </div>
                <div style="display: flex;align-items: center;padding-top: 10px;">
                    <div>显示/隐藏地图标注</div>
                    <div>
                        <el-switch
                            v-model="mapLabel2"
                            size="small"
                            @change="changeSwitchLabel2"
                        />
                    </div>
                </div>
                <div style="padding-top: 10px;" v-if="type==1||type==3">{{output}}</div>
            </div>
            <div class="infoBox">
                <div id="panel"></div>
            </div>
        </div>
        <div id="map" class="mapBox"></div>
    </div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data () {
            return {
                mapLabel:false,
                mapLabel2:false,
                switchVal:false,
                toolStatus:false,
                map:null,
                type:1,
                p1:null,
                p2:null,
                address:'',
                options:[
                    {label:'行车',value:1},
                    {label:'公交',value:2},
                    {label:'步行',value:3},
                ],
                output:'',
                keyWords:'',
                city:'',
                driving:null,
                transit:null,
                walking:null,
                mkList:[],
            }
        },
        mounted () {
            this.initMap()
            this.mkList = window.localStorage.getItem('nkList')?JSON.parse(window.localStorage.getItem('nkList')):[]
            // console.log(JSON.parse(this.mkList));
            let that = this
            window.addEventListener("beforeunload", function(e) { 
                if(that.mkList.length){
                    window.localStorage.setItem('nkList',JSON.stringify(that.mkList))
                }
            });
        },
        methods: {
            // 开启关闭地图标注
            changeSwitchLabel(e){
                this.mapLabel = e
                if(e){
                    // 开启地图点击事件监听
                    this.map.addEventListener('click', this.addLabel);
                }else{
                    this.map.removeEventListener("click",this.addLabel);
                }
            },
            //显示隐藏地图标注 
            changeSwitchLabel2(e){
                this.mapLabel2 = e
                if(e){
                    // 回显标点
                    let that = this
                    this.mkList.forEach((item)=>{
                        var mk = new BMapGL.Marker(item.latLng);
                        mk.id = item.id
                        mk.text = item.text
                        console.log(mk);
                        that.map.addOverlay(mk);
                        var opts = {
                            width : 200,     // 信息窗口宽度
                            height: 100,     // 信息窗口高度
                            title : "" , // 信息窗口标题
                            message:""
                        }
                        var infoWindow = new BMapGL.InfoWindow(item.text, opts);  // 创建信息窗口对象 
                        mk.addEventListener("click", function(e){
                            that.map.openInfoWindow(infoWindow, item.latLng); //开启信息窗口
                        });
                        mk.addEventListener('dblclick',function(e){
                            that.p1 = new BMapGL.Point(item.latLng.lng,item.latLng.lat)
                            that.change()
                        })
                    })
                }else{
                    console.log(this.driving,this.transit,this.walking);
                    this.driving?.clearResults();
                    this.transit?.clearResults();
                    this.walking?.clearResults();
                    console.log(this.driving,this.transit,this.walking);
                    // 删除标点
                    this.mkList.forEach((item)=>{
                        this.deleteLabelById(item.id)
                    })
                }
            },
            // 开启关闭交流流量图
            changeSwitch(e){
                console.log(e);
                this.switchVal = e
                if(e){
                    this.map.setTrafficOn(); // 添加交通流量图层
                }else{
                    this.map.setTrafficOff(); // 移除交通流量图层
                }
            },
            // 切换出行路线规划方式
            change(){
                console.log(this.p1,this.p2);
                if(!(this.p1&&this.p2)){
                    return
                }
                this.driving?.clearResults();
                this.transit?.clearResults();
                this.walking?.clearResults();
                let that = this
                that.output = ''
                console.log(this.type);
                if(this.type==1){
                    // 行车导航路线规划
                    var output = ''
                    this.driving = new BMapGL.DrivingRoute(this.map, {
                        renderOptions:{map: this.map, autoViewport: true},
                        onSearchComplete: function(results){
                            if (that.driving.getStatus() != BMAP_STATUS_SUCCESS){
                                return ;
                            }
                            var plan = results.getPlan(0);
                            output += '总时长:' + plan.getDuration(true);  //获取时间
                            output += '总路程:' + plan.getDistance(true);  //获取距离
                            that.output = output
                            console.log(output)
                        },
                    });
                    // p2,p1为起点和目标点的坐标
                    that.driving.search(this.p2, this.p1);
                }else if(this.type==2){
                    // 公交路线规划
                    var output = ''
                    this.transit = new BMapGL.TransitRoute(this.map,{
                    renderOptions: {map: this.map,panel:'panel'},
                    onSearchComplete: function(results){
                            if (that.transit.getStatus() != BMAP_STATUS_SUCCESS){
                                return ;
                            }
                            var plan = results.getPlan(0);
                            output += '总时长:' + plan.getDuration(true);  //获取时间
                            output += '总路程:' + plan.getDistance(true);  //获取距离
                            that.output = output
                            console.log(output)
                        },
                    });
                    that.transit.search(this.p2, this.p1);
                }else{
                    // 步行路线规划
                    var output = ''
                    this.walking = new BMapGL.WalkingRoute(this.map, {
                        renderOptions:{map: this.map, autoViewport: true},
                        onSearchComplete: function(results){
                            if (that.walking.getStatus() != BMAP_STATUS_SUCCESS){
                                return ;
                            }
                            var plan = results.getPlan(0);
                            output += '总时长:' + plan.getDuration(true);  //获取时间
                            output += '总路程:' + plan.getDistance(true);  //获取距离
                            that.output = output
                            console.log(output)
                        },
                    });
                    that.walking.search(this.p2, this.p1);
                }
            },
            // 初始化地图
            initMap(){
                let that = this
                var map = new BMapGL.Map("map"); //绑定创建的dom元素的id
                that.map = map
                map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
                // 获取定位
                var geolocation = new BMapGL.Geolocation();
                geolocation.getCurrentPosition(function(r){
                    if(this.getStatus() == BMAP_STATUS_SUCCESS){
                        console.log(r);
                        that.p2 = r.point
                        map.centerAndZoom(r.point, 15);
                        var mk = new BMapGL.Marker(r.point);
                        map.addOverlay(mk);
                        map.panTo(r.point);
                        console.log('您的位置:' + r.point.lng + ',' + r.point.lat);
                        that.city = r.address.city
                        that.address = `${r.address.province}-${r.address.city}-${r.address.district}-${r.address.street}-${r.address.street_number}号`
                    }
                    else {
                        alert('failed' + this.getStatus());
                    } 
                });

                console.log(11,map);
            },
            // 搜索地区
            searchArea(i){
                this.deleteLabelById('searchLabel')
                this.driving?.clearResults();
                this.transit?.clearResults();
                this.walking?.clearResults();
                if(!this.keyWords)return
                let that = this
                console.log(this.keyWords);
                //创建地址解析器实例
                var myGeo = new BMapGL.Geocoder();
                // 将地址解析结果显示在地图上,并调整地图视野
                myGeo.getPoint(this.keyWords, function(point){
                    if(point){
                        that.map.centerAndZoom(point, 16);
                         // //创建地址标注
                        var marker = new BMapGL.Marker(point);  // 创建标注
                        marker.id = 'searchLabel'
                        that.map.addOverlay(marker);
                        that.p1 = point
                        if(i=='dh'){
                            that.change()
                        }
                    }else{
                        alert('您选择的地址没有解析到结果!');
                    }
                }, that.city)
            },
            // 添加地图标点
            addLabel(e) {
                let that = this
                var point =  new BMapGL.Point(e.latlng.lng, e.latlng.lat)
                var mk = new BMapGL.Marker(point);
                console.log(mk);
                this.$prompt('请输入内容', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                }).then(({ value }) => {
                    mk.id = Math.random()*100000000000000000
                    mk.text = value?value:''
                    console.log(mk);
                    this.mkList.push({id:mk.id,text:mk.text,latLng:mk.latLng})
                    this.map.addOverlay(mk);
                    var opts = {
                        width : 200,     // 信息窗口宽度
                        height: 100,     // 信息窗口高度
                        title : "" , // 信息窗口标题
                        message:""
                    }
                    var infoWindow = new BMapGL.InfoWindow(value?value:'', opts);  // 创建信息窗口对象 
                    mk.addEventListener("click", function(e){
                        that.map.openInfoWindow(infoWindow, point); //开启信息窗口
                    });
                }).catch(() => {
                    
                });
            },
            // 删除地图标点
            deleteLabelById(id){
                var allOverlay = this.map.getOverlays();
                for (var i = 0; i < allOverlay.length ; i++){
                    if(allOverlay[i].id&&allOverlay[i].id==id){
                        this.map.removeOverlay(allOverlay[i]);
                    }
                }
            },
            // 点击显隐工具栏
            clickShowTool(){
                console.log('aaa');
                this.toolStatus = !this.toolStatus
            }
        },

    })
</script>
</html>
相关推荐
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端