<template>
<div>
<baidu-map
id="allmap"
:center="center"
:zoom="zoom"
@ready="handler"
style="height:9.45rem;width: 100%;"
:scroll-wheel-zoom="true"
>
<div class="drawing-panel">
<el-date-picker
v-model="startTime"
type="datetime"
placeholder="开始时间"
format="yyyy-MM-DD HH:mm:ss"
value-format="yyyy-MM-DD HH:mm:ss"
class="time-picker"
/>
<el-date-picker
v-model="endTime"
type="datetime"
placeholder="结束时间"
format="yyyy-MM-DD HH:mm:ss"
value-format="yyyy-MM-DD HH:mm:ss"
class="time-picker"
/>
<el-button type="primary" @click="searchConfirm">查询</el-button>
<button class="btn" @click="play(1)">播放</button>
<button class="btn" @click="play(2)">暂停</button>
<button class="btn" @click="play(3)">停止</button>
</div>
</baidu-map>
</div>
</template>
<script>
export default {
name: 'BtAddrBaiDu',
data() {
return {
startTime: null,
endTime: null,
center: { lng: 114.085947, lat: 22.547 },
zoom: 15,
gpsArr: [
{ lng: 114.000069, lat: 22.500069 },
],
speed: 500,
lushu: null,
batteryId: "",
mapInstance: null,
BMap: null,
bMapLib: null
};
},
mounted() {
// 从父组件获取电池ID
this.batteryId = "电池编号:" + this.$parent.$children[0].hwid;
},
methods: {
searchConfirm() {
if (!this.mapInstance) {
console.error('地图尚未初始化');
return;
}
this.loadData();
},
// 地图初始化回调
handler({ BMap, map }) {
this.BMap = BMap;
this.mapInstance = map;
this.bMapLib = window.BMapLib; // 从全局获取BMapLib
// 初始化地图设置
map.enableScrollWheelZoom(true);
map.centerAndZoom(new BMap.Point(114.085947, 22.547), 15);
// 添加控件
map.addControl(new BMap.OverviewMapControl({ isOpen: true, anchor: BMap.ANCHOR_BOTTOM_RIGHT }));
map.addControl(new BMap.NavigationControl());
map.addControl(new BMap.ScaleControl({ anchor: BMap.ANCHOR_TOP_LEFT }));
map.addControl(new BMap.MapTypeControl({
mapTypes: [BMAP_NORMAL_MAP, BMAP_SATELLITE_MAP],
anchor: BMap.ANCHOR_TOP_RIGHT
}));
// 修改LuShu原型(只需一次)
this.bMapLib.LuShu.prototype._move = function(initPos, targetPos, effect) {
var pointsArr = [initPos, targetPos];
var me = this,
currentCount = 0,
timer = 10,
step = this._opts.speed / (1000 / timer),
init_pos = this._projection.lngLatToPoint(initPos),
target_pos = this._projection.lngLatToPoint(targetPos),
count = Math.round(me._getDistance(init_pos, target_pos) / step);
this._map.addOverlay(
new BMap.Polyline(pointsArr, {
strokeColor: "#111",
strokeWeight: 3,
strokeOpacity: 0.5
})
);
if (count < 1) {
me._moveNext(++me.i);
return;
}
me._intervalFlag = setInterval(function() {
if (currentCount >= count) {
clearInterval(me._intervalFlag);
if (me.i > me._path.length) return;
me._moveNext(++me.i);
} else {
currentCount++;
var x = effect(init_pos.x, target_pos.x, currentCount, count),
y = effect(init_pos.y, target_pos.y, currentCount, count),
pos = me._projection.pointToLngLat(new BMap.Pixel(x, y));
if (currentCount == 1) {
var proPos = null;
if (me.i - 1 >= 0) proPos = me._path[me.i - 1];
if (me._opts.enableRotation == true) {
me.setRotation(proPos, initPos, targetPos);
}
if (me._opts.autoView && !me._map.getBounds().containsPoint(pos)) {
me._map.setCenter(pos);
}
}
me._marker.setPosition(pos);
me._setInfoWin(pos);
}
}, timer);
};
// 初始加载数据
this.loadData();
},
// 数据加载方法
async loadData() {
try {
// 清除旧覆盖物
this.mapInstance.clearOverlays();
const { data } = await this.$http({
url: this.$http.adornUrl('/mqtt/mtgpslocationinfo/queryGpsLocationInfos'),
method: 'get',
params: this.$http.adornParams({
'startTime': this.startTime,
'endTime': this.endTime,
'thingid': this.$parent.$children[0].hwid
})
});
if (data && data.code === 0 && data.data && data.data.length > 0) {
const socitem = data.data;
const arrPois = [];
// 处理最后一个点作为中心点
const lastPoint = socitem[socitem.length - 1];
this.center = { lng: lastPoint.longitude, lat: lastPoint.latitude };
this.mapInstance.panTo(new this.BMap.Point(lastPoint.longitude, lastPoint.latitude));
// 创建图标
const myIcon = new this.BMap.Icon(
require("../../../assets/img/markers.png"),
new this.BMap.Size(23, 25),
{ offset: new this.BMap.Size(10, 25), imageOffset: new this.BMap.Size(0, -275) }
);
// 处理所有点
socitem.forEach((item, i) => {
const point = new this.BMap.Point(item.longitude, item.latitude);
arrPois.push(point);
// 计算距离
const distance = this.getDistance(
lastPoint.latitude, lastPoint.longitude,
item.latitude, item.longitude
);
// 信息窗口内容
const content = `
<div class="bubble-content">
<h4 class="bubble-title">坐标信息</h4>
<div class="bubble-body">
<p>电池编号:${item.thingId}</p>
<p>经纬度:${item.longitudedirectionValue}${item.longitude},${item.latitudedirectionValue}${item.latitude}</p>
<p>与最新点距离:${distance.toFixed(2)}m</p>
<p>时间:${item.uploadTime}</p>
</div>
</div>
`;
// 创建标记
const marker = this.createMarker(point, content, i, myIcon);
this.mapInstance.addOverlay(marker);
// 添加圆点
const circle = new this.BMap.Circle(point, 6, {
strokeColor: 'Red',
strokeWeight: 8,
strokeOpacity: 0.8,
fillColor: '#f03'
});
this.mapInstance.addOverlay(circle);
});
// 添加折线
const polyLine = new this.BMap.Polyline(arrPois, {
strokeWeight: 2,
strokeOpacity: 0.5,
strokeColor: "#303133",
enableEditing: false,
enableClicking: false,
icons: [new this.BMap.IconSequence(
new this.BMap.Symbol(BMap_Symbol_SHAPE_BACKWARD_OPEN_ARROW, {
scale: 0.3,
strokeColor: '#fff',
strokeWeight: 1
}),
'100%',
'5%',
false
)]
});
this.mapInstance.addOverlay(polyLine);
// 初始化路径动画
this.initLushu(arrPois);
} else {
console.log('没有数据显示');
// 添加无数据提示
const noDataLabel = new this.BMap.Label('暂无轨迹数据', {
position: this.mapInstance.getCenter(),
offset: new this.BMap.Size(-50, 0)
});
noDataLabel.setStyle({
color: '#f56c6c',
backgroundColor: 'rgba(255,255,255,0.7)',
padding: '10px',
borderRadius: '5px',
border: '1px solid #f56c6c'
});
this.mapInstance.addOverlay(noDataLabel);
}
} catch (error) {
console.error('数据加载失败:', error);
this.$message.error('轨迹数据加载失败: ' + error.message);
}
},
// 计算两点间距离
getDistance(lat1, lng1, lat2, lng2) {
const EARTH_RADIUS = 6378.137;
const rad = d => d * Math.PI / 180.0;
const radLat1 = rad(lat1);
const radLat2 = rad(lat2);
const a = radLat1 - radLat2;
const b = rad(lng1) - rad(lng2);
const s = 2 * Math.asin(Math.sqrt(
Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
));
return s * EARTH_RADIUS * 1000; // 返回米
},
// 初始化路径动画
initLushu(arrPois) {
if (!arrPois || arrPois.length < 2) return;
this.lushu = new this.bMapLib.LuShu(this.mapInstance, arrPois, {
defaultContent: this.batteryId,
autoView: true,
icon: new this.BMap.Icon(
require("../../../assets/img/mybike2.png"),
new this.BMap.Size(52, 26),
{ anchor: new this.BMap.Size(27, 13) }
),
speed: this.speed,
enableRotation: true
});
},
// 控制动画播放
play(action) {
if (!this.lushu) {
this.$message.warning('请先查询轨迹数据');
return;
}
switch (action) {
case 1: // 播放
this.lushu.start();
break;
case 2: // 暂停
this.lushu.pause();
break;
case 3: // 停止
this.lushu.stop();
break;
}
},
// 创建标记点
createMarker(point, content, index, icon) {
const marker = new this.BMap.Marker(point, { icon });
// 添加标签
const label = new this.BMap.Label(index + 1, {
offset: new this.BMap.Size(-3, -5)
});
label.setStyle({
color: '#fff',
fontSize: '12px',
width: '25px',
height: '25px',
lineHeight: '25px',
textAlign: 'center',
background: 'transparent',
border: 'none'
});
marker.setLabel(label);
// 信息窗口配置
const infoWindow = new this.BMap.InfoWindow(content, {
width: 300,
height: 180
});
// 添加交互事件
marker.addEventListener("mouseover", () => {
marker.openInfoWindow(infoWindow);
});
marker.addEventListener("mouseout", () => {
marker.closeInfoWindow();
});
return marker;
}
}
};
</script>
<style scoped>
.drawing-panel {
position: absolute;
bottom: 20px;
right: 20px;
padding: 12px;
border-radius: 5px;
background-color: #fff;
box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
z-index: 999;
display: flex;
gap: 10px;
flex-wrap: wrap;
max-width: 80%;
}
.time-picker {
width: 180px;
}
.btn {
min-width: 60px;
height: 36px;
background-color: #fff;
color: #1b8eec;
border: 1px solid #1b8eec;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.btn:hover {
background-color: #1b8eec;
color: #fff;
}
/* 信息窗口样式 */
.bubble-content {
color: #333;
font-size: 14px;
}
.bubble-title {
background-color: #409EFF;
color: white;
padding: 8px;
margin: 0;
border-radius: 4px 4px 0 0;
}
.bubble-body {
padding: 10px;
background-color: rgba(240, 240, 240, 0.9);
border-radius: 0 0 4px 4px;
}
.bubble-body p {
margin: 5px 0;
}
</style>
有什么办法解决日期选择器禁用失效问题,因为该组件默认的格式就是yyyy-MM-dd