vue3 项目通过高德地图获取经纬度,通过经纬度地图定位

<template>
  <el-dialog v-model="dialogVisible" title="获取经纬度" width="50%" :close-on-click-modal="false">
    <div class="home">
      <div id="map-box"  ref="mapbox"></div>
      <div class="info-box">
        <div>
          <el-input
            v-model="keyword"
            @change="handleSearch"
            placeholder="输入关键字搜索"
            style="width: 320px"
          />
          <el-button type="primary" @click="handleSearch">搜索</el-button>
        </div>

        <el-tooltip content="点击复制">
          <span>
            经纬度:<span class="copy" style="cursor: pointer" :data-clipboard-text="coord">{{
              coord
            }}</span>
          </span>
        </el-tooltip>
        <div class="list" id="list"></div>
      </div>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="onSubmit">保存</el-button>
        <el-button @click="dialogVisible = false"> 取消 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
declare global {
  interface Window {
    _AMapSecurityConfig: {
      securityJsCode: string
    }
  }
}
import { shallowRef, ref, onBeforeUnmount, defineEmits } from 'vue'
import * as AMapLoader from '@amap/amap-jsapi-loader'
import ClipboardJS from 'clipboard'
const clipboard = new ClipboardJS('.copy')
const dialogVisible = ref(false)
const emit = defineEmits(['eventName'])
clipboard.on('success', function (e) {
  ElMessage({
    message: '复制成功!',
    type: 'success'
  })
  e.clearSelection()
})

clipboard.on('error', function (e) {
  if (!e.text) {
    ElMessage({
      message: '暂无可复制的内容!',
      type: 'warning'
    })
  }
})
const keyword = ref('')
const data = ref([])
const coord = ref('')
const mapbox=ref(null)
const map = shallowRef(null)
interface AMapObj {
  Map: any
  Marker: any
}
let AMapObj: AMapObj, placeSearch: any, marker: any, geocoder: any
window._AMapSecurityConfig = {
  securityJsCode: '57bfa4ab034bf42374bc5a4ca8abba3e'
}
const initMap = (value) => {
  dialogVisible.value = true
  AMapLoader.load({
    key: '9718a15ec8e675c1810591f074cbaf23', // 设置您的key
    version: '2.0',
    plugins: ['AMap.ToolBar', 'AMap.Driving'],
    AMapUI: {
      version: '1.1',
      plugins: []
    },
    Loca: {
      version: '2.0.0'
    }
  })
    .then((AMap: AMapObj) => {
      AMapObj = AMap
      map.value = new AMap.Map(mapbox.value, {
        viewMode: '2D',
        zoom: 12,
        zooms: [2, 22],
        center: [112.55, 37.85]
      })
      map.value.on('click', onMapClick)
      AMap.plugin(
        [
          'AMap.ToolBar',
          'AMap.Scale',
          'AMap.Geolocation',
          'AMap.PlaceSearch',
          'AMap.Geocoder',
          'AMap.AutoComplete'
        ],
        () => {
          // 缩放条
          const toolbar = new AMap.ToolBar()
          // 比例尺
          const scale = new AMap.Scale()
          // 定位
          const geolocation = new AMap.Geolocation({
            enableHighAccuracy: true, // 是否使用高精度定位,默认:true
            timeout: 10000, // 超过10秒后停止定位,默认:5s
            position: 'RT', // 定位按钮的停靠位置
            buttonOffset: new AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
            zoomToAccuracy: true // 定位成功后是否自动调整地图视野到定位点
          })
          geocoder = new AMap.Geocoder({
            city: '全国'
          })
          map.value.addControl(geolocation)
          map.value.addControl(toolbar)
          map.value.addControl(scale)
          placeSearch = new AMap.PlaceSearch({
            city: '全国',
            pageSize: 3, // 单页显示结果条数
            pageIndex: 1, // 页码
            citylimit: false, // 是否强制限制在设置的城市内搜索
            autoFitView: true,
            panel: 'list',
            map: map.value
          })

          if (value) {
            let arr = value.split(',')
            let location = {
              lng: Number(arr[0]),
              lat: Number(arr[1])
            }
            getlocation(location)
          }
        }
      )
    })
    .catch((e) => {
      console.log(e)
    })
}

// 搜索地图
const handleSearch = () => {
  placeSearch.search(keyword.value)
}
// 点击地图
const onMapClick = (e: any) => {
  coord.value = e.lnglat.lng + ',' + e.lnglat.lat
  geocoder.getAddress([e.lnglat.lng, e.lnglat.lat], function (status: string, result: any) {
    if (status === 'complete' && result.info === 'OK') {
      // result为对应的地理位置详细信息
      keyword.value = result.regeocode.formattedAddress
    }
  })
  drawMarker(e.lnglat)
}
const getlocation = (e: any) => {
  coord.value = e.lng + ',' + e.lat

  geocoder.getAddress([e.lng, e.lat], function (status: string, result: any) {
    if (status === 'complete' && result.info === 'OK') {
      // result为对应的地理位置详细信息
      keyword.value = result.regeocode.formattedAddress
    }
  })
  drawMarker(e)
}
// 点击搜索项
const handleSelect = (item: any) => {
  drawMarker(item.location)
  if (item.location != null) {
    coord.value = item.location.lng + ',' + item.location.lat
  }
}
// 绘制地点marker
const drawMarker = (location: any) => {
  console.log(location)
  if (location == null) return
  let longitude = location.lng,
    latitude = location.lat
  if (marker) {
    marker.setMap(null)
  }
  marker = new AMapObj.Marker({
    position: new AMapObj.LngLat(longitude, latitude),
    anchor: 'bottom-center'
  })
  marker.on('click', () => {
    coord.value = location
  })
  map.value.add(marker)
  map.value.setZoomAndCenter(16, [longitude, latitude])
}
const open = (value) => {
  destroyMap()
  initMap(value)
}
const onSubmit = () => {
  emit('valueChange', coord.value)
  destroyMap()
  dialogVisible.value = false
}
const destroyMap = () => {
  coord.value = ''
  keyword.value = ''
  coord.value = ''
  if (map.value) {
    // 移除marker
    if (marker) {
      marker.setMap(null)
      marker = null
    }
    // 移除事件监听器
    map.value.off('click', onMapClick)
    // 清理地图实例
    if (placeSearch) {
      placeSearch.clear()
    }
    map.value.destroy()
  }

  // 清理其他实例
  placeSearch = null
  geocoder = null
}
onBeforeUnmount(() => {
  clipboard.destroy()
  destroyMap()
})
defineExpose({
  open
})
</script>

<style  scoped>
.home {
  height: 450px;
  width: 100%;
  padding: 0px;
  margin: 0px;
  position: relative;
}
.info-box {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 380px;
  background-color: #001529;
  border-radius: 5px;
  padding: 10px;
  color: white;
  display: flex;
  flex-direction: column;
}
#map-box {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}

.search-dropdown {
  max-height: 200px !important;
}
/deep/ .amap-logo {
  display: none !important;
}
/deep/ .amap-copyright {
  display: none !important;
}
</style>

Vue3中使用高德地图API获取用户输入地点的经纬度,通常需要以下几个步骤: 1. **安装依赖**:首先在项目中安装`vue-amap`库,这是一个方便集成高德地图的UI组件和插件,可以快速接入高德地图API。 ```bash npm install vue-amap @vue-amap/core @vue-amap/geolocation ``` 2. **引入并配置**:在Vue文件中引入组件,并在Vue的原型上注册AMap实例,以便后续使用。 ```javascript import { AMapLoader } from '@vue-amap/core' import Geolocation from '@vue-amap/geolocation' export default { setup() { return new Promise((resolve, reject) => { AMapLoader.init({ key: 'your_amap_key', // 替换为你的高德地图API密钥 }).then(() => { const map = new AMap.Map('container', { zoom: 15, center: [116.404, 39.915], // 北京坐标,作为初始位置 }) new Geolocation({ enableHighAccuracy: true, // 提供更精确的位置信息,默认值为true timeout: 10000, // 超时时间,单位毫秒 showButton: false, // 是否显示定位按钮,默认隐藏 }).on('complete', function(position) { resolve({ lat: position.latitude, lng: position.longitude }) // 返回经纬度 }); }); }) } } ``` 3. **创建元素**:在HTML模板中创建一个用于输入地点的input字段和显示经纬度的地方。 ```html <div id="app"> <input v-model="searchText" placeholder="请输入地址..."> <p>经度: {{ lat }}</p> <p>纬度: {{ lng }}</p> </div> ``` 当用户在输入框中输入地址后,你可以通过监听v-model变化来触发地图的地点查找,并获取经纬度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值