效果
下面的地图图层屏蔽了,不能展示!所以仅有路线demo
核心代码
<template>
<div>
<div id="map" ref="rootmap"></div>
<a-button id="searchPath" type="primary" style="z-index:3" @click="searchPath">{{title}}</a-button>
</div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import { Circle as CircleStyle, Fill, Stroke, Style } from "ol/style";
import Feature from "ol/Feature";
import VectorTileLayer from "ol/layer/VectorTile";
import { LineString, Polygon, Point } from "ol/geom";
import { Vector as VectorSource } from "ol/source";
import VectorLayer from "ol/layer/Vector";
import {
defaults as defaultInteractions
} from "ol/interaction";
import {
defaults as defaultControls,
MousePosition,
} from "ol/control";
import { getVectorContext } from "ol/render";
import { getAction } from "@/api/manage";
import { getCoors } from "@/utils/coordinateUtil";
export default {
data() {
return {
title: "查看当天轨迹",
map: null, //地图对象
pointLayer: null, //路径图层
isShow: false,
url: {
getCoorList: "investigationRecord/getCoorList",
},
dataList: null,
coors: [], //路线坐标
viaPoint: [], //途经点
animating: false,
//路线相关样式
styles: {
route: new Style({
stroke: new Stroke({
width: 6,
color: [0, 30, 255],
}),
}),
start: new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({ color: [0, 191, 94] }),
stroke: new Stroke({
color: "white",
width: 5,
}),
}),
}),
end: new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({ color: [255, 0, 0] }),
stroke: new Stroke({
color: "white",
width: 5,
}),
}),
}),
geoMarker: new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({ color: [0, 30, 255] }),
stroke: new Stroke({
color: "white",
width: 5,
}),
}),
}),
viaMarker: new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({ color: [0, 30, 255] }),
stroke: new Stroke({
color: "white",
width: 5,
}),
}),
}),
},
routeFeature: null,
geoMarker: null,
startMarker: null,
endMarker: null,
speed: 300, //位移速度
nowTime: null,
};
},
created() {
var that = this;
that.getDatas((coors) => {
that.routeFeature = new Feature({
type: "route",
geometry: new LineString(coors),
});
that.geoMarker = new Feature({
type: "geoMarker",
geometry: new Point(coors[0]),
});
that.startMarker = new Feature({
type: "start",
geometry: new Point(coors[0]),
});
that.endMarker = new Feature({
type: "end",
geometry: new Point(coors[coors.length - 1]),
});
});
},
methods: {
//获取记录列表的坐标
getDatas(callback) {
var that = this;
let token = Vue.ls.get("token");
getAction(this.url.getCoorList, null, token).then((res) => {
if (res.success) {
that.dataList = res.result;
for (let i = 1; i < res.result.length; i++) {
//获取此次路线的所有坐标点,因为是路线 根据y=ax+b 简单计算求出大约
var coor = getCoors(
res.result[i - 1].coordinates.split(",").map(Number),
res.result[i].coordinates.split(",").map(Number)
);
if (i > 0 && i < res.result.length - 1) {
//将途经点拿出
that.viaPoint.push(res.result[i].coordinates.split(","));
}
that.coors.push(...coor);
}
callback(that.coors);
}
});
},
searchPath() {
var that = this;
if (that.pointLayer == null) {
that.pointLayer = that.createRouteVector(
that.routeFeature,
that.geoMarker,
that.startMarker,
that.endMarker
);
that.map.addLayer(that.pointLayer);
//设置地图中心点
that.map.getView().setCenter(that.coors[0]);
//开始动画
that.startAnimation();
that.title = "取消观看轨迹";
} else {
//移除路线图层
that.map.removeLayer(that.pointLayer);
that.pointLayer = null;
that.title = "查看当天轨迹";
}
},
createRouteVector(routeFeature, geoMarker, startMarker, endMarker) {
var that = this;
var features = [];
var viaPoint = that.viaPoint;
//循环添加途经点feature
for (var i = 0; i < viaPoint.length; i++) {
features.push(
new Feature({
type: "viaMarker",
geometry: new Point(viaPoint[i]),
})
);
}
//添加路线
features.push(routeFeature)
//添加沿路线动画
features.push(geoMarker)
features.push(startMarker)
features.push(endMarker)
return new VectorLayer({
source: new VectorSource({
features: features,
}),
zIndex: 6,
style: function (feature) {
if (that.animating && feature.get("type") === "geoMarker") {
return null;
}
return that.styles[feature.get("type")];
},
});
},
//进行轨迹流动
moveFeature: function (event) {
var vectorContext = getVectorContext(event);
var frameState = event.frameState;
if (this.animating) {
var elapsedTime = frameState.time - this.nowTime;
var index = Math.round((this.speed * elapsedTime * 2) / 1000);
if (index >= this.coors.length) {
this.stopAnimation(true);
return;
}
var currentPoint = new Point(this.coors[index]);
var feature = new Feature(currentPoint);
vectorContext.drawFeature(feature, this.styles.geoMarker);
}
this.map.render();
},
startAnimation() {
if (this.animating) {
this.stopAnimation(false);
} else {
this.animating = true;
this.nowTime = new Date().getTime();
this.geoMarker.setStyle(null);
this.pointLayer.on("postrender", this.moveFeature);
this.map.render();
}
},
stopAnimation(ended) {
this.animating = false;
var coord = ended ? this.coors[this.coors.length - 1] : this.coors[0];
var geometry = this.geoMarker.getGeometry();
geometry.setCoordinates(coord);
this.startAnimation();
},
},
};
</script>
有朋友需要的coordinateUtil
,如下:
import {getDistance} from 'ol/sphere';
function getCoors(startCoor, endCoor) {
var xDis = endCoor[0] - startCoor[0]
var yDis = endCoor[1] - startCoor[1]
//计算x坐标的增量
var xUnitstep = xDis / 2000
var yUnitstep = yDis / 2000
var x = startCoor[0];
var y = startCoor[1];
var coorArr = []
for (var i = 0; i <= 2000; i++) {
x = x + xUnitstep
y = y + yUnitstep
coorArr.push([x, y])
}
return coorArr;
}
function getCoorsByRtio(ratio, startCoor, endCoor) {
ratio = ratio*1.60665
// ratio = Math.pow(ratio,2)/1000
console.log(ratio)
var xDis = endCoor[0] - startCoor[0]
var yDis = endCoor[1] - startCoor[1]
//计算x坐标的增量
var xUnitstep = xDis / (ratio )
var yUnitstep = yDis / (ratio )
var x = startCoor[0];
var y = startCoor[1];
var coorArr = []
for (var i = 0; i <= (ratio); i++) {
x = x + xUnitstep
y = y + yUnitstep
coorArr.push([x, y])
}
return coorArr;
}
function calculateRatio(coors) {
if (coors.length < 1) {
return;
}
//计算各个线段的距离
var distance = []; //各个线段路程的集合
for (var i = 0; i < coors.length - 1; i++) {
distance.push(Math.floor(sphereDistance(coors[i], coors[i + 1])))
}
return distance;
}
//数组去重 方法1
function uniqueBySet(arr) {
return Array.from(new Set(arr))
}
//数组去重 方法2
function uniqueByMap(arr){
let map = new Map();
let array = new Array();
for(let i =0 ; i<arr.length;i++){
if(map.has(arr[i].toString())){
map.set(arr[i].toString(),true);
}else{
map.set(arr[i].toString(),false);
array.push(arr[i])
}
}
return array;
}
//计算2个经纬度点之间的距离
function sphereDistance( coor1, coor2) {
return getDistance(coor1, coor2);
}
export {
getCoors,
calculateRatio,
getCoorsByRtio,
uniqueByMap,
uniqueBySet,
sphereDistance
}