一、引入天地图
1.引入天地图
在Vue项目文件夹public下的index.html入口文件中引入天地图JavaScript API文件
//引入天地图在线链接 tk 为你自己申请的tk
<script src="https://api.tianditu.gov.cn/api?v=3.0&tk=你申请的tk" type="text/javascript"></script>
// 使用运动轨迹时需要引入一下文件
<script src="http://lbs.tianditu.gov.cn/js/lib/d3/d3.min.js" charset="utf-8"></script>
<script src="http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.js"></script>
<script src="http://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/CarTrack.js"></script>
2.创建初始化文件
创建一个Vue中初始化的天地图的JS文件,用于指向天地图类
// 初始化地图
export default {
init() {
return new Promise((resolve, reject) => {
// 如果已加载直接返回
if (window.T) {
console.log('地图脚本初始化成功...')
resolve(window.T)
reject('error')
}
})
}
}
二、 地图初始化
页面
<template>
<div class="map-content" v-loading="loading">
<div class="input-card">
<span>轨迹回放:</span>
<el-button @click="startAnimation()">开始</el-button>
<el-button @click="pauseAnimation()">暂停</el-button>
<el-button @click="resumeAnimation()">继续</el-button>
</div>
<div id="transportMap" ref="tiandituMap"></div>
</div>
</template>
<style lang="scss" scoped>
.map-content {
height: 100vh;
position: relative;
}
#transportMap {
width: 100%;
height: 100%;
}
.input-card {
z-index: 999;
display: flex;
align-items: center;
padding: 20px;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
background-color: #fff;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
}
::v-deep {
.tdt-infowindow-content-wrapper {
z-index: 9999 !important;
background: radial-gradient(rgba(43, 89, 183, 0.90), rgba(0, 42, 146, 0.54));
border-radius: 10px;
color: white;
padding: 20px;
}
.tdt-infowindow-content {
margin: 0;
line-height: 2.0;
}
.tdt-infowindow-tip {
background: radial-gradient(rgba(43, 89, 183, 0.90), rgba(0, 42, 146, 0.54));
}
.tdt-container a.tdt-infowindow-close-button {
color: white;
}
}
</style>
初始化
<script>
import Api from '../Api'
import MapInit from '@/utils/initMap'
export default {
name: 'Trajectory',
data() {
return {
map:null }
},
mounted() {
this.$nextTick(() => {
setTimeout(() => {
this.initMap()
}, 500)
})
},
methods: {
// 地图初始化
initMap() {
MapInit.init().then((T) => {
this.map = new T.Map('transportMap')
this.map.centerAndZoom(new T.LngLat(104.533244, 28.690068), 14)
})
},
}
}
</script>
三、描点、信息窗口、轨迹运动
// 小车线路回放
carSearch() {
const T = window.T
let that = this;
that.loading = true
Api.getTrajectory().then(res => {
that.loading = false
if (res.data.code == 200) {
that.lineArr = res.data.data.gpsList
const startPoint= res.data.data.startNode
const endPoint= res.data.data.endNode
// 向地图上添加自定义标注
// 起点
if (startPoint) {
const startMarker = new T.Marker(startPoint, {
icon: new T.Icon({
iconUrl: '../start.png',
iconAnchor: new T.Point(12, 31)
})
})
that.map.addOverLay(startMarker)
}
// 终点
if (endPoint) {
const endMarker = new T.Marker(endPoint, {
icon: new T.Icon({
iconUrl: '../end.png',
iconAnchor: new T.Point(12, 31)
})
})
that.map.addOverLay(endMarker)
endMarker.addEventListener("click", function (e) {
that.map.centerAndZoom(new T.LngLat(e.lnglat.lng, e.lnglat.lat), that.map.getZoom());
var infoWin1 = new T.InfoWindow({
maxHeight: 250,
offset: new T.Point(0, 0),
minWidth: 250,
autoPan: true,
closeOnClick: true
})
const sContent = `<div>当前位置:${e.address}</div>`;
infoWin1.setContent(sContent)
endMarker.openInfoWindow(infoWin1)
})
}
// 绘制轨迹
that.mapCarTrack = new T.CarTrack(that.map, {
interval: 10,
speed: 8,
dynamicLine: true,
carstyle: { iconUrl: '..car.png' },
polylinestyle: { color: '#28F', width: 6, opacity: 1 },
Datas: that.lineArr?.map(function (obj, i) {
const lnlat = new T.LngLat(obj[0], obj[1])
return lnlat
}),
passOneNode: that.carpassOneNodeRecord
})
var dataslist = that.mapCarTrack.options.Datas;
for (var j = 0; j < that.lineArr.length - 1; j++) {
var p1 = that.mapCarTrack.dataToLnglat(dataslist[j]);
var p2 = that.mapCarTrack.dataToLnglat(dataslist[j + 1]);
var d = that.mapCarTrack.map.getDistance(p1, p2);
for (var k = 0; k < Math.round(d); k++) {
that.trajectoryNodes.push(this.lineArr[j]);
}
}
} else {
that.$message.error(res.data.msg)
}
}).catch((error) => {
this.$message.error(error)
that.loading = false
})
},
// 轨迹回到原点不继续运动
carpassOneNodeRecord(lnglat, index, length) {
if (index == length) {
this.pauseAnimation(); //暂停
}
},
// 开始
startAnimation() {
if (this.mapCarTrack != undefined) {
this.mapCarTrack.start()
} else {
this.$message.warning('当前暂无轨迹');
}
},
// 暂停
pauseAnimation() {
if (this.mapCarTrack != undefined) {
this.mapCarTrack.pause()
}
},
// 继续
resumeAnimation() {
if (this.mapCarTrack != undefined) {
this.mapCarTrack.start()
} else {
this.$message.warning('当前暂无轨迹');
}
},
三、地图自适应容器
map.checkResize()方法来自适应容器,需要配合定时器使用才有效
<el-button @click="isShow = !isShow">{{isShow?'缩小':'放大'}}</el-button>
watch: {
isShow:{
handler: function (newVal) {
this.$refs.tiandituMap.style.width = newVal ? '55%' : '100%';
this.$refs.tiandituMap.style.height = newVal ? '50%' : '100%';
this.loading = true;
setTimeout(() => {
this.map.checkResize();
this.loading = false;
}, 300);
},
}
}