百度GIS地图笔记

因我司是搞路桥等基建项目的,故在每个项目中都会牵扯到GIS地图相关的功能。

本篇文章记录下我在Vue.js项目中使用百度GIS地图的一些笔记。


官方文档:https://lbsyun.baidu.com/index.php?title=jspopularGL/guide/show

API类:https://mapopen-pub-jsapi.bj.bcebos.com/jsapi/reference/jsapi_webgl_1_0.html



初始化地图

  1. 引入百度地图API文件

    // index.html
    
    <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=您的密钥"></script>
    

  2. 地图初始化

    // template
    <div id="locationmap"></div>
    
    // script
    mounted() {
        let map = new BMapGL.Map("locationmap", { enableMapClick: false })    // 创建
        map.setMapType(BMAP_EARTH_MAP)  // 卫星地球地图
        map.centerAndZoom(new BMapGL.Point(113.816282, 34.796343), 10)    // 中心点, 缩放比例
        map.setDisplayOptions({poiText: true,poiIcon: false})
        map.enableScrollWheelZoom(true)    // 开启鼠标滚轮缩放
        map.clearOverlays()    // 清除所有覆盖物
        map.disableDragging(true)    // 开启推拽
        map.disableDoubleClickZoom(true)    // 开始双击缩放
        this.MAP = map
    }
    


常用功能

1. 给地图添加标记点和事件

标记点(Marker)是有:icon,point,label组成;其中:label是标记点文字部分, point是标记点显示位置, icon是标记点显示的图标

包含图标、文字内容的标记点

let EmyIcon = new BMapGL.Icon(require("@/assets/img/people_line.svg"), new BMapGL.Size(35, 35));    // 显示的图标
let Epoint = new BMapGL.Point(113.816282, 34.796343)    // 显示的位置
let Emarker = new BMapGL.Marker(Epoint, {icon: EmyIcon});    // 合成marker点

let offsetSize = new BMapGL.Size(-43, 18)    // 距Epoint偏移量
let labelStyle = {    // 样式
    border: 'none',
    background: 'none',
    textAlign: 'center',
    width: '90px',
    whiteSpace: 'normal',
    textShadow: ' 0 0 0.2em #fff, 0 0 0.2em #fff',
    color: '#415a77',//rgb(63 53 200)
}
let label = new BMapGL.Label(‘显示的markder文字’, {offset: offsetSize, position: Epoint})
label.setStyle(labelStyle)    // 设置样式
// label.name = "emergencyAlarm"    // 给标记点添加名称
Emarker.name = "emergencyAlarm"    // 给标记点添加名称,两者添加一个即可
Emarker.setLabel(label)    
Emarker.addEventListener("click", this.func.bind(this, args, args))    // 给标记点添加点击事件
this.MAP.addOverlay(Emarker);    // 在地图上添加覆盖物
this.MAP.centerAndZoom(new BMapGL.Point(经纬度), 10)    // 把地图中心挪到该点的位置 并缩放比例到10

只包含文字内容的标记点(不需要图标时候,不用marker包裹)

let point = new BMapGL.Point(经纬度)
let content = '显示的文字'
let label = new BMapGL.Label(content, {position: point})
label.name = 'stakeMark'
label.setStyle({                              // 设置label的样式
    color: '#fff',
    fontSize: '12px',
    background: 'green',
    padding: "0 3px",
    border: 'none'
})
 map.addOverlay(label)


2. 给地图添加轨迹

let pl = new BMapGL.Polyline(轨迹经纬度列表,{strokeColor:"blue", strokeWeight:6, strokeOpacity:0.8});

trackAni = new BMapGLLib.TrackAnimation(that.winMap, pl, {
    overallView: true, // 动画完成后自动调整视野到总览
    tilt: 55,          // 轨迹播放的角度,默认为55
    duration: duration,   // 动画持续时长,默认为10000,单位ms
    delay: 0        // 动画开始的延迟,默认0,单位ms
});
// 开始轨迹动画
trackAni.start();

// 结束轨迹动画
if (trackAni) {
    trackAni.cancel();         // 强制停止动画
}


3. 给标记点添加自定义动画(呼吸灯动画)

  1. 存储要添加动画的标记点

    // 显示的图标,添加css动画背景的话建议此图标为透明的
    let icon = new BMapGL.Icon(require("@/assets/img/people_line.svg"), new BMapGL.Size(35, 35));
    let point = new BMapGL.Point(经纬度)
    let marker = new BMapGL.Marker(point, {icon: icon});    // 合成marker点
    ...
    this.noEmergencyAlarmsMarks.push(marker)    // 将标记点存储下
    this.addHuxi()    // 步骤2,给标记点添加css
    this.MAP.addOverlay(marker);    // 在地图上添加覆盖物
    

  2. 给标记点dom添加class

    addHuxi() {
        this.noEmergencyAlarmsMarks.forEach(item => {
            setTimeout(() => {
                item.domElement.classList.add('huxi')
            }, 1000)
        })
    }
    

  3. css动画

    .huxi{
      background: url("../assets/img/index/emergencyAlarms.gif") no-repeat!important;
      background-position: -15px -7px!important;
      width: 80px!important;
      height: 67px!important;
      background-size: 90% 67%!important;
      animation-name: breath;                         /* 动画名称 */
      animation-duration: 3s;                         /* 动画时长3秒 */
      animation-timing-function: ease-in-out;         /* 动画速度曲线:以低速开始和结束 */
      animation-iteration-count: infinite;            /* 播放次数:无限 */
      /* Safari and Chrome */
      -webkit-animation-name: breath;                 /* 动画名称 */
      -webkit-animation-duration: 3s;                 /* 动画时长3秒 */
      -webkit-animation-timing-function: ease-in-out; /* 动画速度曲线:以低速开始和结束 */
      -webkit-animation-iteration-count: infinite;    /* 播放次数:无限 */
    }
    
    @keyframes breath {
      from { opacity: 0.1; }                          /* 动画开始时的不透明度 */
      50%  { opacity:   1; }                          /* 动画50% 时的不透明度 */
      to   { opacity: 0.1; }                          /* 动画结束时的不透明度 */
    }
    
    @-webkit-keyframes breath {
      from { opacity: 0.1; }                          /* 动画开始时的不透明度 */
      50%  { opacity:   1; }                          /* 动画50% 时的不透明度 */
      to   { opacity: 0.1; }                          /* 动画结束时的不透明度 */
    }
    


4. 清除指定名称的标记点

let allOverlay = map.getOverlays(); // 获取地图中所有的覆盖物

allOverlay.forEach(overlay => { // 遍历覆盖物
    if (overlay.name === 'emergencyAlarm') {
            map.removeOverlay(overlay)    // 清楚该覆盖物
    }
})


5. 点击标记点事件后的弹窗

第一步中点击事件:func()

func(arg1, arg2) {
    let opts = {
        title: '标题',     // 信息窗口标题
    }
    let content = `
        <div>在这里填写要显示的文本内容,支持html和行内样式</div>
    `
    var infoWindow = new BMapGL.InfoWindow(content, opts);  // 创建信息窗口对象
    map.openInfoWindow(infoWindow, new BMapGL.Point(item.alarmLongitude, item.alarmLatitude));        // 打开信息窗口
    map.setCenter(new BMapGL.Point(经纬度))    // 信息窗显示的位置
}


6. 地图搜索

可以通过数据接口获得详细的数据信息,结合地图API您可以自行向地图添加标注和信息窗口。 BMap.LocalSearchBMap.LocalSearchOptions类提供了若干设置回调函数的接口,通过它们可得到搜索结果的数据信 息。 例如,通过onSearchComplete回调函数参数可以获得BMap.LocalResult对象实例,它包含了每一次搜索结果的数据信息。 当回调函数被执行时,您可以使用BMap.LocalSearch.getStatus()方法来确认搜索是否成功或者得到错误的详细信息。

在下面这个示例中,通过onSearchComplete回调函数得到第一页每条结果的标题和地址信息,并输出到页面上:

<template>
    <div class="filter">
        <div class="search">
            <a-input placeholder="搜索地点" allow-clear v-model="modalData.locationName" @clear="modalData.mapResults = []"></a-input>
            <a-button type="primary" @click="handleSearchLocation"><icon-search /></a-button>
        </div>
    <div class="result" v-if="modalData.mapResults.length">
        <div class="title">
            <div class="name">搜索结果</div>
            <span class="close" @click="modalData.mapResults = []; modalData.locationName = ''"><icon-close /></span>
        </div>
        <div style="margin-bottom: 50px"></div>
        <div class="item" v-for="item in modalData.mapResults" :key="item.uid" @click="handleSelectLocation(item.point)">
            <div class="title">{{item.title}}</div>
            <div class="address" v-if="item.address">地址:{{item.address}}</div>
        </div>
        </div>
    </div>
</template>
<script>
// 处理地图中的搜索
const handleSearchLocation = ():void => {
    if (modalData.locationName === '') {
        modalData.mapResults = []
        return
    }
    let map = modalMap.value;
    var options = {
        onSearchComplete: function(results){
            if (local.getStatus() == BMAP_STATUS_SUCCESS){
                let s = [];
                for (var i = 0; i < results.getCurrentNumPois(); i ++){
                    let _obj:object = {title: results.getPoi(i).title, address: results.getPoi(i).address, point: results.getPoi(i).point, uid: results.getPoi(i).uid}
                    s.push(_obj)
                }
                modalData.mapResults = s
            }
        }
    };
    let local = new BMapGL.LocalSearch(map, options);
    local.search(modalData.locationName)
};

</script>

参考文章:https://www.cnblogs.com/0201zcr/p/4689456.html



暂时先记录这些,再有新实践后继续更新。

若有错误,烦请指出。


2022.7.21: 增加地图搜索


原文链接:https://blog.zhanghaoran.ren/article/html/BaiDuGISDiTuBiJi.html