182 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<template>
 | 
						||
  <section class="AiLocateDialog">
 | 
						||
    <ai-dialog :visible.sync="dialog" title="标绘" @closed="$emit('visible',false),selected={}"
 | 
						||
               @opened="$nextTick(()=>initMap())"
 | 
						||
               @onConfirm="handleConfirm">
 | 
						||
      <div id="amap" v-if="dialog"/>
 | 
						||
      <div class="poi">
 | 
						||
        <el-input ref="poiInput" v-model="search" size="small" clearable @change="handleSearch" placeholder="请输入地点"/>
 | 
						||
      </div>
 | 
						||
      <el-form class="selected" v-if="!!selected.location" id="result" size="mini" label-suffix=":"
 | 
						||
               label-position="left">
 | 
						||
        <div class="header">
 | 
						||
          <i class="iconfont iconLocation"/>
 | 
						||
          <span v-html="[selected.location.lng, selected.location.lat].join(',')"/>
 | 
						||
        </div>
 | 
						||
        <el-form-item label="地点">{{ selected.name || "未知地名" }}</el-form-item>
 | 
						||
        <el-form-item label="类型" v-if="!!selected.type">{{ selected.type }}</el-form-item>
 | 
						||
        <el-form-item label="地址" v-if="!!selected.address">{{ selected.address }}</el-form-item>
 | 
						||
      </el-form>
 | 
						||
    </ai-dialog>
 | 
						||
  </section>
 | 
						||
</template>
 | 
						||
 | 
						||
<script>
 | 
						||
import AMapLoader from '@amap/amap-jsapi-loader'
 | 
						||
 | 
						||
export default {
 | 
						||
  name: "AiLocateDialog",
 | 
						||
  model: {
 | 
						||
    prop: "visible",
 | 
						||
    event: "visible",
 | 
						||
  },
 | 
						||
  props: ['latlng', 'visible'],
 | 
						||
  data() {
 | 
						||
    return {
 | 
						||
      dialog: false,
 | 
						||
      search: "",
 | 
						||
      poi: null,
 | 
						||
      map: null,
 | 
						||
      AMap: null,
 | 
						||
      selected: {},
 | 
						||
      geo: null
 | 
						||
    }
 | 
						||
  },
 | 
						||
  watch: {
 | 
						||
    visible(v) {
 | 
						||
      this.dialog = v
 | 
						||
    }
 | 
						||
  },
 | 
						||
  methods: {
 | 
						||
    initMap() {
 | 
						||
      AMapLoader.load({
 | 
						||
        key: "b553334ba34f7ac3cd09df9bc8b539dc",
 | 
						||
        version: '2.0',
 | 
						||
        plugins: ['AMap.PlaceSearch', 'AMap.Marker', 'AMap.Geolocation'],
 | 
						||
      }).then(AMap => {
 | 
						||
        this.AMap = AMap
 | 
						||
        this.map = new AMap.Map('amap', {
 | 
						||
          zoom: 14,
 | 
						||
          center: this.latlng ? [this.latlng.lng, this.latlng.lat] : ''
 | 
						||
        }).on('click', res => {
 | 
						||
          this.map.clearMap()
 | 
						||
          this.selected = {location: res.lnglat}
 | 
						||
          this.poi?.searchNearBy('', res.lnglat, 100)
 | 
						||
        });
 | 
						||
        if (this.latlng) {
 | 
						||
          let marker = new AMap.Marker({
 | 
						||
            position: [this.latlng.lng, this.latlng.lat]
 | 
						||
          })
 | 
						||
          this.map.add(marker)
 | 
						||
        }
 | 
						||
        this.poi = new AMap.PlaceSearch().on('complete', ({poiList}) => {
 | 
						||
          this.map.clearMap()
 | 
						||
          if (poiList?.length > 0) {
 | 
						||
            poiList?.pois?.map(e => {
 | 
						||
              let marker = new AMap.Marker({
 | 
						||
                position: e.location,
 | 
						||
              }).on('click', () => this.selected = e)
 | 
						||
              this.map.add(marker)
 | 
						||
            })
 | 
						||
          } else {
 | 
						||
            let marker = new AMap.Marker({
 | 
						||
              position: this.selected.location,
 | 
						||
            })
 | 
						||
            this.map.add(marker)
 | 
						||
          }
 | 
						||
        })
 | 
						||
        this.geo = new AMap.Geolocation({
 | 
						||
          enableHighAccuracy: true,//是否使用高精度定位
 | 
						||
          zoomToAccuracy: true//定位成功后是否自动调整地图视野到定位点
 | 
						||
        })
 | 
						||
        this.map.addControl(this.geo)
 | 
						||
      })
 | 
						||
    },
 | 
						||
    handleSearch(v) {
 | 
						||
      if (v) {
 | 
						||
        this.poi.searchNearBy(v, this.map.getCenter(), 50000)
 | 
						||
      }
 | 
						||
    },
 | 
						||
    handleConfirm() {
 | 
						||
      if (this.selected?.location) {
 | 
						||
        this.$emit('confirm', this.selected)
 | 
						||
      } else {
 | 
						||
        this.$message.error('请先选择坐标位置')
 | 
						||
      }
 | 
						||
 | 
						||
    }
 | 
						||
  },
 | 
						||
  created() {
 | 
						||
    this.dialog = this.visible
 | 
						||
  }
 | 
						||
}
 | 
						||
</script>
 | 
						||
 | 
						||
<style lang="scss" scoped>
 | 
						||
.AiLocateDialog {
 | 
						||
  :deep( .el-dialog__body ){
 | 
						||
    padding: 0;
 | 
						||
    height: 480px;
 | 
						||
    position: relative;
 | 
						||
 | 
						||
    .ai-dialog__content--wrapper {
 | 
						||
      padding: 0 !important;
 | 
						||
    }
 | 
						||
 | 
						||
    #amap {
 | 
						||
      width: 100%;
 | 
						||
      height: 480px;
 | 
						||
 | 
						||
      .amap-logo, .amap-copyright {
 | 
						||
        display: none !important;
 | 
						||
      }
 | 
						||
 | 
						||
      .amap-marker-label {
 | 
						||
        border-color: transparent;
 | 
						||
        box-shadow: 1px 1px 0 0 rgba(#999, .2);
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    .poi {
 | 
						||
      position: absolute;
 | 
						||
      left: 10px;
 | 
						||
      top: 10px;
 | 
						||
      display: flex;
 | 
						||
      height: 32px;
 | 
						||
      flex-direction: column;
 | 
						||
 | 
						||
      div {
 | 
						||
        flex-shrink: 0;
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    .selected {
 | 
						||
      position: absolute;
 | 
						||
      right: 16px;
 | 
						||
      top: 16px;
 | 
						||
      background: #fff;
 | 
						||
      min-width: 200px;
 | 
						||
      box-sizing: border-box;
 | 
						||
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
 | 
						||
 | 
						||
      .header {
 | 
						||
        color: #fff;
 | 
						||
        background: #26f;
 | 
						||
        text-align: center;
 | 
						||
        display: flex;
 | 
						||
        align-items: center;
 | 
						||
        height: 32px;
 | 
						||
        font-size: 14px;
 | 
						||
        gap: 4px;
 | 
						||
        padding: 0 8px;
 | 
						||
      }
 | 
						||
 | 
						||
      .el-form-item {
 | 
						||
        padding: 0 8px;
 | 
						||
        margin: 0;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
</style>
 |