openlayers之轨迹回放
程序员文章站
2022-07-05 12:55:16
...
效果图
老规矩,直接上代码,已经把该备注的都备注好了(可直接复制查看)
<div id="map"></div>
<label for="speed">
speed:
<input id="speed" type="range" min="10" max="999" step="10" value="60">
</label>
<button id="start-animation">Start Animation</button>
<script>
var center = [-5639523.95, -3501274.52];
var map = new ol.Map({
target: document.getElementById('map'),
view: new ol.View({
center: center,
zoom: 10 ,
minZoom: 2,
maxZoom: 18,
}),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(), //底图
}) ],
});
//polyline 从官网拿到的json数据,最后转为[[],[],[]...]
var polyline = '[email protected]`[email protected]}@[email protected]??aC^[email protected][email protected]@b[wFdE??wFfE}NfIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^aMyBiHOkFNoI`CcVvM??gG^[email protected]??eCcA]OoL}[email protected][email protected]\\[email protected]@{vA}[email protected]}{@iRaqE{[email protected]_T{][email protected]{PmhEwaA{[email protected]]wQeEgtAsZ}LiCarAkVwI}D??_}[email protected]@[email protected]@gV}TiYs[uTwXoNmT{[email protected]]{[email protected][email protected]_G}YsFw][email protected][email protected][email protected]|@[email protected][email protected]@[email protected]@[email protected]@{[email protected]@[email protected]@[email protected]@[email protected]@{[email protected]}[email protected]@[email protected]~C{[email protected]@[email protected]{[email protected]_~QHeU`IuyDrC_}@[email protected]?qMbD}{AIkeAgBk_A_A{[email protected]@qH{[email protected]@qH{`@[email protected]@kL{[email protected]@ymBgwE}[email protected][email protected]@[email protected][email protected]}|[email protected]^eaC}L{dAaJ_aAiOyjByH{nAuYu`[email protected]{[email protected]}@[email protected]`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrXitAhT}[email protected]}[email protected][email protected]}A~JovAxCqW~WanB`XewBbK{_A`K}[email protected]}}@[email protected][email protected]@cDs[[email protected][email protected]@eZcDwjBoGw`BoMegBaU_`[email protected][email protected][email protected]@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o~CfIewG|[email protected]}RorAoVajA_nAodD{[y`[email protected]@[email protected]{[email protected]|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`[email protected]}[email protected][email protected]_lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\[email protected]_wAyTwpBmPc|BwZknFoFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}[email protected][email protected]`EuiBudIabB{hF{[email protected]`[email protected]~BkoAi}[email protected]@}`@oaXi_C}[email protected]|[email protected]]kgPcaAu}[email protected]\\[email protected]@siO{[ol\\kCmjMe\\[email protected]}EqiBaCg}@[email protected][email protected]`[email protected]{[email protected]{[email protected]_yCu\\wyCwyA{[email protected]}rO{{[email protected]_bAumFo}[email protected]~AkzDlhA}xEvcBa}[email protected]@`rAo|@~bBq{@``[email protected]@[email protected]@nfC_eC|[email protected]}@``Fi~FpnAooC|[email protected]}[email protected]}[email protected]@woBhR{gCwGkgCc[[email protected][[email protected]@[email protected]@[email protected]@`[email protected]@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@[email protected]{AkB{[email protected]_bYmC}[email protected]@[email protected]{X_{[email protected]{[email protected]@[email protected][email protected]@XcQ|@oNdCoSfFwXhEmOnLi\\lbAulB`[email protected]|[email protected]@[email protected]@bqC}{BhwDgcD`[email protected]@??bL{G|[email protected]@oS~][email protected]|[email protected]}Jv}[email protected]{[email protected]_]`|[email protected]@wSb{@[email protected]`RooQ~e[upZbuIolI|[email protected]@nMmJ|OeJn^{[email protected]@[email protected]@kAp~BkBxO{@|QsAfYgEtYiGd]}[email protected]`[email protected]@vgK}cJnSoSzQkVvUm^[email protected]`[email protected]\\[email protected]~kDyq[[email protected]@[email protected]@[email protected]@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB_}D~NgY`\\[email protected][[email protected]{Cw`G`[email protected]{AdjAwzBh{C}`[email protected]@}[email protected]{[email protected][email protected]`CuOlC}YnAcV`@_^[email protected]}@[email protected]^uCkZiGk\\yGeY}[email protected][uWi[[email protected]@[email protected]@asAcyAklA}qAwHkGi{@[email protected]_{B}IsJuEeFymAssAkdAmhAyTcVkFeEoKiH}[email protected]@[email protected]@[email protected]@[email protected]@}EsFmG}Jk^[email protected][email protected][email protected]@[email protected]@[email protected]@??kF}D??OL'
var route = new ol.format.Polyline({
factor: 1e6,
}).readGeometry(polyline, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857',
});
var routeLength = route.A.length;
var routeCoords = []
var routeCoordsX = []
var routeCoordsY = []
for(var i=0;i<route.A.length;i++) {
if(i%2 ==0){
routeCoordsX.push(route.A[i])
}else{
routeCoordsY.push(route.A[i])
}
}
// 将[1,2,3,4,5,6...]转为[[1,2],[3,4],[5,6]...]
for(var i=0;i<routeCoordsX.length;i++) {
routeCoords.push([routeCoordsX[i],routeCoordsY[i]])
}
// 矢量元素要呈现的几何图形的特征属性LineString代表线段
var routes = new ol.geom.LineString(routeCoords);
var routeLength = routeCoords.length;
// var routeCoords =[
// [120.97202539443971,29.149083495140076],
// [121.27202539443971,29.149083495140076],
// [121.99202539443971,29.149083495140076],
// [122.27202539443971,29.149083495140076],
// [123.27202539443971,29.149083495140076],
// [123.97202539443971,29.149083495140076],
// [125.0260719060898,30.149083495140076],
// [129.0260719060898,29.115327894687653]
// ]
// var route = new ol.geom.LineString(routeCoords);
// 定义矢量元素
var routeFeature = new ol.Feature({
type: 'route',
geometry: routes,
});
var geoMarker = new ol.Feature({
type: 'geoMarker',
geometry: new ol.geom.Point(routeCoords[0]),
});
var startMarker = new ol.Feature({
type: 'iconStart',
geometry: new ol.geom.Point(routeCoords[0]),
});
var endMarker = new ol.Feature({
type: 'iconEnd',
geometry: new ol.geom.Point(routeCoords[routeLength - 1]),
});
// 设置矢量元素样式
var styles = {
'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,
color: [237, 212, 0, 0.8],
}),
}),
'iconStart': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
src: './startSend.png',
}),
}),
'iconEnd': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
src: './endAll.png',
}),
}),
'geoMarker': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5], //图标中心
src: './plane.png',
scale: 0.6,
rotation:-Math.atan2(routeCoords[0][1]-routeCoords[1][1], routeCoords[0][0]-routeCoords[1][0]),
rotateWithView:true
}),
}),
};
// 是否处于动画状态
var animating = false;
// 定义的是图层类型Vector代表矢量图层源
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature, geoMarker, startMarker, endMarker],
}),
style: function (feature) {
console.log(feature.get('type'))
if (animating && feature.get('type') === 'geoMarker') {
return null;
}
return styles[feature.get('type')];
},
});
map.addLayer(vectorLayer);
var speed, startTime;
var speedInput = document.getElementById('speed');
var startButton = document.getElementById('start-animation');
// 动画方法
function moveFeature(event) {
// console.log(event)
var vectorContext = event.vectorContext
// var vectorContext = getVectorContext(event);
var frameState = event.frameState;
var carStyle,rotation;
// 开始动画
if (animating) {
var elapsedTime = frameState.time - startTime;
var index = Math.round(speed * elapsedTime/1000); //已经走了多少个点
// 点走完停止动画
if (index >= routeCoords.length) {
stopAnimation(true);
return;
}
if(routeCoords[index] && routeCoords[index+1]){
// console.log(route.A[index],route.A[index+1])
x=routeCoords[index][0]-routeCoords[index+1][0];
y=routeCoords[index][1]-routeCoords[index+1][1];
// 返回从原点(0,0)到(x,y)点的线段与x轴正方向之间的弧度值
rotation = Math.atan2(y,x);
console.log(rotation)
// 设置动画时的图标
carStyle= new ol.style.Style({
image: new ol.style.Icon({
src: './plane.png',
rotateWithView: false,
rotation: (-rotation+(Math.atan2(routeCoords[0][1]-routeCoords[1][1], routeCoords[0][0]-routeCoords[1][0])/2)),
scale:0.6,
anchor: [0.5, 0.5], //图标中心
})
});
// 矢量元素要呈现的几何图形的特征属性Point代表点
var currentPoint = new ol.geom.Point(routeCoords[index]);
// 添加矢量元素
var feature = new ol.Feature(currentPoint);
// 将特征渲染到画布中(功能,样式)
vectorContext.drawFeature(feature, carStyle);
}
}
map.render();
}
function startAnimation() {
// console.log(animating)
if (animating) {
stopAnimation(false);
} else {
animating = true;
startTime = new Date().getTime();
speed = speedInput.value;
startButton.textContent = 'Cancel Animation';
// 隐藏geoMarker
geoMarker.changed();
// just in case you pan somewhere else
map.getView().setCenter(center);
// 添加事件,地图渲染时触发
map.on('postcompose', moveFeature);
map.render();
}
}
function stopAnimation(ended) {
animating = false;
startButton.textContent = 'Start Animation';
// if animation cancelled set the marker at the beginning
var coord = route.getCoordinateAt(ended ? 1 : 0);
geoMarker.getGeometry().setCoordinates(coord);
// remove listener
map.un('postcompose', moveFeature);
}
startButton.addEventListener('click', startAnimation, false);
</script>
上一篇: redis连接池对象-工具
下一篇: Oracle共享池