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

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

2024-09-30 23:09:15 前端知识 前端哥 535 400 我要收藏

目录

示例:

准备:

​编辑

开始:

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>

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18788.html
标签
评论
发布的文章

jQuery QueryBuilder 教程

2024-10-29 23:10:44

水球图 及各种参数设置

2024-10-29 23:10:13

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!