Bootstrap

vue3使用腾讯地图(关键词搜索,地址获取经纬度,标记位置)

效果图:

父页面必须先填写地址,才能点击经纬度按钮

获取父页面数据,初始化获取经纬度并标点,可模糊查询,可点击地图

代码

一,.在index.html中引入

<script src="https://map.qq.com/api/gljs?v=1.exp&key=你的key"></script>

二,地图组件

<template>
  <ke-dialog
    :visible.sync="dialog.visible"
    :title="dialog.title"
    width="900"
    :show-ok-btn="false"
    :show-cancel-btn="false"
    class="voteOneDialog"
  >
    <div class="cont">
      <el-row class="info">
        <el-col :offset="1" :span="7">
          <el-autocomplete
            v-model="address_detail"
            :fetch-suggestions="querySearch"
            placeholder="请输入详细地址"
            :trigger-on-focus="false"
            @select="handleSelect"
            value-key="title"
          ></el-autocomplete>
        </el-col>
        <el-col style="margin-left: 10px" :span="4">
          <el-input v-model="userlocation.lng" placeholder="经度" readonly="readonly"></el-input>
        </el-col>
        <el-col style="margin: 0 30px 0 10px" :span="4">
          <el-input v-model="userlocation.lat" placeholder="纬度" readonly="readonly"></el-input>
        </el-col>
        <div class="btn-box f_l" style="padding-left: 20px">
          <el-button id="position" @click="resultFn" type="danger">确定</el-button>
          <el-button @click="mapClose" type="info">关闭</el-button>
        </div>
      </el-row>

      <div id="container" style="width: 100%; height: 100%"></div>
    </div>
  </ke-dialog>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import { jsonp } from "vue-jsonp"; // npm i vue-jsonp -S

@Component({
  name: "baiduMapIndex",
  components: {},
})
export default class baiduMapIndex extends Vue {
  @Prop({ type: Object, default: true }) dialog: any;

  private userlocation: any = {
    map: "",
    markerLayer: "",
    lng: "",
    lat: "",
  };
  private address_detail = "";
  private suggestId = "suggestId";
  private TMap = (window as any).TMap;

  mounted() {
    //nextTick渲染
    this.$nextTick(() => {
      this.initMap();
    });
  }
  initMap() {
    //定义地图中心点坐标
    var center = new (window as any).TMap.LatLng(22.543731, 114.059589);
    //定义map变量,调用 TMap.Map() 构造函数创建地图
    this.userlocation.map = new (window as any).TMap.Map(document.getElementById("container"), {
      center: center, //设置地图中心点坐标
      zoom: 16, //设置地图缩放级别
      viewMode: "3D",
    });

    this.address_detail = this.dialog.address;

    this.addrToGetCoordinate(this.address_detail);
    (this.userlocation.map as any).on("click", this.clickHandler); // 绑定点击地图获取地理位置的事件
    //  this.addrToGetCoordinate(this.address_detail);
  }

  //标记地图
  markerLayer(lat, lng) {
    this.userlocation.markerLayer = new (window as any).TMap.MultiMarker({
      map: this.userlocation.map, //指定地图容器
      //样式定义
      styles: {
        //创建一个styleId为"myStyle"的样式(styles的子属性名即为styleId)
        myStyle: new (window as any).TMap.MarkerStyle({
          // width: 20, // 点标记样式宽度(像素)
          // height: 30, // 点标记样式高度(像素)
          // src: "https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker-pink.png", //图片路径
          //焦点在图片中的像素位置,一般大头针类似形式的图片以针尖位置做为焦点,圆形点以圆心位置为焦点
          anchor: { x: 16, y: 32 },
        }),
      },
      //点标记数据数组
      geometries: [
        {
          id: "1", //点标记唯一标识,后续如果有删除、修改位置等操作,都需要此id
          styleId: "myStyle", //指定样式id
          position: new (window as any).TMap.LatLng(this.userlocation.lat, this.userlocation.lng), //点标记坐标位置
        },
      ],
    });
  }

  // 根据地址获取坐标
  addrToGetCoordinate(address) {
    const url = "https://apis.map.qq.com/ws/geocoder/v1/";
    jsonp(url, {
      key: "3WDBZ-HMUCX-NIE43-ZPLQ4-OOHAO-OKBES",
      output: "jsonp",
      address: address,
    })
      .then((res) => {
        if (res.status === 0) {
          // 处理得到的经纬度
          this.userlocation.lat = res.result.location.lat.toFixed(6);
          this.userlocation.lng = res.result.location.lng.toFixed(6);
          this.$nextTick(() => {
            this.markerLayer(this.userlocation.lat, this.userlocation.lng); // 标记地图
            this.setInitChange();
          });
        }
        // else {
        //   console.log(22222, this.userlocation.lat, this.userlocation.lng);
        //   // 处理得到的经纬度
        //   // this.userlocation.lat = res.result.location.lat.toFixed(6);
        //   // this.userlocation.lng = res.result.location.lng.toFixed(6);
        //   // this.$nextTick(() => {
        //   //   this.markerLayer(this.userlocation.lat, this.userlocation.lng); // 标记地图
        //   //   this.setInitChange();
        //   // });
        // }
      })
      .catch((e) => {
        console.log(e);
      });
  }

  handleSelect(item) {
    this.userlocation.lat = item.location.lat;
    this.userlocation.lng = item.location.lng;
    this.setInitChange();
  }

  // 修改地图位置
  setInitChange() {
    (this.userlocation.map as any).setCenter(
      new (window as any).TMap.LatLng(this.userlocation.lat, this.userlocation.lng)
    );
    (this.userlocation.markerLayer as any).updateGeometries([
      {
        styleId: "myStyle",
        id: "1",
        position: new (window as any).TMap.LatLng(this.userlocation.lat, this.userlocation.lng),
      },
    ]);
  }

  // 获取搜索经纬度
  querySearch(queryString, callback) {
    // 关键字查询
    const url = "https://apis.map.qq.com/ws/place/v1/suggestion"; // 关键字查询
    jsonp(url, {
      key: "3WDBZ-HMUCX-NIE43-ZPLQ4-OOHAO-OKBES",
      keyword: queryString,
      output: "jsonp",
    }).then((res) => {
      if (res.status == 0) {
        const list = res.data;
        callback(list);
      } else {
        this.$message.warning(res.message);
      }
    });
  }

  // 重载地图
  reloadMap() {
    (document.getElementById("container") as any).innerHTML = "";
    this.userlocation.markerLayer = "";
    let center = new (window as any).TMap.LatLng(this.userlocation.lat, this.userlocation.lng);
    this.userlocation.map = new (window as any).TMap.Map(document.getElementById("container"), {
      center: center, //设置地图中心点坐标
      viewMode: "3D",
    });
  }

  // 点击获取经纬度
  clickHandler(evt: any) {
    let lat = evt.latLng.getLat().toFixed(6);
    let lng = evt.latLng.getLng().toFixed(6);
    this.userlocation.lng = lng;
    this.userlocation.lat = lat;
    //这里的evt有模糊的坐标可以打印看看但是没有街道所以我这做了判断
    //如果有大的目标就取大的目标否则就取街道;
    if (evt.poi) {
      this.address_detail = evt.poi.name;
      //bug,点击出现多个标点
      // this.addrToGetCoordinate(this.address_detail);
    } else {
      //调用详细地址函数
      // console.log(this.userlocation.lng, this.userlocation.lat);
      this.getAreaCode();
    }
    this.userlocation.markerLayer.geometries = [];
    //修改id为4的点标记的位置
    (this.userlocation.markerLayer as any).updateGeometries([
      {
        styleId: "marker",
        id: "1",
        position: new (window as any).TMap.LatLng(lat, lng),
      },
    ]);
  }

  resultFn() {
    this.$message({ message: "定位获取成功!", type: "success" });

    this.$emit(
      "getLocationSuccess",
      this.userlocation.lng,
      this.userlocation.lat,
      this.address_detail
    );
  }

  mapClose = () => {
    this.$emit("mapClose", false);
  };
}
</script>
<style lang="scss" scoped>
.map {
  width: 100%;
  height: 400px;
  ::v-deep {
    .BMap_cpyCtrl,
    .anchorBL {
      display: none;
    }
  }
}
.info {
  height: 40px;
  margin-bottom: 20px;
}
</style>

说明:ke-dialog和里面的一些方法是公司封装组件你们可以忽略,功能点都在里面,照葫芦画瓢是没有问题的,剩下的根据自己的需求修改

;