<template>
<div id="map-box">
<div id="menu">
<label for="speed">
speed:
<input id="speed" type="range" min="1000" max="10000" step="1000" value="1000">
</label>
<button id="start-animation" @click="startAnimation">开始</button>
<button id="pause-animation" @click="pauseAnimation">暂停</button>
<button id="continue-animation" @click="continueAnimation">继续</button>
<button id="stop-animation" @click="stopAnimation">结束</button>
</div>
</div>
</template>
<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import { fromLonLat } from 'ol/proj';
import XYZ from 'ol/source/XYZ';
import { Style, Stroke, Icon } from 'ol/style'
import { LineString, Point } from 'ol/geom';
import Feature from 'ol/Feature.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import { testData } from './mockData.js'
var geoMarker;
var moveFeature;
let vectorLayer;
let routeFeature;
let startMarker;
let endMarker;
let animating;
let elapsedTime
let speed;
export default {
name: 'mapBox',
data() {
return {
map: null,
timer: null,
animating: false,
timerFlag: false,
routerIndex: 0,
pointLayer: null
}
},
methods: {
initMap() {
this.map = new Map({
layers: [
new TileLayer({
source: new XYZ({
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
}),
})
],
view: new View({
center: fromLonLat([121.061162, 30.628472]),
zoom: 18,
projection: 'EPSG:3857',
maxZoom: 18,
minZoom: 4,
}),
target: 'map-box',
});
},
initLineLayer() {
let that = this
var Coordinates = testData.map((item) => {
return fromLonLat(item)
})
var route = new LineString(Coordinates);
var routeCoords = route.getCoordinates();
console.log('routeCoords: ', routeCoords);
var routeLength = routeCoords.length;
routeFeature = new Feature({
type: 'route',
geometry: route
});
geoMarker = new Feature({
type: 'geoMarker',
geometry: new Point(routeCoords[0])
});
startMarker = new Feature({
type: 'icon',
geometry: new Point(routeCoords[0])
});
endMarker = new Feature({
type: 'icon',
geometry: new Point(routeCoords[routeLength - 1])
});
var styles = {
'route': new Style({
stroke: new Stroke({
width: 6,
color: 'transparent'
})
}),
'icon': new Style({
image: new Icon({
src: require('/public/终点.png'),
scale: 0.1,
})
}),
'geoMarker': new Style({
image: new Icon( ({
anchorOrigin: 'top-right',
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
offsetOrigin: 'top-right',
scale: 0.3,
rotateWithView: false,
rotation: -Math.atan2(routeCoords[0][1] - routeCoords[1][1], routeCoords[0][
0
] - routeCoords[1][0]),
src: require('/public/plane.png')
})),
})
};
animating = false;
vectorLayer = new VectorLayer({
source: new VectorSource({
features: [routeFeature, geoMarker, startMarker, endMarker]
}),
style: function (feature) {
if (animating && feature.get('type') === 'geoMarker') {
return null;
}
return styles[feature.get('type')];
}
})
this.map.addLayer(vectorLayer)
moveFeature = function () {
if (!vectorLayer.getVisible()) {
vectorLayer.setVisible(true)
}
elapsedTime++
that.routerIndex = Math.round(speed * elapsedTime / 1000);
console.log('elapsedTime', elapsedTime);
if (that.routerIndex >= routeLength) {
clearInterval(that.timer);
return;
}
var x, y, rotation, carStyle;
console.log('that.routerIndex: ', that.routerIndex);
if (routeCoords[that.routerIndex] && routeCoords[that.routerIndex + 1]) {
x = routeCoords[that.routerIndex][0] - routeCoords[that.routerIndex + 1][0];
y = routeCoords[that.routerIndex][1] - routeCoords[that.routerIndex + 1][1];
rotation = Math.atan2(y, x);
} else {
rotation = 0
}
carStyle = new Style({
image: new Icon({
src: require('/public/plane.png'),
rotateWithView: false,
rotation: Math.atan2(1, 0) - rotation,
scale: 0.3,
})
});
var line = new Feature({
geometry: new LineString(routeCoords.slice(0, that.routerIndex + 1))
})
var lineStyle = new Style({
stroke: new Stroke({
width: 6,
color: 'blue'
})
})
line.setStyle(lineStyle)
var line1 = new Feature({
geometry: new LineString(routeCoords.slice(that.routerIndex))
})
var lineStyle1 = new Style({
stroke: new Stroke({
width: 6,
color: 'transparent'
})
})
line1.setStyle(lineStyle1)
var currentPoint = new Point(routeCoords[that.routerIndex])
var feature = new Feature(currentPoint)
vectorLayer.getSource().clear()
feature.setStyle(carStyle)
vectorLayer.getSource().addFeature(startMarker)
vectorLayer.getSource().addFeature(endMarker)
vectorLayer.getSource().addFeature(feature)
vectorLayer.getSource().addFeature(line)
vectorLayer.getSource().addFeature(line1)
that.map.render();
};
},
startAnimation() {
this.pointLayer.getSource().clear()
animating = true
var speedInput = document.getElementById('speed')
speed = speedInput.value
console.log('speed', speed);
geoMarker.changed()
if (this.timer) {
clearInterval(this.timer)
}
this.timer = setInterval(() => {
moveFeature()
}, 1000)
elapsedTime = 0
},
stopAnimation() {
this.pointLayer.getSource().clear()
clearInterval(this.timer)
vectorLayer.getSource().clear()
vectorLayer.getSource().addFeature(routeFeature)
vectorLayer.getSource().addFeature(startMarker)
vectorLayer.getSource().addFeature(endMarker)
},
pauseAnimation() {
clearInterval(this.timer)
this.timerFlag = true
},
continueAnimation() {
if (this.timerFlag) {
this.timer = setInterval(() => {
moveFeature()
}, 60)
}
this.timerFlag = false
},
initPointLayer() {
const vectorSource = new VectorSource();
this.pointLayer = new VectorLayer({
source: vectorSource,
style: new Style({
image: new Icon({
anchor: [0.5, 1],
src: require('/public/河湖长水质监测点位点位.png'),
scale: 0.1,
}),
})
})
this.map.addLayer(this.pointLayer)
},
},
watch: {
routerIndex(val) {
console.log('val', val);
let pointFeature = new Feature({
geometry: new Point(fromLonLat(testData[this.routerIndex])),
});
this.pointLayer.getSource().addFeature(pointFeature);
}
},
mounted() {
this.initMap()
this.initPointLayer()
this.initLineLayer()
}
}
</script>
<style scoped>
#map-box {
width: 1920px;
height: 1080px;
}
</style>