高德地图搜索地点,设置签到地点和签到范围,并点击回显

第一步:首先申请高德地图key

可以从其他博主那理看如何注册申请

接下来就可以引用组件开发 import AMapLoader from "@amap/amap-jsapi-loader"

我懒得的写白话了 直接代码粘出来 都有注释 不懂问我 我这是弹框里地图封装的子组件

注:谷歌等一些浏览器定位不了只能获取到当前城市

<template>
  <div class="aMap">
    <div class="left" v-if="dialoglocation === 'update'">
      <div class="map-box">
        <el-select
          size="small"`在这里插入代码片`
          v-model="mapAddress"
          filterable
          clearable`在这里插入代码片`
          remote
          reserve-keyword
          placeholder="请输入地名"
          :no-data-text="'查询失败,请输入正确地名'"
          :popper-class="'g-poi-search-popper'"
          :remote-method="searchKeyWord"
          :loading="showsearchResult"
          @change="markerResult">
          <el-option
            v-for="item in poiList"
            :key="item.id"
            :label="item.name"
            :title="item.name"
            :value="item.id"/>
        </el-select>
        <el-button icon="el-icon-search" type="primary" @change="markerResult" size="small" class="mapAddressSearch"/>
      </div>
      <el-select v-model="radius" size="small" style="width:106px" @change="updateRadius" placeholder="请选择">
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value"/>
      </el-select>
    </div>
    <div id="container"/>
  </div>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader"
window._AMapSecurityConfig = {
  securityJsCode: "XXXXXXXXX",//申请key时的安全密钥
}
export default {
  name: "MapView",
  
  props: {
    signInfoForm: {
      type: Object,
      default: () => ({}),
    },
    dialoglocation: {
      type: String,
      default: 'update',
    },
    showMap: {
      type: Boolean,
      default: false,
    },
  },
  data(){
    return{
      isShowMap: this.showMap,
      showsearchResult: false,
      poiList: [],
      mapModule: null,
      map: null,
      circle: null,
      radius: '300', // 假设当前位置为圆心,1000米为半径
      // 搜索输入
      mapAddress: this.signInfoForm.name,
      autoCompleteComponent: null,
      placeSearchComponent: null,
      options:  [
        {
          value: '100',
          label: '100米'
        },
        {
          value: '200',
          label: '200米'
        },
        {
          value: '300',
          label: '300米'
        },
        {
          value: '400',
          label: '400米'
        },
        {
          value: '500',
          label: '500米'
        },
        {
          value: '600',
          label: '600米'
        },
        {
          value: '700',
          label: '700米'
        },
        {
          value: '800',
          label: '800米'
        },
        {
          value: '900',
          label: '900米'
        },
        {
          value: '1000',
          label: '1000米'
        }
     ],
    }
  },
  watch: {
    showMap(val) {
      this.isShowMap = val
      if(val){
        this.initAMap()
      }else{
        this.map?.destroy()
      }
    },
    signInfoForm(val){
      this.mapAddress= val.name
      this.radius= val.effectiveRange || '300'
    }
  },
  mounted() {
    this.initAMap()
  },
  unmounted() {
    this.map?.destroy()
  },
  methods: {
    initAMap() {
      AMapLoader.load({
        key: "XXXXXXXX", // 申请好的Web端开发者Key,首次调用 load 时必填
        version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
        plugins: [
        'AMap.Geocoder',
        'AMap.Circle',
        'AMap.Geolocation',
        'AMap.CitySearch',
        'AMap.CircleEditor',
        'AMap.PlaceSearch',
        'AMap.AutoComplete',
        ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
      })
        .then((AMap) => {
          const that = this
          // 保存AMap实例
          that.mapModule = AMap
          that.map = new AMap.Map("container", {
            // 设置地图容器id
            viewMode: "2D", // 是否为3D地图模式
            zoom: 11, // 初始化地图级别
            // center: [116.397428, 39.90923], // 初始化地图中心点位置
            resizeEnable: true, // 设置地图容器大小变化时自动调整地图大小
          })
          
          // 构造定位插件实例
          AMap.plugin(['AMap.Geolocation','AMap.AutoComplete','AMap.PlaceSearch'], () => {
            let geolocation = new AMap.Geolocation({
              enableHighAccuracy: true, // 是否使用高精度定位,默认:true
              timeout: that.dialoglocation === 'update' ? 3000 : 0,          // 超过5秒后停止定位,默认:无穷大
              zoomToAccuracy: true,
            })
            that.mapSearchInit()
            // 获取当前位置具体信息
            geolocation.getCurrentPosition((status, result) => {
              // 定位成功
              if (status == 'complete') {
                onComplete(result)
              } else {
                // 谷歌浏览器等只能获取当前用户所在城市和城市的经纬度
                geolocation.getCityInfo((stat, res) => {   
                if (stat == "complete") {
                  console.log('城市定位成功', stat, res)
                  // that.map.setCenter(res.position)
                  if(that.signInfoForm.name !=='') {
                    that.echoData(that.signInfoForm)
                  }
                }else {
                  console.log('未获取定位')
                }
              })
              }
            })
            // 详情页面高德地图上面定位按钮不展示按钮- 新增地点的时候展示定位按钮
            if(that.dialoglocation === 'update'){
              that.map.addControl(geolocation)
            }else{
              that.map.removeControl(geolocation)
            }
          })
          // 定位成功回调函数
          function onComplete(data) {
            console.log('定位成功', data)
          }
          that.geoCoder = new AMap.Geocoder()
          // 定位失败回调函数
          // function onError(data) {
          //   console.log('定位失败', data)
          // }
          // 地图点击事件,实现选点
          that.map.on('click', (e) => {
            console.log(e,'e')
            const { lng, lat } = e.lnglat
            // 清除之前的标记
            that.map.clearMap()
            // 在点击的位置添加一个标记
            const marker = new that.mapModule.Marker({
              map: that.map,
              position: [lng, lat],
              icon: new that.mapModule.Icon({
                  size: new that.mapModule.Size(25,25),
                  image: require(`@/assets/img/marker.png`),
                  imageSize: new that.mapModule.Size(20, 20), 
              }),//设置定位图标
              offset: new that.mapModule.Pixel(-20,-20), // 设置点标记偏移量
            })
            marker.setMap(that.map)
            that.radiusInit(e.lnglat)
            that.geoCoder.getAddress([lng, lat], (status, result) => {
              if (status === 'complete' && result.regeocode) {
                that.mapAddress = result.regeocode.addressComponent.neighborhood || result.regeocode.formattedAddress
                console.log('点击位置信息:', result.regeocode.formattedAddress)
                const signInfoForm = {
                  name: result.regeocode.addressComponent.neighborhood || result.regeocode.formattedAddress,
                  address:result.regeocode.formattedAddress,
                  longitude: lng,
                  latitude: lat,
                  effectiveRange: this.radius,	
                }
                this.$emit('setSignInfo',signInfoForm)
                // id
                // let {adcode} = result.regeocode.addressComponent
                //   let reg = /.+?(省|市|自治区|自治州|县|区)/g
                // let provinceId = parseInt(adcode.substr(0, 2) + '0000')
                // let cityId = parseInt(adcode.substr(0, 4) + '00')
                // let areaId = adcode
                // console.log('点击位置的省市区id:', provinceId, cityId, areaId)
              }
            })
          })
        })
        .catch((e) => {
          console.log(e)
        })
    },
     /** 初始化覆盖物 */
    radiusInit(data) {
      const that = this
      that.circle = null
      that.circle = new that.mapModule.Circle({
        map: that.map,
        center: data, // 圆心点坐标
        radius: that.radius, // 圆的半径
        strokeColor: '#CCA05D', // 边线颜色
        strokeOpacity: 1, // 边线透明度
        strokeWeight: 1, // 边线宽度
        strokeStyle: "dashed", //轮廓线样式
        fillColor: '#CCA05D', // 填充颜色
        fillOpacity: 0.35, // 填充透明度
      })
      //圆形 Circle 对象添加到 Map
      that.map.add(that.circle)
      //根据覆盖物范围调整视野
      that.map.setFitView([ that.circle ])
    },
    // 签到范围修改
    updateRadius() {
      this.circle.setRadius(this.radius)
      const signInfoForm = {
        name: this.signInfoForm.name,
        address: this.signInfoForm.address,
        longitude: this.signInfoForm.longitude,
        latitude: this.signInfoForm.latitude,
        effectiveRange: this.radius,	
      }
      this.$emit('setSignInfo',signInfoForm)
    },
     /** 初始化搜索 */
    mapSearchInit(){
      const _this = this
      let autoOptions = {
        input: "tipInput",
      }
      let autoCompleteComponent= new _this.mapModule.Autocomplete(autoOptions)
      this.autoCompleteComponent = autoCompleteComponent
      // 注册placeSearch组件
      this.placeSearchComponent = new _this.mapModule.PlaceSearch()
    },
    //根据输入内容查询
    searchKeyWord(query){
      if(query === '') return 
      let that= this
      that.mapAddress = query
      that.showsearchResult = true
      that.placeSearchComponent.search(query, function (status, result) {
        if(status==='complete' && result.info === "OK"){
          that.showsearchResult = false
          that.poiList = result.poiList.pois
        }else{
          that.showsearchResult = false
          that.poiList = []
          that.$message({
            message: "没有查到结果",
            type: "warning",
          })
        }
      })
    },
    //选择搜索的内容
    markerResult(id){
      if(id === '') return 
      const data =this.poiList.filter(item => item.id === id)[0]
      const signInfoForm = {
        name: data.name,
        address: data.address,
        longitude: data.location.lng,
        latitude: data.location.lat,
        effectiveRange: this.radius,	
      }
      this.echoData(signInfoForm)
    },
    // 回显数据
    echoData(data){
      const _this = this
      this.showsearchResult = false
      this.address = data.name
      var marker = new _this.mapModule.Marker({
        position: [Number(data.longitude),Number(data.latitude)],
        icon: new _this.mapModule.Icon({
            size: new _this.mapModule.Size(25,25),
            image: require(`@/assets/img/marker.png`),
            imageSize: new _this.mapModule.Size(20, 20), 
        }),//设置定位图标
        offset: new _this.mapModule.Pixel(-20,-20), // 设置点标记偏移量
      })
      this.map.clearMap()// 清除所有覆盖物(点标志) 不能清除 不然覆盖物没了
      this.map.add(marker)// 添加点标志
      setTimeout(() => {
        this.map.setCenter([Number(data.longitude),Number(data.latitude)])
        this.map.setZoom(15)
        this.radiusInit([Number(data.longitude),Number(data.latitude)])
      }, 50)
      this.poiList = []
      this.$emit('setSignInfo',data)

    },
  },
}
</script>
<style scoped lang="scss">
.aMap{
  display: flex;
  flex-direction: row;
  position: relative;
  .left{
    position: absolute;
    top: 20px;
    left: 24px;
    z-index: 99999;
    display: flex;
    flex-direction: row;
    .map-box{
      margin-right: 12px;
      ::v-deep .el-input__inner{
        border-radius: 4px 0 0 4px;
        border-right: none;
      }
      ::v-deep .el-button{
        border-radius: 0 4px 4px 0;
        border-left: none;
      }
    }
  }
}
#container {
  width: 760px;
  height: 380px;
  margin: auto;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值