update
init
This commit is contained in:
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<div class="devive-map">
|
||||
<div class="map-search-box">
|
||||
<a-select
|
||||
v-model:value="intValue"
|
||||
allow-clear
|
||||
show-search
|
||||
label-in-value
|
||||
placeholder="请输入地点"
|
||||
style="width: 400px"
|
||||
:default-active-first-option="false"
|
||||
:show-arrow="true"
|
||||
:filter-option="false"
|
||||
:not-found-content="null"
|
||||
@search="onSearch"
|
||||
:options="panelList"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<!-- <a-button type="primary" @click="onButtonSearch"> 搜索 </a-button>-->
|
||||
</div>
|
||||
<div id="panel" style="display: none"></div>
|
||||
<div class="list" id="list"> </div>
|
||||
<div class="map" id="container"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="aed-map" lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import AMapLoader from '@amap/amap-jsapi-loader';
|
||||
import { debounce } from 'lodash-es';
|
||||
import positionIcon from '/@/assets/images/position.png';
|
||||
import MarkersIcon from '/@/assets/images/markerCricle.png';
|
||||
import { list } from './DeviceMap.api';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
let SelfMap = null;
|
||||
let BasicMap = null;
|
||||
let overlayGroup = null;
|
||||
const intValue = ref('');
|
||||
let placeSearch = ref();
|
||||
let panelList = ref([]);
|
||||
let pointerArray = ref([]);
|
||||
let positionRef = ref({
|
||||
lng: '',
|
||||
lat: '',
|
||||
handleItem: {
|
||||
pname: '',
|
||||
},
|
||||
});
|
||||
let mapState = [];
|
||||
let defaultMarker = null;
|
||||
onMounted(() => {
|
||||
initMap();
|
||||
});
|
||||
function initMap() {
|
||||
AMapLoader.load({
|
||||
key: '4bbcb216b889f2d612cbed05ae6979c8',
|
||||
version: '2.0',
|
||||
plugins: ['AMap.Geocoder'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
||||
})
|
||||
.then((AMap) => {
|
||||
SelfMap = AMap;
|
||||
//设置地图容器id
|
||||
BasicMap = new AMap.Map('container', {
|
||||
viewMode: '3D', //是否为3D地图模式
|
||||
// zoom: 11, //初始化地图级别
|
||||
// center: [108.95, 34.33], //初始化地图中心点位置
|
||||
resizeEnable: true,
|
||||
});
|
||||
// 注册搜索插件
|
||||
bindSearch(AMap);
|
||||
handleMarker({});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
/*
|
||||
** 获取区域对角线的两点坐标,即这个区域内的最小坐标值和最大坐标值
|
||||
* @param pointerArray [[a,b],[c,d]]* @return Array {min:number[a,b], max:number[c,d]}
|
||||
* */
|
||||
function getMaxBoundsPointer(pointerArray) {
|
||||
let lngArray = pointerArray.map((item) => item[0]);
|
||||
let latArray = pointerArray.map((item) => item[1]);
|
||||
return { min: [Math.min(...lngArray), Math.min(...latArray)], max: [Math.max(...lngArray), Math.max(...latArray)] };
|
||||
}
|
||||
/**
|
||||
* @Description:输入框查询位置
|
||||
* @date 2023/7/8
|
||||
*/
|
||||
function onSearch(value: string) {
|
||||
//关键字查询
|
||||
if (value) {
|
||||
intValue.value = value;
|
||||
searchRes(value);
|
||||
}
|
||||
}
|
||||
const searchRes = debounce((value) => {
|
||||
placeSearch.value.search(value, (status: string, result: any) => {
|
||||
if (status === 'complete') {
|
||||
panelList.value = result.poiList.pois.map((item) => ({ label: item.name, value: item.name, ...item }));
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
function onButtonSearch() {
|
||||
onSearch(intValue.value);
|
||||
}
|
||||
/**
|
||||
* @Description下拉框选择事件
|
||||
* @date 2023/8/30
|
||||
*/
|
||||
function handleChange(value: any, option: any) {
|
||||
if (option) {
|
||||
setMapZoom(16);
|
||||
let params = {
|
||||
longitude: option.location.lng, // 经度
|
||||
latitude: option.location.lat, // 纬度
|
||||
radiusRange: '50', // 半径范围
|
||||
};
|
||||
addDefault(option.location.lng, option.location.lat);
|
||||
handleMarker(params);
|
||||
} else {
|
||||
handleMarker({});
|
||||
setMapZoom(12);
|
||||
removeDefault();
|
||||
}
|
||||
}
|
||||
function handleMarker(params) {
|
||||
list(params).then((res) => {
|
||||
if (res.length > 0) {
|
||||
pointerArray.value = res;
|
||||
let maxLocations = getMaxBoundsPointer(res.map((item) => [item.longitude, item.latitude]));
|
||||
hanleBounds(maxLocations);
|
||||
addMarker(res);
|
||||
} else {
|
||||
removeMarker();
|
||||
// message.warn('该位置附近暂无设备!');
|
||||
}
|
||||
});
|
||||
}
|
||||
function hanleBounds(maxLocations) {
|
||||
let lngGap = (maxLocations.max[0] - maxLocations.min[0]) / 4;
|
||||
let latGap = (maxLocations.max[1] - maxLocations.min[1]) / 4;
|
||||
let min = new SelfMap.LngLat(maxLocations.min[0] - lngGap, maxLocations.min[1] - latGap);
|
||||
let max = new SelfMap.LngLat(maxLocations.max[0] + lngGap, maxLocations.max[1] + latGap);
|
||||
if (pointerArray.value.length > 1) {
|
||||
let bounds = new SelfMap.Bounds(min, max);
|
||||
BasicMap.setBounds(bounds);
|
||||
}
|
||||
// 2. 一个点时,将其作为中心点
|
||||
else if (pointerArray.value.length === 1) {
|
||||
let pointValue = pointerArray.value;
|
||||
let centerLngLat = new SelfMap.LngLat(pointValue[0].longitude, pointValue[0].latitude);
|
||||
BasicMap.setCenter(centerLngLat); // 设置地图中心点坐标
|
||||
}
|
||||
}
|
||||
// 加载默认图标
|
||||
function addDefault(longitude, latitude) {
|
||||
removeDefault();
|
||||
let defaultIcon = new SelfMap.Icon({
|
||||
image: MarkersIcon,
|
||||
size: new SelfMap.Size(50, 58), //图标大小
|
||||
imageSize: new SelfMap.Size(50, 58),
|
||||
});
|
||||
|
||||
defaultMarker = new SelfMap.Marker({
|
||||
icon: defaultIcon,
|
||||
position: [longitude, latitude],
|
||||
offset: [-18, -32],
|
||||
maxZoom: 14,
|
||||
});
|
||||
defaultMarker.setMap(BasicMap);
|
||||
BasicMap.setCenter([longitude, latitude], true);
|
||||
}
|
||||
function addMarker(position) {
|
||||
removeMarker();
|
||||
if (position.length === 0) {
|
||||
return;
|
||||
}
|
||||
overlayGroup = new SelfMap.OverlayGroup();
|
||||
position.map((item) => {
|
||||
let marker = new SelfMap.Marker({
|
||||
icon: positionIcon,
|
||||
position: [item.longitude, item.latitude],
|
||||
offset: [-18, -32],
|
||||
maxZoom: 14,
|
||||
});
|
||||
marker.on('click', () => {
|
||||
infoWindow(item);
|
||||
});
|
||||
overlayGroup.setMap(BasicMap);
|
||||
overlayGroup.addOverlay(marker);
|
||||
});
|
||||
}
|
||||
function removeDefault() {
|
||||
defaultMarker && BasicMap.remove(defaultMarker);
|
||||
}
|
||||
function removeMarker() {
|
||||
if (overlayGroup) {
|
||||
BasicMap.remove(overlayGroup);
|
||||
overlayGroup.setMap(null);
|
||||
overlayGroup = null;
|
||||
}
|
||||
}
|
||||
function infoWindow(position) {
|
||||
let startDiv = `<div class="dialog-conMap">
|
||||
<div class="item">
|
||||
<span> 设备型号:</span>
|
||||
<span>${position.hostModel}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span>设备编号:</span>
|
||||
<span>${position.hostSerialNum}</span>
|
||||
</div>
|
||||
`;
|
||||
if (position.installAddress) {
|
||||
startDiv += `<div class="item">
|
||||
<span>布点位置:</span>
|
||||
<span>${position.installAddress}</span>
|
||||
</div>`;
|
||||
}
|
||||
if (position.mfrsMobile) {
|
||||
startDiv += ` <div class="item">
|
||||
<span>售后电话:</span>
|
||||
<span>${position.mfrsMobile}</span>
|
||||
</div>`;
|
||||
}
|
||||
if (position.manageUserMobile) {
|
||||
startDiv += ` <div class="item">
|
||||
<span>管理人电话:</span>
|
||||
<span>${position.manageUserMobile}</span>
|
||||
</div>`;
|
||||
}
|
||||
if (position?.chargeFirstMobile) {
|
||||
startDiv += ` <div class="item">
|
||||
<span>负责人1电话:</span>
|
||||
<span>${position?.chargeFirstMobile}</span>
|
||||
</div>`;
|
||||
}
|
||||
if (position.chargeSecondMobile) {
|
||||
startDiv += ` <div class="item">
|
||||
<span>负责人2电话:</span>
|
||||
<span>${position?.chargeSecondMobile}</span>
|
||||
</div>`;
|
||||
}
|
||||
let endDiv = `</div>`;
|
||||
let infoWindow = new SelfMap.InfoWindow({
|
||||
position: [position.longitude, position.latitude],
|
||||
offset: new SelfMap.Pixel(0, -30),
|
||||
content: startDiv + endDiv,
|
||||
});
|
||||
infoWindow.open(BasicMap);
|
||||
}
|
||||
function setMapZoom(zoom: number) {
|
||||
if (zoom) BasicMap && (BasicMap as any).setZoom(zoom);
|
||||
}
|
||||
// 搜索插件
|
||||
function bindSearch(AMap) {
|
||||
AMap.plugin(['AMap.PlaceSearch'], function () {
|
||||
//构造地点查询类
|
||||
placeSearch.value = new AMap.PlaceSearch({
|
||||
pageSize: 20, // 单页显示结果条数
|
||||
pageIndex: 1, // 页码
|
||||
panel: 'panel', // 结果列表将在此容器中进行展示。
|
||||
autoFitView: false, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.devive-map {
|
||||
width: 100%;
|
||||
height: calc(100vh - 130px);
|
||||
.map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.map-search-box {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
z-index: 10;
|
||||
box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.panel-list {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
max-height: 90%;
|
||||
overflow-y: auto;
|
||||
top: 70px;
|
||||
left: 13px;
|
||||
width: 280px;
|
||||
z-index: 9;
|
||||
.panel-item {
|
||||
padding: 10px 5px;
|
||||
color: #999;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.dialog-conMap {
|
||||
padding: 10px;
|
||||
width: 380px;
|
||||
.item {
|
||||
padding: 8px 0;
|
||||
display: flex;
|
||||
span:nth-child(1) {
|
||||
display: inline-block;
|
||||
width: 30%;
|
||||
text-align: right;
|
||||
}
|
||||
span:nth-child(2) {
|
||||
display: inline-block;
|
||||
width: 70%;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user