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.
414 lines
11 KiB
414 lines
11 KiB
6 months ago
|
<template>
|
||
|
<div class="home_div">
|
||
|
<div id="search">
|
||
|
<a-input
|
||
|
v-model:value="searchValue"
|
||
|
@keyup.enter="seachAddress"
|
||
|
id="tipinput"
|
||
|
placeholder="请输入要搜索的位置"
|
||
|
style="width: 200px; margin: -1px 2px 0 12px"
|
||
|
/>
|
||
|
<a-button type="primary" @click="seachAddress">查询</a-button>
|
||
|
</div>
|
||
|
<div id="container" style="height: 50vh; width: 100%"></div>
|
||
|
</div>
|
||
|
</template>
|
||
|
<script setup>
|
||
|
// 地图map
|
||
|
import AMapLoader from "@amap/amap-jsapi-loader"
|
||
|
import { reactive, ref, onMounted, nextTick, defineProps } from 'vue';
|
||
|
import { shallowRef } from '@vue/reactivity'
|
||
|
|
||
|
/**实际生产中不要用 此处仅测试
|
||
|
具体实际使用方法看官网*/
|
||
|
window._AMapSecurityConfig = {
|
||
|
securityJsCode: '0c4dce68b8380eb47ad26dbea2cff570', // 应用生成的秘钥
|
||
|
}
|
||
|
|
||
|
const searchValue = ref('')
|
||
|
const lnglat = ref('')
|
||
|
const state = reactive({
|
||
|
|
||
|
map: null,
|
||
|
placeSearch: null,
|
||
|
autoComplete: 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'], // 地图插件 根据需求从高德开放平台添加
|
||
|
}).then((AMap) => {
|
||
|
state.map = new AMap.Map('container', {
|
||
|
viewMode: "3D", // 是否为3D地图模式
|
||
|
zoom: 10, // 地图显示的缩放级别
|
||
|
zooms:[2,22], // 地图缩放范围
|
||
|
center: arr, // 地图中心点坐标
|
||
|
resizeEnable: true // 是否监控地图容器尺寸变化
|
||
|
});
|
||
|
// 地图放大缩小插件
|
||
|
let toolBar = new AMap.ToolBar({
|
||
|
position: {
|
||
|
top: '120px',
|
||
|
right: '51px'
|
||
|
}
|
||
|
})
|
||
|
// 3D地图插件
|
||
|
let controlBar = new AMap.ControlBar({
|
||
|
position: {
|
||
|
top: '20px',
|
||
|
right: '20px',
|
||
|
},
|
||
|
});
|
||
|
|
||
|
state.geoCoder = new AMap.Geocoder({
|
||
|
city: '全国', // 默认:“全国”
|
||
|
radius: 1000 // 范围,默认:500
|
||
|
})
|
||
|
|
||
|
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); // 添加右上角的放大缩小
|
||
|
}).catch((e) => {
|
||
|
console.error(e); //加载错误提示
|
||
|
}).finally(() => {
|
||
|
initCoord([state.form.lng, state.form.lat])
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// 地图点击事件
|
||
|
function clickMap(e) { // 点击地图事件
|
||
|
if (!e && !e.lnglat) {
|
||
|
return
|
||
|
}
|
||
|
state.form.lng = e.lnglat.lng
|
||
|
state.form.lat = e.lnglat.lat
|
||
|
regeocoder()
|
||
|
removeMarker() // 先删除地图上标记点
|
||
|
setMapMarker() // 在添加新的标记点
|
||
|
}
|
||
|
|
||
|
// 关键字搜索
|
||
|
const seachAddress = () => {
|
||
|
if (searchValue.value != '') {
|
||
|
//清除地图上的覆盖物
|
||
|
state.map.clearMap()
|
||
|
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.value, function (status, 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) {
|
||
|
//实例化信息窗体
|
||
|
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) {
|
||
|
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) {
|
||
|
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()
|
||
|
})
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 设置标记
|
||
|
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],
|
||
|
})
|
||
|
toGetAddress()
|
||
|
state.map.add(state.marker)
|
||
|
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]
|
||
|
state.geoCoder.getAddress(lnglat, (status, result) => {
|
||
|
if (status === 'complete' && result.regeocode) {
|
||
|
// 此处写处理逻辑
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
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 scope>
|
||
|
.home_div{
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
padding: 0px;
|
||
|
margin: 0px;
|
||
|
position: relative;
|
||
|
}
|
||
|
#container{
|
||
|
padding: 0px;
|
||
|
margin: 0px;
|
||
|
}
|
||
|
|
||
|
html, body, #container {
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
.content-window-card {
|
||
|
position: relative;
|
||
|
box-shadow: none;
|
||
|
bottom: 0;
|
||
|
left: 0;
|
||
|
width: auto;
|
||
|
padding: 0;
|
||
|
}
|
||
|
|
||
|
.content-window-card p {
|
||
|
height: 2rem;
|
||
|
}
|
||
|
|
||
|
.custom-info {
|
||
|
border: solid 1px silver;
|
||
|
}
|
||
|
|
||
|
div.info-top {
|
||
|
position: relative;
|
||
|
background: none repeat scroll 0 0 #F9F9F9;
|
||
|
border-bottom: 1px solid #CCC;
|
||
|
border-radius: 5px 5px 0 0;
|
||
|
}
|
||
|
|
||
|
div.info-top div {
|
||
|
display: inline-block;
|
||
|
color: #333333;
|
||
|
font-size: 14px;
|
||
|
font-weight: bold;
|
||
|
line-height: 31px;
|
||
|
padding: 0 10px;
|
||
|
}
|
||
|
|
||
|
div.info-top img {
|
||
|
position: absolute;
|
||
|
top: 10px;
|
||
|
right: 10px;
|
||
|
transition-duration: 0.25s;
|
||
|
}
|
||
|
|
||
|
div.info-top img:hover {
|
||
|
box-shadow: 0px 0px 5px #000;
|
||
|
}
|
||
|
|
||
|
div.info-middle {
|
||
|
font-size: 12px;
|
||
|
padding: 10px 6px;
|
||
|
line-height: 20px;
|
||
|
}
|
||
|
|
||
|
div.info-bottom {
|
||
|
height: 0px;
|
||
|
width: 100%;
|
||
|
clear: both;
|
||
|
text-align: center;
|
||
|
}
|
||
|
|
||
|
div.info-bottom img {
|
||
|
position: relative;
|
||
|
z-index: 104;
|
||
|
}
|
||
|
|
||
|
span {
|
||
|
margin-left: 5px;
|
||
|
font-size: 11px;
|
||
|
}
|
||
|
|
||
|
.info-middle img {
|
||
|
float: left;
|
||
|
margin-right: 6px;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
</style>
|
||
|
|