web端接腾讯地图,根据位置获取经纬度,下拉选地址,并绘制地图

 MAP: {
        KEY: `${MAPKEY}`//自己申请的腾讯开发者密钥
      },
      loading: false,
      isAjaxSearch: false,
      // 地区列表
      areas: [],
      // 地图搜索出来的地址
      addressList: [
        { value: 1, label: '', desc: '', },
      ],
      mapDialog: false,
      keyword: '', // 用于绑定输入框的值
      defaultForm: {
        isSelect: 1, // 是否选择了详细地址0
        area: [441900], // 存储省市区ID数组
        areaArr: ['广东省'], // 存储省市区json数组
        province: '广东省',  //
        city: '', //
        region: '', //
        address: '东莞市', // 详细地址 
        // mapCenter: '39.12,116.54', // 默认中心点
        mapCenter: '23.02067,113.75179',
        mapSrc: '', // 地图图片地址
        // 经纬度
        location: {
          lat: '',
          lng: '',
        },
      },
      form: {
        address: '',
        mapCenter: '',
      },
<el-form ref="mapForm">
        <!-- <el-form-item label="学校地址:" class="tipsDiv">
          <span class="tipsStart">*</span>
          <el-col>
            <el-cascader ref="myCascader" style="width:100%" :options="area" v-model="ruleForm.area" change-on-select
              clearable @change="changeArea" placeholder="请选择省/市/县(区)" filterable
              :props="{ value: 'code', label: 'name', children: 'children' }"></el-cascader>
          </el-col>
        </el-form-item> -->
        <!-- <el-form-item label="详细地址" prop="schoolAddress">
          <el-input v-model.trim="ruleForm.schoolAddress" clearable placeholder="请填写详细地址,30个字符以内"
            maxlength="30"></el-input>
        </el-form-item>  -->
        <!-- 提交后台的参数 -->

        <el-form-item label="学校地址省市区:" class="tipsDiv" style="position: relative;">
          <span class="tipsStart" style="position: absolute;left: -8px;">*</span>
          <el-col>
            <el-cascader ref="myCascader" style="width:100%" :options="area" v-model="form.area" change-on-select
              clearable @change="changeArea" placeholder="请选择省/市/县(区)" filterable
              :props="{ value: 'code', label: 'name', children: 'children' }"></el-cascader>
          </el-col>
        </el-form-item>
        <!-- <el-form-item label="省市区:">
          <el-cascader ref="myCascader" v-model="form.area"
            :props="{ value: 'code', label: 'name', children: 'children' }" :options="area" placeholder="请选择"
            @change="changeArea">
            <template slot="displayRender" slot-scope="{ labels }">
              <span v-for="(label, index) in labels" :key="index">
                <span v-if="index === 0" style="color: #262626;">
                  {{ labels && labels.length && labels.join(' ') || '' }}
                </span>
              </span>
            </template>
          </el-cascader>
        </el-form-item> -->
        <el-form-item label="详细地址:" prop="schoolAddress" style="position: relative;">
          <span class="tipsStart" style="position: absolute;left: -8px;">*</span>
          <el-autocomplete style="width: 100%;" allow-clear v-model="keyword" :fetch-suggestions="querySearch"
            :disabled="form.area && form.area.length > 1 ? false : true" @select="handleSelect"
            placeholder="请输入关键字"></el-autocomplete>
          <p v-if="!keyword"
            style="font-size: 12px;min-height: 22px;font-size: 14px;line-height: 1.5;color: #F56C6C;font-size: 12px;">
            请选择省市区后选择详细地址
          </p>
        </el-form-item>
        <el-form-item label="地图显示:">
          <div class="form-map-box">
            <div class="form-map">
              <img :src="form.mapSrc" style="width: 100%;height: 100%;">
            </div>
          </div>
        </el-form-item>
      </el-form>
  this.form = { ...this.defaultForm }
    // 添加debounce
    // this.ajaxSearch = lodash.debounce(this.ajaxSearch, 500)
    // // 地图区域生成未选择图片展示
    this.getMapSrc()
 //输入框获取焦点时调用的方法
    querySearch(queryString, cb) { // queryString是用户输入的想要查询的内容,cb是回调函数(可以发请求获取数据)
      console.log("如何触发", queryString, cb);
      if (queryString == "") {
        cb([]); // 当然这里的历史记录是后端返给我们的,应该为接口返回的数据
      } else {
        // let apiResult = [
        //   {
        //     value: "老王",
        //   },
        //   {
        //     value: "王老吉",
        //   },
        // ];
        // // 这里我们模拟从后端的接口异步获取的数据
        // setTimeout(() => {
        //   // cb([])    cb函数如果返回一个空数组的话,那个模糊搜索输入建议的下拉选项因为length为0就会消失了
        //   cb(apiResult);
        // }, 500);
        let res = []
        // console.log(e)
        // if (!e) { return } hhr
        this.loading = true
        getSuggestion({
          key: this.MAP.KEY,
          province: this.form.province || '',
          city: this.form.city || '',
          region: this.form.region || '',
          keyword: this.keyword
        })
          .then(res => {
            // if (res.message == 'query ok') {
            res = res.data
            this.loading = false
            res = (res && res.data) || res || []
            // console.log('搜索地址结果:', res)
            // it.value = it.address || ''//有变化 id hhr
            const result = res.map((it) => {
              it.value = it.address || ''
              it.label = it.title || ''
              it.desc = it.address || ''
              return it
            }).filter((it) => it && it.id && it.address) || []
            console.log("addrress")
            this.addressList = result
            cb(result)


            // 如果地址结果为空,设置为未选择地址状态
            if (result.length === 0) {
              this.clearAddress()
            }

            this.isAjaxSearch = true
            // }
          })
          .catch(err => {
            this.dataLoading = false
          })
        console.log('1111')
      }
    },
    // 选中输入框推荐的值的时候触发
    handleSelect(item) { // 参数
      console.log("拿到数据", item);
      console.log(this.addressList)
      this.form.isSelect = '1'
      this.form.mapCenter = `${item.location.lat},${item.location.lng}`
      this.form.location = {
        lat: item.location.lat,
        lng: item.location.lng
      }
      this.form.address = item.address
      this.getMapSrc()
    },
    // 点击clearable清空小图标按钮以后,继续重新在输入框中输入数据,querySearch会触发,但是cb函数不会触发
    // 这样的话就会出现发请求了,也获取数据了,但是input框的输入建议下拉框不呈现在页面上的问题,所以解决方法就是
    // 只要用户点击了
    blurForBug() {
      document.activeElement.blur()
    },
    // querySearch(queryString, cb) {
    //   // 对输入的关键字进行匹配,返回匹配的选项
    //   const options = this.options;
    //   const results = queryString ? options.filter(this.createFilter(queryString)) : options;
    //   // 通过回调函数将匹配的选项返回给el-autocomplete组件
    //   cb(results);
    // },
    createFilter(queryString) {
      return (option) => {
        return option.indexOf(queryString) === 0;
      };
    },
    // setData(obj = {}) {
    //   setTimeout(() => {
    //     if (!obj.location) { obj.location = {} }
    //     try { obj.location.lat = obj.location.lat || obj.latitude } catch (error) { }
    //     try { obj.location.lng = obj.location.lng || obj.longitude } catch (error) { }
    //     this.form = {
    //       ...this.form,
    //       ...obj,
    //       mapCenter: `${obj.location.lat || ''},${obj.location.lng || ''}`,
    //       isSelect: 1,
    //       area: obj.province ? this.$tool.getAreaIndexFromName(this.area, [obj.province, obj.city, obj.region], 'name', 'id') : [440000],
    //     }
    //     // console.log(this.form, this.$tool.getAreaIndexFromName(this.area, [obj.province, obj.city, obj.region], 'name', 'id'))
    //     this.$nextTick(() => {
    //       this.handleSearch(this.form.address || '')
    //       this.getMapSrc()
    //     })
    //   }, 700)
    // },

    getLenText(keyword, len = 64) {
      if (!keyword) { return '' }
      let str = keyword
      try {
        str = str.substring(0, len)
      } catch (e) { }
      return str
    },
    // 选择省市区
    changeArea(e) {
      this.$emit('change', e)
      // this.$nextTick(() => {
      //   this.areaNames = this.$refs['myCascader'].currentLabels   //获取lable的值
      // })
      // console.log(this.$refs['myCascader'].getCheckedNodes()[0].label )

      let data =''
      if(this.$refs["myCascader"].getCheckedNodes()&&this.$refs["myCascader"].getCheckedNodes()[0]&&this.$refs["myCascader"].getCheckedNodes()[0].pathLabels){
        data = this.$refs["myCascader"].getCheckedNodes()[0].pathLabels
      }else{
        return
      }
      // 切换省市区,清空地址
      this.clearAddress()
      this.form = {
        ...this.form,
        area: e || [],
        areaArr: data,
        province: (data && data[0]) || '',
        city: (data && data[1]) || '',
        region: (data && data[2]) || '',
        address: '',

      }
      this.keyword = ''
      this.addressList = []  
     
      this.$nextTick(() => {
        this.getMapLng(data.join(''))
      })
    },
    getMapLng(address) {
      // let res = []
      // // console.log(e)
      // // if (!e) { return } hhr
      // this.loading = true
      getSuggestion1({
        key: this.MAP.KEY,
        address: address || this.form.province||'',

      })
        .then(res => {
          if (res.message == 'query ok') {
            let obj = res.result
            this.form.isSelect = '1'
            this.form.mapCenter = `${obj.location.lat},${obj.location.lng}`
            this.form.location = {
              lat: obj.location.lat,
              lng: obj.location.lng
            }
            this.form.address = obj.title
            this.getMapSrc()
          }

        })
        .catch(err => {
          // this.dataLoading = false
        })

    },
    // 选择地址
    selectAddress(e, props) {
      let item = {}
      try {
        item = (props && props.data.attrs.item) || {}
        item.location = item.location || {}
      } catch (error) { }
      // console.log(e, item)
      if (!item.location) { item.location = {} }
      this.form = {
        ...this.form,
        location: item.location || {},
        mapCenter: `${item.location.lat},${item.location.lng}`,
        // province: item.province || '',
        // city: item.city || '',
        // region: item.region || item.district || '',
        address: `${item.title}${item.address}` || '',
        isSelect: 1,
      }

      this.$nextTick(() => {
        this.getMapSrc()
      })
    },
    // 设置为未选择地址状态
    clearAddress() {
      this.form.isSelect = 0
      this.form.location = {}
    },
    // handleSearch(e) {
    //   if (!this.form.area || this.form.area.length === 0) { return }
    //   const region = this.form.region || ''
    //   if (!region || !e) {
    //     // 设置为未选择地址状态
    //     this.clearAddress()
    //     return
    //   }
    //   // 搜索地址列表
    //   this.ajaxSearch(e)
    // },

    // 搜索地址列表
    // async ajaxSearch(e) {


    //   let res = []
    //   // console.log(e)
    //   if (!e) { return }
    //   this.loading = true
    //   getSuggestion({
    //     key: this.MAP.KEY,
    //     province: this.form.province || '',
    //     city: this.form.city || '',
    //     region: this.form.region || '',
    //     keyword: this.keyword
    //   })
    //     .then(res => {

    //       // if (res.message == 'query ok') {
    //       res = res.data
    //       this.loading = false
 
    //       res = (res && res.data) || res || []
    //       // console.log('搜索地址结果:', res)
    //       const result = res.map((it) => {
    //         it.value = it.id || ''
    //         it.label = it.title || ''
    //         it.desc = it.address || ''
    //         return it
    //       }).filter((it) => it && it.id && it.address) || []
    //       console.log("addrress")
    //       this.addressList = result
    //       console.log(this.addressList)
    //       // this.form.isSelect = '1'
    //       // this.form.mapCenter = '39.827982,116.459249'
    //       // this.form.address = '小红门[地铁站]'
    //       // this.getMapSrc()

    //       // 如果地址结果为空,设置为未选择地址状态
    //       if (result.length === 0) {
    //         this.clearAddress()
    //       }

    //       this.isAjaxSearch = true
    //       // }
    //     })
    //     .catch(err => {
    //       this.dataLoading = false
    //     })
    //   console.log('1111')
    // },

    // 生成图片地图
    getMapSrc() {
      // ${this.form.province || ''}${this.form.city || ''}${this.form.region || ''}
      let title = this.form.isSelect === 0 ? `未选择地址` : `${this.form.address || ''}`
      title = title.substring(0, 13)
      // console.log('title', title)

      let center = this.form.mapCenter
      if (this.form.isSelect === 0) {
        center = '39.12,116.54'
      }

      const obj = {
        center: `${center}`,
        zoom: `17`,
        size: `270*115`,
        maptype: `roadmap`,
        scale: `2`,
        markers: `size:large|color:red|${center}`,
        key: `${this.MAP.KEY}`,
        labels: `border:0|size:12|color:0x262626|bgcolor:white|anchor:3|offset:0_-10|${title}|${center}`
      }
      const str = `https://apis.map.qq.com/ws/staticmap/v2/?${Qs.stringify(obj)}`
      // console.log(str, 'map')
      this.form.mapSrc = str
      this.form.isSelect === 0 && (this.defaultMapSrc = str)
    },

    // getContainer() {
    //   return document.getElementById('component-modal-addr-map')
    // },
    // close() {
    //   this.isAjaxSearch = false
    //   this.$emit('close')
    // },

    // confirm() {
    //   this.$refs.form.validate(valid => {
    //     // console.log('表单数据:', this.form)
    //     if (!valid) { return }

    //     // console.log(valid)

    //     this.$emit('ok', this.form)
    //   })
    // },
// 根据省市区关键字获取下拉数据
export function getSuggestion(obj) {
  return request({
    url: '/qqUrl/ws/place/v1/suggestion/?region='+obj.province+''+obj.city+''+obj.region+'&keyword='+obj.keyword+'&key='+obj.key,
    method: 'get',
    data: obj
  })
}

// 根据位置获取经纬度    
export function getSuggestion1(obj) {
  return request({
    url: '/qqUrl/ws/geocoder/v1/?address='+obj.address+'&key='+obj.key,
    method: 'get',
    data: obj
  })
}

 

 

posted @ 2023-08-30 14:11  shuihanxiao  阅读(282)  评论(0编辑  收藏  举报