首先我们引入vue-baidu-map地图,可以参考:https://blog.csdn.net/qq_39009348/article/details/90070142,里面有详细的vue-baidu-map的基本使用方法。更多覆盖物的使用请参考:https://blog.csdn.net/qq_39009348/article/details/106189999

需求:如果我们需要自定义一个控件区域,并且在该控件区域控制我们的某些标注是否显示,以及搜索详细地址,以及回到地图中心,该如何做呢?

首先我们引入自定义控件:

 在<baidu-map></baidu-map>标签内加入一个自定义控件,里面布局自己设置,就和常规的布局一样了;

<bm-control id="searAdressBox">
            <div class="controlBox">
              <div class="control_left">
                <i class="iconcommon iconfont icon-huidaozhongxin" title="回到地图中心"></i>
                <i class="iconcommon iconfont icon-shezhizhongxin" title="设置地图中心"></i>
                <div>
                  <el-checkbox class="iconcommon check" v-model="showTerminal">显示集中器</el-checkbox>
                  <el-checkbox class="iconcommon check" v-model="showLamp">显示灯控</el-checkbox>
                  <el-checkbox class="iconcommon check" v-model="showLine">显示线路</el-checkbox>
                </div>
              </div>
              <div class="control_right">
                <div>
                  <span class="searchText">搜索地址:</span><el-input placeholder="请输入搜索地址" @keyup.enter.native="searchAdress" style="width:200px" size="mini" v-model="searchadress"></el-input>
                  <el-button type="primary" size="mini" @click="searchAdress" icon="el-icon-search">搜索</el-button>
                </div>
                <div style="margin-left:10px;"><i @click="openBar" class="iconcommon iconfont icon-zhankai1" title="展开"></i></div>
              </div>
            </div>           
          </bm-control>

我的css代码(需要注意的是自定义控件默认的初始样式是在左上部分,自己根据需要改变初始样式即可):

#searAdressBox{
    position:absolute;
    top:0 !important;
    right:0 !important;
    left: 0 !important;
    bottom:auto !important;
    z-index: 1000;
    width:100%;
    height:40px;
    line-height: 40px;
    background-color:rgba(0,0,0,0.1)
}
.controlBox{
  padding-left:170px;
  padding-right:20px;
  display: flex;
  justify-content: space-between;
}
.control_left{
  display: flex;
}
.check{
  position: relative;
  bottom:7px;
}
.control_right{
  display: flex;
}
.iconcommon{
  color:#409EFF;
  font-size: 30px;
  margin-right:20px;
  cursor: pointer;
  font-weight: 900;
}
.searchText{
  color:#409EFF;
  font-size: 15px;
  font-weight: 900;
}

第一个功能:回到地图中心

首先根据每个账号可以设置一个地图的中心点,当用户切换到中心点以外的地方,即可点击回到地图中心,这个功能比较简单,直接点击时把经纬度赋值给<baidu-map></baidu-map>标签中绑定的:center="{lng: map.center.lng, lat: map.center.lat}"即可;

第二个功能:切换标注隐藏显示

首先我们添加了一些标注的聚合点,我们想通过控制单选框来控制是否显示这些标注点(不止一个)

<!--集中器聚合动态添加的点坐标-->
          <bm-marker-clusterer :averageCenter="true" :maxZoom="16">
              <bm-marker v-for="Cmarker of Cmarkers" :key="Cmarker.id" :title="Cmarker.name" :icon="{url: controllerIcon, size: {width: 50, height: 50}}" :position="{lng: Cmarker.longitude, lat: Cmarker.latitude}" @click="lookDetail(Cmarker)">
                <bm-label :content="Cmarker.name" title="Hover me" :labelStyle="{color: 'red', fontSize : '14px'}" :offset="{width: -25, height: -25}"/>
                <bm-context-menu>
                  <bm-context-menu-item :callback="getPosition" text="获取坐标"></bm-context-menu-item>
                </bm-context-menu>
              </bm-marker>
          </bm-marker-clusterer>

首先要说明的是,通过v-show来控制这个标签的显示隐藏是没有效果的;那要如何做呢?我们知道这个标注点是通过v-for遍历一个数组,绑定经纬度标注在地图页面的。当我们遍历一个空数组时,当然就不会显示这些标注了;所以我们的思路是通过计算属性去控制这个数组的数据来达到类似效果:

首先:请求要标注数据,保存在本地

// 获取已经标注集中器经纬度数组
    getCMarked() {
      getCMarked().then(res => {
        if (res.rows.length > 0 || res.rows !== undefined) {
          var cArr = []
          for (var i = 0; i < res.rows.length; i++) {
            if (res.rows[i].ismark) {
              cArr.push(res.rows[i])
            }
          }
          this.Cmarked = cArr
        } else {
          this.$message({
            message: '获取数据失败',
            type: 'error'
          })
        }
      })
    },

然后,计算属性控制该数组是否有数据:

computed: {
    // 计算属性控制集中器标注是否显示
    Cmarkers() {
      // this.showTerminal为单选框绑定是否显示标注的值,为true是让遍历数组有数据,false时遍历数组为空
      if (this.showTerminal) {
        return this.Cmarked
      } else {
        return []
      }
    }
  },

这样既完成了这个功能

第三个功能:搜索地址并且定位

原理和第一个回到地图中心一样的,获取经纬度,然后设置地图中心为该经纬度的值

getlalg为百度提供的根据地址获取经纬度的接口:

http://api.map.baidu.com/geocoder?address=' + address + '&output=json&key=cCQ1X0IjCVzdIxOD8nEguY&city='

// 通过获取经纬度定位

export const getlalg = (address) => {

  return Axios.get(Url.baiduMap + '/geocoder?address=' + address + '&output=json&key=你的秘钥&city=').then(res => res.data)

}

// 搜索地址
    searchAdress() {
      var adress = this.searchadress
      getlalg(adress).then(res => {
        if (res.status === 'OK') {
          var lg = res.result.location.lng
          var la = res.result.location.lat
          this.map.center.lng = lg
          this.map.center.lat = la
          this.map.zoom = 18
        } else {
          this.$message({
            message: '搜索失败',
            type: 'info'
          })
        }
      })
    },

 回到地图中心:

上面搜索功能做完之后,搜索一个地址,地图中心也相应的在搜索的位置,所以地图切换到搜索的位置,回到地图中心即是设置了一个固定的地图中心点,每次进入地图初始位置并是该地图中心点,当我们对地图拖拽,离开了地图中心点,想要一键回到中心点该怎么做呢?很容易想到是获取中心点经纬度,重新给地图中心点赋值,即:

this.map.center.lng = lg
this.map.center.lat = la

但事实上并没有效果,即点击回到中心点并不会回到中心点的可视范围内,为什么呢?因为中心点一直没变,保存在数据库里的中心点没变,拖拽地图并没有改变中心点,所以地图可视范围不会变的,但是我们发现搜索后中心点是变了,所以地图移动到了搜索位置,我们根据这个思路,只要在每次拖拽结束,获取到当前位置的中心点,赋值给地图中心点,回到中心点后去获取数据库的中心点即可完美解决:

 地图绑定拖拽结束事件

<baidu-map id="map" :zoom="map.zoom" @dragend="dragendEvent" :center="{lng: map.center.lng, lat: map.center.lat}" @ready="handler" :scroll-wheel-zoom="true">
</baidu-map>

获取中心点经纬度,改变中心点 

// 监听拖拽地图结束事件
    dragendEvent(type, target, pixel, point) {
      this.map.center.lng = type.point.lng
      this.map.center.lat = type.point.lat
    },
// 监听拖拽地图结束事件(建议按这种方式写,因为上面这种方式得到的事拖拽时鼠标点击下去那一刻的经纬度,而不是你拖拽到可视区域的中心点经纬度)
,而且上面的方式获取点击时的坐标点经纬度,然后又设置该点为中心点,地图就会有一个从点击向中心点移动的过程,看起来像卡顿一样,体验不好
    dragendEvent(e) {
      const { lng, lat } = e.target.getCenter()
      this.map.center.lng = lng
      this.map.center.lat = lat
    },

 回到中心点:

// 获取地图中心点
    getMapCenters() {
      const para = {
        id: this.peopleId
      }
      var params = Qs.stringify(para)
      getMarkcenter(params).then(res => {
        // 获取地图中心点,设置中心点
        this.map.center.lng = res.longitude
        this.map.center.lat = res.latitude
        this.map.zoom = 18
      })
    },

效果图:

Logo

前往低代码交流专区

更多推荐