You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

403 lines
12 KiB

<template>
<div id="container"></div>
</template>
<script setup>
// 地图map
import AMapLoader from '@amap/amap-jsapi-loader'
import { reactive, ref, onMounted, nextTick, defineEmits, defineProps } from 'vue'
definePageMeta({
layout: false,
})
// const props = defineProps(['searchValue'])
const emit = defineEmits(['mapChange', 'writeBockCity', 'draggingMap'])
/**实际生产中不要用 此处仅测试
具体实际使用方法看官网*/
window._AMapSecurityConfig = {
securityJsCode: '0c4dce68b8380eb47ad26dbea2cff570', // 应用生成的秘钥
}
const props = defineProps(['searchValue', 'position','mapAddress'])
console.log(props)
watch(
() => props.searchValue,
(newValue, oldValue) => {
console.log(props)
// 执行你的操作,比如打印新旧值
console.log('新值:', newValue)
console.log('旧值:', oldValue)
seachAddress(newValue)
// 或者触发其他方法
},
)
// const searchValue = props.searchValue
const lnglat = ref('')
const state = reactive({
map: null,
placeSearch: null,
autoComplete: null,
geoCoder: null,
marker: null,
form: {
address: '',
lng: '',
lat: '',
},
})
// 地图初始化
function initMap(arr) {
// 参数为中心点经纬度坐标
AMapLoader.load({
key: '37b09e9ef9458d8e987b9351420563ab',
version: '2.0',
plugins: [
'AMap.ToolBar',
'AMap.ControlBar',
'AMap.AutoComplete',
'AMap.PlaceSearch',
'AMap.Geocoder',
'AMap.Marker',
'AMap.Pixel',
], // 地图插件 根据需求从高德开放平台添加
})
.then((AMap) => {
state.map = new AMap.Map('container', {
viewMode: '3D', // 是否为3D地图模式
zoom: 10, // 地图显示的缩放级别
zooms: [2, 22], // 地图缩放范围
center: arr, // 地图中心点坐标
resizeEnable: true, // 是否监控地图容器尺寸变化
})
state.geoCoder = new AMap.Geocoder({
city: '全国', // 默认:“全国”
radius: 1000, // 范围,默认:500
})
// ==============================================帮助使用 地名转经纬度
function convertlatOrlon(address) {
state.geoCoder.getLocation(address, function (status, result) {
if (status === 'complete' && result.geocodes.length) {
var lnglat = result.geocodes[0].location
state.marker.setPosition(lnglat);
state.map.add(state.marker);
state.map.setFitView(state.marker);
} else log.error('根据地址查询位置失败');
});
}
if(props.mapAddress) convertlatOrlon(props.mapAddress)
// ==============================================
state.autoComplete = new AMap.AutoComplete({ city: '全国' })
state.placeSearch = new AMap.PlaceSearch({
map: state.map,
})
state.map.on('click', clickMap)
// state.map.addControl(toolBar) // 添加右上角的放大缩小
// state.map.addControl(controlBar) // 添加右上角的放大缩小
if (Object.keys(props.position).length) {
state.form.lng = props.position.lon
state.form.lat = props.position.lat
setMapMarker()
}
})
.catch((e) => {
console.error(e) //加载错误提示
})
.finally(() => {
// initCoord([state.form.lng, state.form.lat])
})
}
const server = {
url: 'https://restapi.amap.com/v5/place/around',
key: '42dab0116529aa771fc2b1094174ce00',
lat: '',
lng: '',
}
// 地图点击事件
function clickMap(e) {
return
// 点击地图事件
if (!e && !e.lnglat) {
return
}
console.log(e)
fetch(`${server.url}?key=${server.key}&types=120000&location=${e.lnglat.lng},${e.lnglat.lat}`).then((res) => {
res.json().then((resoult) => {
emit('mapChange', resoult)
})
})
state.form.lng = e.lnglat.lng
state.form.lat = e.lnglat.lat
regeocoder()
removeMarker() // 先删除地图上标记点
setMapMarker() // 在添加新的标记点
}
// 关键字搜索
const seachAddress = (searchValue) => {
if (searchValue != '') {
//清除地图上的覆盖物
state.map.clearMap()
console.log(11111)
fetch(`https://restapi.amap.com/v3/place/text?key=${server.key}&keywords=${searchValue}`).then((res) => {
res.json().then((resoult) => {
console.log(resoult)
const arr = resoult.pois[0].location.split(',')
state.form.lng = arr[0]
state.form.lat = arr[1]
regeocoder()
removeMarker() // 先删除地图上标记点
setMapMarker()
emit('mapChangeCity', resoult)
})
})
// https://restapi.amap.com/v3/place/text?key=42dab0116529aa771fc2b1094174ce00&keywords=小岳寺
// state.map.plugin('AMap.PlaceSearch', () => {
// let placeSearch = new AMap.PlaceSearch({
// // city 指定搜索所在城市,支持传入格式有:城市名、citycode和adcode
// city: '010',
// map: state.map,
// })
// let that = state.form
// placeSearch.search(searchValue, function (status, result) {
// console.log(searchValue, result)
// // 查询成功时,result即对应匹配的POI信息
// var pois = result.poiList.pois
// for (var i = 0; i < pois.length; i++) {
// var poi = pois[i]
// var marker = []
// marker[i] = new AMap.Marker({
// position: poi.location, // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
// title: poi.name,
// })
// // 将创建的点标记添加到已有的地图实例:
// state.map.add(marker[i])
// }
// state.map.setFitView()
// AMap.Event.addListener(placeSearch, 'markerClick', function (data) {
// let result = data
// //经纬度
// state.form.lng = result.event.lnglat.lng
// state.form.lat = result.event.lnglat.lat
// toGetAddress()
// })
// })
// })
} else {
// alert('请输入地址')
}
}
// 筛选查询
function searchCoord(data) {
if (data) {
//清除地图上的覆盖物
state.map.clearMap()
state.map.setCenter([data.records[0].longitude, data.records[0].latitude])
state.map.setZoom(11)
var marker = []
for (var index = 0; index < data.records.length; index++) {
var poi = data.records[index]
// 其他坐标转J02坐标
var gps = [poi.longitude, poi.latitude]
AMap.convertFrom(gps, 'gps', function (status, result) {
if (result.info === 'ok') {
poi.longitude = result.locations[0].lng
poi.latitude = result.locations[0].lat
}
})
marker[index] = new AMap.Marker({
position: [poi.longitude, poi.latitude],
title: poi.locationName,
})
// 将创建的点标记添加到已有的地图实例:
state.map.add(marker[index])
var content = []
if (poi.personInCharge) {
content.push('负责人: ' + poi.personInCharge + '')
}
marker[index].content = content
marker[index].title = poi.locationName
marker[index].on('click', showInfoWindow)
state.map.off('click', clickMap)
}
}
}
// 自定义窗体
function showInfoWindow(e) {
console.log(111)
//实例化信息窗体
var title = e.target.title,
content = e.target.content
var infoWindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
content: createInfoWindow(title, content.join('<br/>')),
closeWhenClickMap: true,
offset: new AMap.Pixel(16, -45),
})
infoWindow.open(state.map, e.target.getPosition())
}
//构建自定义信息窗体
function createInfoWindow(title, content) {
console.log(222)
var info = document.createElement('div')
info.className = 'custom-info input-card content-window-card'
//可以通过下面的方式修改自定义窗体的宽高
info.style.width = '400px'
// 定义顶部标题
var top = document.createElement('div')
var titleD = document.createElement('div')
top.className = 'info-top'
titleD.innerHTML = title
top.appendChild(titleD)
info.appendChild(top)
// 定义中部内容
var middle = document.createElement('div')
middle.className = 'info-middle'
middle.style.backgroundColor = 'white'
middle.innerHTML = content
info.appendChild(middle)
// 定义底部内容
var bottom = document.createElement('div')
bottom.className = 'info-bottom'
bottom.style.position = 'relative'
bottom.style.top = '0px'
bottom.style.margin = '0 auto'
// var sharp = document.createElement("img");
// sharp.src = "https://webapi.amap.com/images/sharp.png";
// bottom.appendChild(sharp);
info.appendChild(bottom)
return info
}
// 下拉选中查询
function select(e) {
console.log(1111)
state.placeSearch.setCity(e.poi.adcode)
state.placeSearch.search(e.poi.name) //关键字查询查询
}
// 坐标转换
// function initCoord(gps) {
// // 其他坐标转J02坐标
// AMap.convertFrom(gps, 'gps', function (status, result) {
// if (result.info === 'ok') {
// state.form.lng = result.locations[0].lng
// state.form.lat = result.locations[0].lat
// nextTick(function () {
// removeMarker()
// setMapMarker()
// })
// }
// })
// }
// 设置标记
let timer = null
function setMapMarker() {
if (state.form.lng == '' && state.form.lat == '') {
return
}
state.map.setFitView()
state.marker = new AMap.Marker({
map: state.map,
position: [state.form.lng, state.form.lat],
offset: new AMap.Pixel(0, 15), //以 icon 的 [center bottom] 为原点
draggable: true,
cursor: 'move',
// 设置拖拽效果
raiseOnDrag: true,
})
if (Object.keys(props.position).length) {
toGetAddress()
}
state.map.add(state.marker)
state.marker.on('dragging', function (e) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
// console.log('最新坐标:', state.marker.getPosition());
const position = state.marker.getPosition()
state.form.lat = position.lat
state.form.lng = position.lng
toGetAddress()
}, 500);
})
state.map.setFitView()
}
// 清除标记
function removeMarker() {
if (state.marker) {
state.map.remove(state.marker)
}
}
// 坐标位置转换
function regeocoder() {
let lnglat = [state.form.lng, state.form.lat]
state.geoCoder.getAddress(lnglat, (status, result) => {
if (status === 'complete' && result.regeocode) {
state.form.address = result.regeocode.formattedAddress // 返回位置信息
}
})
}
// 获取地址
function toGetAddress() {
let lnglat = [state.form.lng, state.form.lat]
console.log(lnglat);
state.geoCoder.getAddress(lnglat, (status, result) => {
if (status === 'complete' && result.regeocode) {
if (Object.keys(props.position).length) {
emit('writeBockCity', result.regeocode)
}
emit('draggingMap', result.regeocode)
// console.log(result, '1111111111')
// 此处写处理逻辑
} else {
console.log('失败')
}
})
}
function toGetCoordinate() {
let address = state.form.address
state.geocoder.getLocation(address, function (status, result) {
if (status === 'complete' && result.info === 'OK') {
initMap([result.geocodes[0].location.lng, result.geocodes[0].location.lat])
state.form.lng = result.geocodes[0].location.lng
state.form.lat = result.geocodes[0].location.lat
state.form.address = result.geocodes[0].formattedAddress
}
})
nextTick(function () {
removeMarker()
setMapMarker()
})
}
onMounted(() => {
//组件挂载
initMap()
})
/** 样式*/
</script>
<style lang="scss" scoped>
#container {
width: 100%;
height: 100%;
}
</style>