vue3-openlayers 轨迹回放(历史轨迹),实时轨迹
本篇介绍一下使用vue3-openlayers轨迹回放(历史轨迹),实时轨迹
1 需求
- 轨迹回放(历史轨迹)
- 实时轨迹
2 分析
可以使用和上一篇相同的办法,即主要是利用定时器,不断添加feature
- 轨迹回放(历史轨迹),一般是一次性拿到所有坐标点,按照时间间隔不断循环添加feature
- 实时轨迹,一般是通过websocket监听,不断获取最新坐标点,根据上报的频率,可能需要抽样
也可以使用ol-animation-path(下篇介绍,其实openlayers也有类似的方法)
3 实现
<template><ol-map:loadTilesWhileAnimating="true":loadTilesWhileInteracting="true"style="width: 100%; height: 100%"ref="mapRef"><ol-viewref="view":center="center":zoom="zoom":projection="projection"/><ol-tile-layer><ol-source-tianditulayerType="img":projection="projection":tk="key":hidpi="true"ref="sourceRef"></ol-source-tianditu></ol-tile-layer><ol-tile-layer><ol-source-tianditu:isLabel="true"layerType="img":projection="projection":tk="key":hidpi="true"></ol-source-tianditu></ol-tile-layer><ol-vector-layer><ol-source-vector><ol-feature v-if="trace.length" ><ol-geom-point :coordinates="trace[trace.length-1][1]" ></ol-geom-point><ol-style><ol-style-icon :src="iconSrc" :width="30" :height="30" :rotation="angle"></ol-style-icon></ol-style></ol-feature><ol-feature v-for="(item, index) in trace" :key="index"><ol-geom-line-string :coordinates="item"></ol-geom-line-string><ol-style><ol-style-stroke color="rgba(228, 147, 87, 1)" :width="3"></ol-style-stroke></ol-style></ol-feature></ol-source-vector></ol-vector-layer></ol-map>
</template><script setup lang="ts">
import iconSrc from '@/assets/image/truck.png';const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const mapRef = ref();
const key = '替换为天地图key';
const sourceRef = ref(null);
const data = ref([[110, 30],[110.2, 30],[110.4, 30.2],[110.8, 30.4],[111, 31],[111.3, 31],[111.6, 31],[111.9, 31],[112, 31],[112.3, 31],[112.5, 31],[112.8, 31],[113, 31],[114, 31],[115.3, 32],[115.5, 32],[115.8, 31.8],[116, 31.4],[116.2, 31.1],[116.5, 30.5],[115, 30.2],[114, 29.8],[113, 29.6],[112, 29.4],[111, 30.2],[110, 30.4],[109, 30.6],[108, 31]
]);
const trace = ref([]);
const angle=ref(0);onMounted(() => {let i = 0;const interval = setInterval(() => {if (data.value[i + 1]) {let arc = 0;if ((data.value[i + 1][0] - data.value[i][0] >= 0 &&data.value[i + 1][1] - data.value[i][1] >= 0) ||(data.value[i + 1][0] - data.value[i][0] < 0 &&data.value[i + 1][1] - data.value[i][1] > 0)) {arc = Math.atan((data.value[i + 1][0] - data.value[i][0]) / (data.value[i + 1][1] - data.value[i][1]));} else if ((data.value[i + 1][0] - data.value[i][0] > 0 &&data.value[i + 1][1] - data.value[i][1] < 0) ||(data.value[i + 1][0] - data.value[i][0] < 0 &&data.value[i + 1][1] - data.value[i][1] < 0)) {arc =Math.PI +Math.atan((data.value[i + 1][0] - data.value[i][0]) /(data.value[i + 1][1] - data.value[i][1]));}angle.value=arctrace.value.push([data.value[i], data.value[i + 1]]);i++;} else {clearInterval(interval);}}, 200);
});
</script>
<style scoped lang="scss">
.overlay-content {background: rgba(255, 255, 255, 0.7);box-shadow: 0 5px 10px rgb(2 2 2 / 20%);padding: 10px 20px;font-size: 16px;color: black;
}
</style>