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
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>
|
|
|