vue 使用百度地图:搜索定点

需求:
1.以某一点为圆心,半径5000米以内的地方进行标注;
2.点击选择定位,添加覆盖物,并解析地址;
3.通过搜索进行定位:↑↓键进行选择Enter键确定,也可以点击选择,并添加覆盖物。

效果图 ↓

官网地址:
https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi

这次的需求是,圆心五公里之内的地方,需要可以搜索定点。根据文档,需要用到的api是
https://api.map.baidu.com/place/v2/search?query=银行&location=39.915,116.404&radius=2000&output=xml&ak=您的密钥
具体参数看上面的网址就成~~
在解析地址时,可能会出现跨域问题,所以我们还需要安装一个vue-jsonp。

安装 ↓

npm install vue-jsonp --s

main.js ↓

import {VueJsonp} from "vue-jsonp"; 
Vue.use(VueJsonp);

在utils中创建文件loadMap.js ↓

export default function loadBMap(ak) {
    return new Promise(function(resolve, reject) {
      if (typeof BMap !== 'undefined') {
        resolve(BMap)
        return true
      }
      window.onBMapCallback = function() {
        resolve(BMap)
      }
      let script = document.createElement('script')
      script.type = 'text/javascript'
      script.src =
        'http://api.map.baidu.com/api?v=2.0&ak=' + ak + '&callback=onBMapCallback'
      script.onerror = reject
      document.head.appendChild(script)
    })
  }

准备工作就完成啦~~~~

正式代码片段

html ↓

    
当前定位地址:

css ↓ (首先要确保容器有足够的宽高)

.baidu-map-container {
  height: 480px;
  position: relative;
  #baidu-map-container {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
  }
  #tips-container {
    z-index: 1;
    position: absolute;
    top: 10px;
    left: 10px;
    padding: 0px 7px;
    min-width: 400px;
    height: 70px;
    line-height: 35px;
    background: #fff;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border-bottom: 1px solid lightgrey;
    font-size: 12px;
    .drop-container {
      min-width: 400px;
      max-height: 400px;
      overflow: scroll;
      overflow-y: auto;
      overflow-x: hidden;

      position: absolute;
      left: 0;
      background: white;
      .loop-address-search {
        padding: 0 7px;
        display: flex;
        align-items: center;
        cursor: pointer;
        .icon,
        .name {
          margin-right: 10px;
        }
        .icon {
          line-height: 20px;
        }
        .address {
          color: #999999;
        }
      }
      .loop-address-search:hover {
        background: rgba(0, 0, 0, 0.1);
      }
      .active-address {
        background: rgba(0, 0, 0, 0.1);
      }
    }
    .drop-container::-webkit-scrollbar {
      display: none;
    }
  }
}

script ↓

  // 引入写好的使用百度地图的方法
  import loadMap from "@/components/BaiduMap/loadMap";

  data() {
    return {
      addressSearchDropShow: false,
      addressNum: -1, // 控制地址搜索下拉框是否选中的变量
      addressSearchList: [], // 搜索下拉框的数组
      
      locationTips: "", 
      ifHasSearchAddress: false,
      // 不知道该怎么备注了。。。。都是语义化自己理解吧
      currentSearchAddressInfo: {
        lng: "",
        lat: "",
      },
      // 中心点坐标
      center: {
        lng: "119.587727",
        lat: "39.961482",
      },
    };
  },
  methods: {
    // 下拉框消失
    dispearAddressDrop() {
      // 设置定时器原因:
      // 当点击下拉框中的任意一条时,会先执行el-input的blur方法
      // 即,下拉框先消失,后面的语句都执行不了啦
      setTimeout(() => {
        this.addressNum = -1;
        this.addressSearchDropShow = false;
      }, 100);
    },
    // 选中某条数据时,将选中的地址放输入框里,并保存经纬度
    handleChooseAddress(idx) {
      let addressInfo = this.addressSearchList[idx];
      // 当选择了一个地址后保存一个变量,地图添加覆盖物时会有用
      this.ifHasSearchAddress = true;
      // 文字入框 获取经纬度
      this.locationTips = addressInfo.name;
      this.currentSearchAddressInfo = { ...addressInfo.location };
      // 获取到选中的经纬度后需要重新加载地图
      this.initBaiduMap();
      this.dispearAddressDrop();
    },
    onFocusLocation(e) {
      if (e.target.value) {
        this.addressNum = -1;
        this.addressSearchDropShow = true;
      }
    },
    keydownChangeLocation(e) {
      if (e.keyCode === 40) {
        // ↓
        if (this.addressNum < this.addressSearchList.length - 1) {
          this.addressNum++;
        } else {
          this.addressNum = 0;
        }
      }
      if (e.keyCode === 38) {
        // ↑
        if (this.addressNum <= 0) {
          this.addressNum = this.addressSearchList.length - 1;
        } else {
          this.addressNum--;
        }
      }
      if (e.keyCode === 13) {
        // Enter
        this.handleChooseAddress(this.addressNum);
      }
    },
    // 通过输入的文字搜索一定范围内的地址
    onInputLocation(val) {
      this.addressNum = -1;
      this.addressSearchDropShow = true;
      // 获取出现地址的API
      this.$jsonp(
        `https://api.map.baidu.com/place/v2/search?query=${val}&location=${this.center.lat},${this.center.lng}&radius=5000&output=json&ak=你的密钥`
      ).then((res) => {
        this.addressSearchList = res.results;
      });
    },
    initBaiduMap() {
        loadMap("你的密钥")
        .then(() => {
          // 之后在circle中添加点击事件时this指向会发生改变所以先存一个
          let _this = this;
          // 初始化地图
          this.myMap = new BMap.Map("baidu-map-container");
          // 中心点和缩放
          this.myMap.centerAndZoom(
            new BMap.Point(this.center.lng, this.center.lat),
            13
          );
          // 地图可以使用鼠标滚轮进行缩小放大
          this.myMap.enableScrollWheelZoom();

          let geoc = new BMap.Geocoder();
          // 设置规定范围的圆圈
          let circle = new BMap.Circle(
            new BMap.Point(this.center.lng, this.center.lat),
            5000,
            {
              strokeColor: "green",
              strokeWeight: 6,
              strokeOpacity: 0.5,
            }
          );
          // 添加覆盖物 规定范围的圈儿
          this.myMap.addOverlay(circle);
          // 圆圈儿在之后可能会进行的clearOverlays()时不会被删除
          circle.disableMassClear();

          let marker;
          // 选择搜索地址后保存的变量
          if (this.ifHasSearchAddress) {
            marker = new BMap.Marker(
              new BMap.Point(
                this.currentSearchAddressInfo.lng,
                this.currentSearchAddressInfo.lat
              )
            );
            // 如果有选中的地址则添加marker
            this.myMap.addOverlay(marker);
          }

          // 给圈儿内的地图范围添加点击事件
          circle.addEventListener("click", function (e) {
            // 清空下拉框中的数据
            _this.addressSearchList = [];
            // 清空之前的覆盖物
            _this.myMap.clearOverlays();

            let point = e.point;
            // 获取点击地点的经纬度
            _this.longitude = point.lng;
            _this.latitude = point.lat;
            // 添加覆盖物
            let markerPoint = new BMap.Marker(
              new BMap.Point(point.lng, point.lat)
            );
            _this.myMap.addOverlay(markerPoint);

            // 将点选的地址信息存入data中
            geoc.getLocation(point, function (rs) {
              let position = rs.addressComponents;

              _this.locationTips = `${position.province}${position.city}${position.district}${position.street}${position.streetNumber}`;
            });
          });
        })
        .catch((err) => {
          console.log("地图加载失败");
        });
    }
  },
  mounted() {
    this.initBaiduMap();
  },

tada~一个可以点选也可以搜索定点的地图就完成啦

你可能感兴趣的:(vue 使用百度地图:搜索定点)