<template>
<div class="map">
<baidu-map
class="map-contain"
:scroll-wheel-zoom="true"
:center="center"
:zoom="zoom"
MapType="BMAP_SATELLITE_MAP"
@ready="mapReady"
>
<!-- @mouseout="selectMarker.show = false" -->
<bm-marker
v-for="(marker, index) in markers"
:key="index"
:rotation="marker.rotation"
:offset="{ width: 3, height: 0 }"
:position="marker.position"
@click="markerClick(marker)"
@mouseout="selectMarker.show = false"
:icon="{
url: marker.icon,
size: { width: marker.width, height: marker.height },
}"
>
<bm-label
v-if="marker.label"
:content="marker.label"
:labelStyle="{ color: '#2F80DE', fontSize: '12px' }"
:offset="{ width: -28, height: -30 }"
/>
<bm-info-window
:show="marker.show"
:closeOnClick="false"
@close="infoWindowClose(marker)"
@open="infoWindowOpen(marker)"
>
<p v-if="marker.carInfo.recCode">接运编码:{{ marker.carInfo.recCode }}</p>
<p>车牌号:{{ marker.carInfo.recCarNo }}</p>
<p>司机:{{ marker.carInfo.driver }}</p>
<p v-if="marker.carInfo.contact">承办人:{{ marker.carInfo.contact }}</p>
<p v-if="marker.carInfo.contactPhone">承办人手机号:{{ marker.carInfo.contactPhone }}</p>
<p v-if="marker.carInfo.deadName">逝者名:{{ marker.carInfo.deadName }}</p>
<p v-if="marker.carInfo.purpose">接运用途:{{ marker.carInfo.purpose }}</p>
<p v-if="marker.carInfo.recStateDesc">接运状态:{{ marker.carInfo.recStateDesc }}</p>
<p v-if="marker.carInfo.address">接运地址:{{ marker.carInfo.address }}</p>
<p
v-if="marker.carInfo.transportDestination"
>接运目的地:{{ marker.carInfo.transportDestination }}</p>
<p v-if="marker.carInfo.arrivalTime">预约到达时间:{{ marker.carInfo.arrivalTime }}</p>
</bm-info-window>
</bm-marker>
</baidu-map>
<!-- 左侧弹框 -->
<div class="left_model" :class="moveFlag ? 'leftmodelgo' : 'leftmodelback'">
<div class="left_model_title">
<span>定位监控</span>
</div>
<div class="model_content">
<div class="model_title">
<div class="model_title_item" style="color:#81FF5D;">车牌号</div>
<div class="model_title_item" style="color:#FF6F6F;">司机</div>
<div class="model_title_item" style="color:#F7B500;">时速</div>
<div class="model_title_item" style="color:#70FFE7;">状态</div>
</div>
<!-- @scroll="scrollEvent" ref='seamlessWarp' -->
<div class="seamless_warp">
<div
@click="goItem(marker)"
class="list_item"
:class="[
marker.carInfo.recState == 0 ? 'grey' : '',
marker.carInfo.recState == 1 ? 'going' : '',
marker.carInfo.recState == 2 ? 'back' : '',
marker.carInfo.recState == 3 ? 'yuyue' : '',
marker.carInfo.recState == 4 ? 'yujing' : '',
]"
v-for="(marker, index) in leftData"
:key="index"
>
<span class="item">{{ marker.carInfo.recCarNo }}</span>
<span class="item">{{ marker.carInfo.driver }}</span>
<span class="item number">
<countTo :startVal="0" :endVal="marker.carInfo.speed" :duration="3000"></countTo>
</span>
<span class="recStateDesc">{{ marker.carInfo.recStateDesc }}</span>
</div>
</div>
<!-- <div v-else class="no_data">
<img
class="no_data_img"
:src="require('../assets/no_data.png')"
alt
/>
<span>暂无数据</span>
</div>-->
</div>
</div>
<el-button
@click="moveFlag = !moveFlag"
class="model_close"
type="primary"
:icon="moveFlag ? 'el-icon-back' : 'el-icon-right'"
circle
></el-button>
</div>
</template>
<script>
import * as API from "../api/map";
import countTo from "vue-count-to";
export default {
data() {
return {
timer: null,
moveFlag: true,
boxWidth: 0,
boxHeight: 0,
selectMarker: {
show: false
},
markers: [],
zoom: 12, //地图相关设置
center: { lng: 116.17099999999999, lat: 36.685184 },
//center: { lng: 117.023358, lat: 39.488513 },
scrollTop: 0,
leftData: [],
map: null,
BMap: null,
convertor: null,
points: [],
formatPoints: [],
formatData: []
};
},
components: {
countTo
},
created() {},
mounted() {
this.timer = setInterval(() => {
this.getMapData();
}, 30000);
},
updated() {
//this.scrollToSessionLocation()
},
methods: {
// scrollEvent(){
// // this.scrollTop=this.$refs.seamlessWarp.scrollTop;
// sessionStorage.setItem('scrollTop',this.$refs.seamlessWarp.scrollTop)
// },
// scrollToSessionLocation(){
// console.log("数据更新",sessionStorage.getItem('scrollTop'),'最后滚动位置',this.$refs.seamlessWarp)
// this.$refs.seamlessWarp.scrollTo({
// top: sessionStorage.getItem('scrollTop'),
// behavior: "smooth"
// })
// },
async getMapData() {
let params = {};
try {
let res = await API["getMakers"](params);
if (res.code === 0) return this.$message.error(res.message);
if (res.code === 2) {
this.$message.error(res.message);
clearInterval(this.timer);
sessionStorage.clear();
this.$router.push("/");
return;
}
if (res.data && res.data.length > 0) {
this.markers = [];
this.$nextTick(() => {
//this.markers = res.data;
// this.leftData = [
// {
// position: { lng: 117.17099999999999, lat: 36.685184 },
// show: false,
// width: 30,
// height: 44,
// label: "津B-10G09",
// icon:
// "http://192.168.1.100:8001/fmis/files/image/car/blue1.png",
// imei: "011710319889",
// carInfo: {
// recCode: "JY202203220001",
// speed: 0.0,
// driver: "张秀山",
// statusDesc: "静止",
// status: 0,
// recCarNo: "津B-10G09",
// contact: "百富源",
// contactPhone: "15000000032",
// address: "天津市武清区xx小圆",
// purpose: "遗体接运",
// transportDestination: "殡仪馆",
// deadName: "上好佳",
// recState: 3,
// recStateDesc: "预约任务",
// arrivalTime: "2022-03-22 10:13:00"
// },
// rotation: 0
// },
// ];
this.leftData=res.data
this.formatData = this.getNewArray(this.leftData, 10);
this.points = this.leftData.map(item => item.position);
this.formatPoints = this.getNewArray(this.points, 10);
this.transformationPoint();
});
}
} catch (error) {
console.log(error);
}
// let points=[
// {lng:116.3786889372559,lat:39.90762965106183},
// {lng:116.38632786853032,lat:39.90795884517671},
// {lng:116.39534009082035,lat:39.907432133833574},
// ]
},
//
getNewArray(arr, size) {
// size=5,要分割的长度
const arrNum = Math.ceil(arr.length / size, 10); // Math.ceil()向上取整的方法,用来计算拆分后数组的长度
let index = 0; // 定义初始索引
let resIndex = 0; // 用来保存每次拆分的长度
const result = [];
while (index < arrNum) {
result[index] = arr.slice(resIndex, size + resIndex);
resIndex += size;
index++;
}
return result;
},
//
async transformationPoint() {
let newArr = [];
for (let i = 0; i < this.formatData.length; i++) {
this.convertor.translate(this.formatPoints[i], 1, 5, data => {
if (data.status === 0) {
//转换成功
data.points.forEach(item => {
newArr.push(item);
});
}
});
}
setTimeout(() => {
for (let i = 0; i < this.leftData.length; i++) {
this.leftData[i].position = newArr[i];
}
this.markers = this.leftData;
}, 1000);
},
markerClick(item) {
item.show = true;
},
infoWindowClose(item) {
item.show = false;
},
infoWindowOpen(item) {
item.show = true;
},
//地图初始化
async mapReady({ BMap, map }) {
// let mapStyle = { style: "midnight" };
// map.setMapStyle(mapStyle);
this.map = map;
this.BMap = BMap;
this.convertor = new BMap.Convertor();
await this.getMapData();
var geolocation = new BMap.Geolocation();
// 开启SDK辅助定位
geolocation.enableSDKLocation();
geolocation.getCurrentPosition(r => {}, {
enableHighAccuracy: true //要求浏览器获取最佳结果
});
},
//点击每项
goItem(marker) {
let lng = marker.position.lng
let lat = marker.position.lat
let point = new BMap.Point(lng, lat);
this.map.setCenter(point);
marker.show = true;
}
},
watch: {}
};
</script>
<style lang="scss" scoped>
/* 设置滚动条的样式 */
::-webkit-scrollbar {
width: 0;
}
.sample {
width: 300px;
height: 200px;
border-radius: 15px;
background: rgba(255, 255, 255, 0.6);
box-shadow: 0 0 5px #ccc;
padding: 10px;
position: absolute;
}
.sample.active {
}
.map {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
.map-contain {
width: 100%;
height: 100%;
overflow: hidden;
/deep/ .BMapLabel {
z-index: 1 !important;
border: none !important;
color: #2f80de !important;
box-sizing: border-box !important;
padding: 5px 10px 10px !important;
// background-color: rgba(255, 255, 255, 0.5) !important;
background: url("../assets/pic.png") no-repeat !important;
background-size: 100% 100% !important;
}
}
/deep/ .el-button--primary {
background-color: #04132c;
position: absolute;
left: 12px;
top: 0;
z-index: 122;
}
/* 左侧弹窗 */
.left_model {
width: 460px;
height: 100%;
position: absolute;
left: 12px;
top: 0;
padding: 0 12px;
background-image: url("~@/assets/model_bg.png");
background-repeat: no-repeat;
background-size: 100% 100%;
transition: all 2s;
z-index: 120;
display: flex;
flex-direction: column;
.left_model_title {
position: relative;
width: 100%;
height: 40px;
font-size: 22px;
font-family: SourceHanSansSC-Bold, SourceHanSansSC;
font-weight: bold;
color: #bfe8ff;
line-height: 40px;
text-align: center;
/* margin-bottom: 20px; */
}
.model_content {
width: 100%;
height: calc(100% - 40px);
display: flex;
flex-direction: column;
.model_title {
width: 100%;
height: 50px;
border: 1px solid #1c95dc;
margin-top: 20px;
display: flex;
.model_title_item {
flex: 1;
font-size: 18px;
color: #fff;
text-align: center;
line-height: 50px;
}
}
.seamless_warp {
height: calc(100% - 70px);
overflow-y: scroll;
.list_item {
display: flex;
align-items: center;
line-height: 50px;
color: #fff;
cursor: pointer;
.item {
flex: 1;
text-align: center;
}
.recStateDesc {
width: 150px;
text-align: center;
}
}
.going {
color: #81ff5d;
}
.grey {
color: gray;
}
.back {
color: #eebd2a;
}
.yuyue {
color: #20bbd4;
}
.yujing {
color: #e24646;
}
}
}
}
}
</style>
1、转坐标一次最左转10-个,所以要分割数据
//分割数据
getNewArray(arr, size) {
// size=5,要分割的长度
const arrNum = Math.ceil(arr.length / size, 10); // Math.ceil()向上取整的方法,用来计算拆分后数组的长度
let index = 0; // 定义初始索引
let resIndex = 0; // 用来保存每次拆分的长度
const result = [];
while (index < arrNum) {
result[index] = arr.slice(resIndex, size + resIndex);
resIndex += size;
index++;
}
return result;
},
//转换坐标
async transformationPoint() {
let newArr = [];
for (let i = 0; i < this.formatData.length; i++) {
this.convertor.translate(this.formatPoints[i], 1, 5, data => {
if (data.status === 0) {
//转换成功
data.points.forEach(item => {
newArr.push(item);
});
}
});
}
setTimeout(() => {
for (let i = 0; i < this.leftData.length; i++) {
this.leftData[i].position = newArr[i];
}
this.markers = this.leftData;
}, 1000);
},
|