<template>
|
<div class="map-container">
|
<div class="map-content" id="map" ref="map"></div>
|
|
<div class="shadow"></div>
|
<!-- 图标菜单 -->
|
<div class="info-box">
|
<!-- right菜单-->
|
<div class="info-div" :class="{ 'info-active': item.isActive }" v-for="item in legendList" :key="item.id"
|
@click="selectLegend(item)">
|
<img :src="item.icon" alt="" class="item-tb-img">
|
<div class="info-div-p">
|
<p class="info-label">{{ item.name }}</p>
|
<p class="info-num">{{ item.num }}</p>
|
</div>
|
</div>
|
</div>
|
|
|
|
<!-- 实时路况 -->
|
<div class="road" @click="showRoad">
|
<div class="item-tb">
|
<img src="@/assets/img/sslk.png" alt="" class="item-tb-img">
|
<p class="item-tb-p">实时路况</p>
|
</div>
|
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { onMounted, ref } from 'vue';
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
|
import { require } from '@/utils/require.js';
|
|
import icon1 from '@/assets/img/icon/icon1.png';
|
import icon2 from '@/assets/img/icon/icon2.png';
|
import icon3 from '@/assets/img/icon/icon3.png';
|
import icon4 from '@/assets/img/icon/icon4.png';
|
import icon5 from '@/assets/img/icon/icon5.png';
|
import icon6 from '@/assets/img/icon/icon6.png';
|
import icon7 from '@/assets/img/icon/icon7.png';
|
import icon8 from '@/assets/img/icon/icon8.png';
|
import icon9 from '@/assets/img/icon/icon9.png';
|
|
|
const map = ref(null);
|
let mapInstance = null;
|
let trafficLayer = null;;
|
|
// 是否显示实时路况
|
let isVisible = true;
|
|
// 地图的图标数组
|
const markers = [];
|
|
// 图列
|
const legendList = ref([
|
{
|
id: 1,
|
name: '事故易发多发路段',
|
num: 78,
|
type: 1,
|
icon: icon1,
|
positions: [[103.647593, 30.981856], [103.646627, 30.988235], [103.650077, 30.988074]],
|
isActive: false
|
},
|
{
|
id: 2,
|
name: '重点旅游通道',
|
type: 2,
|
num: 178,
|
positions: [[103.647888, 30.985006], [103.650983, 30.986252], [103.641461, 30.984588]],
|
icon: icon2,
|
isActive: false
|
},
|
{
|
id: 3,
|
name: '都江堰景区',
|
num: 278,
|
positions: [[103.637916, 30.986298], [103.636751, 30.989508], [103.64093, 30.99344]],
|
type: 3,
|
icon: icon3,
|
isActive: false
|
},
|
{
|
id: 4,
|
name: '警力配备',
|
num: 348,
|
positions: [[103.646413, 30.996714], [103.634337, 31.0026], [103.620841, 31.001253]],
|
type: 4,
|
icon: icon4,
|
isActive: false
|
},
|
{
|
id: 5,
|
name: '打围施工',
|
num: 578,
|
positions: [[103.62134, 30.996972], [103.622005, 30.991923], [103.63062, 30.986588]],
|
type: 5,
|
icon: icon5,
|
isActive: false
|
},
|
{
|
id: 6,
|
name: '交通事故易发点',
|
num: 788,
|
positions: [[103.640319, 30.984486], [103.644916, 30.986956], [103.646853, 30.992143]],
|
type: 1,
|
icon: icon6,
|
isActive: false
|
},
|
{
|
id: 7,
|
name: '重点运输企业',
|
num: 758,
|
positions: [[103.651482, 30.995956], [103.639654, 30.995206], [103.631119, 30.987425]],
|
type: 7,
|
icon: icon7,
|
isActive: false
|
},
|
{
|
id: 8,
|
name: '公交线路',
|
num: 758,
|
positions: [[103.652716, 30.974745], [103.668166, 30.976447], [103.672511, 30.979961]],
|
type: 8,
|
icon: icon8,
|
isActive: false
|
},
|
{
|
id: 9,
|
name: '安全隐患',
|
num: 718,
|
positions: [[103.674056, 30.988625], [103.668155, 30.996379], [103.660333, 30.998098]],
|
type: 9,
|
icon: icon9,
|
isActive: false
|
},
|
|
]);
|
|
// 切换状态
|
const selectLegend = (item) => {
|
item.isActive = !item.isActive;
|
const list = hasMarker(item.type);
|
if (list) {
|
if (item.isActive) {
|
list.markerList.map((mark) => {
|
mark.show();
|
})
|
} else {
|
list.markerList.map((mark) => {
|
mark.hide();
|
})
|
}
|
} else {
|
filterLegend(item);
|
}
|
}
|
|
// 过滤图列
|
const filterLegend = (item) => {
|
const { icon, positions, type } = item;
|
const tempList = [];
|
positions.map(position => {
|
const markerIcon = createIcon(icon);
|
const marker = ceateMarker(markerIcon, position);
|
tempList.push(marker);
|
});
|
markers.push({ type: type, markerList: tempList })
|
mapInstance.add(tempList);
|
}
|
|
// 创建图标
|
const createIcon = (img) => {
|
return new AMap.Icon({
|
// size: new AMap.Size(43.8, 49.2), // 图标尺寸
|
image: img, // Icon的图像
|
imageSize: new AMap.Size(43.8, 49.2) // 根据所设置的大小拉伸或压缩图片
|
});
|
}
|
|
|
// 创建marker
|
const ceateMarker = (icon, position) => {
|
return new AMap.Marker({
|
icon: icon,
|
position: new AMap.LngLat(position[0], position[1]),
|
zooms: [2, 20],
|
});
|
}
|
|
const hasMarker = (type) => {
|
return markers.find(item => item.type === type);
|
}
|
|
const showRoad = () => {
|
if (isVisible) {
|
trafficLayer.hide();
|
isVisible = false;
|
} else {
|
trafficLayer.show();
|
isVisible = true;
|
}
|
}
|
|
// 测试
|
const test = () => {
|
const { icon, positions, type } = legendList.value[0];
|
const tempList = [];
|
positions.map(position => {
|
const markerIcon = createIcon(icon);
|
const marker = ceateMarker(markerIcon, position);
|
tempList.push(marker);
|
});
|
|
markers.value.push({ type: type, markerList: tempList })
|
|
}
|
|
|
onMounted(() => {
|
AMapLoader.load({
|
key: "2898109c22191c3969957500934169dc", //申请好的 Web 端开发者 Key,首次调用 load 时必填
|
version: "2.0", //指定要加载的 JS API 的版本,缺省时默认为 1.4.15
|
plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['AMap.Scale','...','...']
|
})
|
.then((AMap) => {
|
mapInstance = new AMap.Map(map.value, {
|
viewMode: '3D',
|
mapStyle: "amap://styles/grey",
|
center: [103.647193, 30.988763],
|
pitch: 60, //地图俯仰角度,有效范围 0 度- 83 度
|
zoom: 19, //初始化地图层级
|
});
|
trafficLayer = new AMap.TileLayer.Traffic({
|
zIndex: 10,
|
zooms: [7, 22],
|
});
|
|
trafficLayer.setMap(mapInstance);
|
|
|
const options = {
|
subdistrict: 0,
|
extensions: "all",
|
level: "district",
|
};
|
|
// 限制一个区域轮廓
|
AMap.plugin("AMap.DistrictSearch", function () {
|
//在回调函数中实例化插件,并使用插件功能
|
const district = new AMap.DistrictSearch(options);
|
district.search("都江堰市", (status, result) => {
|
const outer = [
|
new AMap.LngLat(-360, 90, true),
|
new AMap.LngLat(-360, -90, true),
|
new AMap.LngLat(360, -90, true),
|
new AMap.LngLat(360, 90, true),
|
];
|
const holes = result.districtList[0].boundaries;
|
|
const pathArray = [outer];
|
pathArray.push.apply(pathArray, holes);
|
const polygon = new AMap.Polygon({
|
pathL: pathArray,
|
//线条颜色,使用16进制颜色代码赋值。默认值为#006600
|
strokeColor: "rgb(20,164,173)",
|
strokeWeight: 4,
|
//轮廓线透明度,取值范围[0,1],0表示完全透明,1表示不透明。默认为0.9
|
strokeOpacity: 0.5,
|
//多边形填充颜色,使用16进制颜色代码赋值,如:#FFAA00
|
fillColor: "rgba(0,0,0)",
|
//多边形填充透明度,取值范围[0,1],0表示完全透明,1表示不透明。默认为0.9
|
fillOpacity: 1,
|
//轮廓线样式,实线:solid,虚线:dashed
|
strokeStyle: "solid",
|
/*勾勒形状轮廓的虚线和间隙的样式,此属性在strokeStyle 为dashed 时有效, 此属性在
|
ie9+浏览器有效 取值:
|
实线:[0,0,0]
|
虚线:[10,10] ,[10,10] 表示10个像素的实线和10个像素的空白(如此反复)组成的虚线
|
点画线:[10,2,10], [10,2,10] 表示10个像素的实线和2个像素的空白 + 10个像素的实
|
线和10个像素的空白 (如此反复)组成的虚线*/
|
strokeDasharray: [10, 2, 10],
|
});
|
polygon.setPath(pathArray);
|
mapInstance.add(polygon);
|
});
|
});
|
|
})
|
.catch((e) => {
|
console.log(e);
|
});
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.map-container {
|
width: 100%;
|
height: 100%;
|
position: absolute;
|
z-index: 0;
|
box-shadow: inset 0px 0px 100px 18px #081729;
|
|
.map-content {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
|
.info-div {
|
align-items: center;
|
display: flex;
|
cursor: pointer;
|
margin-top: 0.5rem;
|
height: 2.5rem;
|
line-height: 2.5rem;
|
padding-left: 0.5rem;
|
padding-right: 0.5rem;
|
font-family: PingFang SC;
|
font-weight: 800;
|
border-radius: 6px;
|
|
.item-tb-img {
|
width: 20px;
|
object-fit: contain;
|
margin-right: 5px;
|
}
|
|
.info-div-p {
|
flex: 1;
|
margin-left: 5px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
}
|
|
.info-box {
|
position: absolute;
|
top: 142px;
|
left: 2220px;
|
width: 300px;
|
background: rgba(17, 34, 58, 0.6);
|
border: 1px solid #29466A;
|
padding: 1rem;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.info-label {
|
color: #74A6F2;
|
}
|
|
.info-num {
|
color: #fff;
|
}
|
|
.info-active {
|
background-color: rgba(68, 129, 221, 0.4);
|
}
|
|
.road {
|
position: absolute;
|
bottom: 202px;
|
left: 2434px;
|
z-index: 999;
|
width: 65px;
|
cursor: pointer;
|
|
.item-tb-p {
|
font-family: 'PingFang SC';
|
|
font-weight: 400;
|
font-size: 16px;
|
color: #FFFFFF;
|
line-height: 42px;
|
}
|
}
|
|
.shadow {
|
width: 100%;
|
height: 100%;
|
top: 0;
|
left: 0;
|
position: absolute;
|
box-shadow: inset 0px 0px 100px 120px #081729;
|
pointer-events: none;
|
}
|
|
:deep(.amap-logo) {
|
display: none !important;
|
}
|
|
:deep(.amap-copyright) {
|
visibility: hidden !important;
|
}
|
</style>
|