<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 项目通过高德地图获取经纬度,通过经纬度地图定位
于 2024-08-21 09:25:16 首次发布