说明:

我的需求是需要实现轨迹播放/暂停/重新播放/从点击处播放,因此封装了一个类

解决方案:

1、初始化:主要是处理一下图层以及数据,通过插值构造一个全局数组

    /**
* @description 初始化轨迹
*/
(function init() {
//地图容器
that._map = _map;
//轨迹线图层
that._animationLineLayer = animationLineLayer;
//轨迹点图层
that._animationPointLayer = animationPointLayer;
//轨迹样式
that._strokestyle = strokestyle;
//轨迹样式
that._Iconstyle = Iconstyle;
//轨迹点集(带插值)
that._pointArray = [];
//轨迹点集(不带插值)
that._linePatrolArray = linePatrolArray; //设置图层id
animationLineLayer.set('layerId', 'animationLineLayer');
animationPointLayer.set('layerId', 'animationPointLayer');
//没有传坐标点过来就返回
if (linePatrolArray.length == 0) return;
//如果连续定时器没有清空,则清空定时器
clearInterval(this.timer);
//移除路径图层
if (_map.findLayerByID("animationLineLayer") != null) {
_map.encmap.removeLayer(_map.findLayerByID("animationLineLayer"));
}
//移除动画点的图层
if (_map.findLayerByID("animationPointLayer") != null) {
_map.encmap.removeLayer(_map.findLayerByID("animationPointLayer"));
} //记录插值后的所有轨迹点,给pointArray
for (var i = 0; i < linePatrolArray.length - 1; i++) {
interpolation(linePatrolArray[i], linePatrolArray[i + 1]);
} var curentLineLayer = _map.findLayerByID("animationLineLayer");
var curentPointLayer = _map.findLayerByID("animationPointLayer"); //如果此时map对象中有路径animationLineLayer图层
if (curentLineLayer != null) {
//如果此时路径animationLineLayer图层没有清空,清空里面的内容
if (curentLineLayer.getSource() != null) {
curentLineLayer.getSource().clear();
}
} else {
//如果此时map对象中没有路径图层,添加路径animationLineLayer图层
_map.encmap.addLayer(animationLineLayer);
}
//如果此时map对象中有移动动画点animationPointLayer图层
if (curentPointLayer != null) {
if (curentPointLayer.getSource() != null) {
//清空动画点animationPointLayer图层的内容
curentPointLayer.getSource().clear();
}
} else {
//如果此时map对象中没有移动点图层,添加移动点animationPointLayer图层
_map.encmap.addLayer(animationPointLayer);
} //注册点击查询事件,点击暂停/从此播放
let selecthover = new ol.interaction.Select({
condition: ol.events.condition.click,
layers: [animationLineLayer]
});
selecthover.set("arrPoints", that._pointArray);
// selecthover.set("tmpPoints", that._pointArray);
selecthover.set("_strokestyle", that._strokestyle);
selecthover.set("_Iconstyle", that._Iconstyle);
selecthover.set("_animationLineLayer", that._animationLineLayer);
selecthover.set("_animationPointLayer", that._animationPointLayer);
_map.encmap.addInteraction(selecthover);
var me = that;
//查询结果
selecthover.on("select", function (evt) {
if (evt.selected[0] == null) return;
//取消选中要素高亮
this.getFeatures().clear();
//暂停/继续
//isRun = !isRun;
// console.log(replayIndex); //从点击处开始播放
isRun = true;
replayIndex = evt.selected[0].get("arrIndex"); var tmpPointsArray = this.getProperties()["arrPoints"];
var tmpPoints = this.getProperties()["tmpPoints"];
var _strokestyle = this.getProperties()["_strokestyle"];
var _Iconstyle = this.getProperties()["_Iconstyle"];
var _animationLineLayer = this.getProperties()["_animationLineLayer"];
var _animationPointLayer = this.getProperties()["_animationPointLayer"]; //保留走完的线
_animationLineLayer.getSource().clear();
// tmpPointsArray.filter(e => e <= replayIndex);
var pts = [];
pts.push(tmpPointsArray);
pts = pts[0]; for (var m = 0; m <= replayIndex - 1; m++) {
//创建轨迹线
var line = new ol.Feature({
geometry: new ol.geom.LineString([pts[m], pts[m + 1]])
});
line.set("arrIndex", m);
// //设置线的样式
line.setStyle(_strokestyle);
_animationLineLayer.getSource().addFeature(line);
} //添加点击点
var clickPt = new ol.Feature({
geometry: new ol.geom.Point(tmpPointsArray[replayIndex])
});
clickPt.setStyle(_Iconstyle);
_animationPointLayer.getSource().clear();
_animationPointLayer.getSource().addFeature(clickPt);
});
})();

2、播放方法:首先跳转到轨迹范围;新建一个timer定时器,并控制播放完所有轨迹点后清除定时器;用lineString函数传入首尾坐标,完成绘线。

    //动画播放
this.play = function (_speed) {
//var me = this;
//定位到轨迹范围
var featureExtent = new ol.Feature({
geometry: new ol.geom.LineString(that._linePatrolArray)
});
that._map.encmap.getView().fit(featureExtent.getGeometry().getExtent()); //如果连续定时器没有清空,则清空定时器
if (this.timer != null) {
clearInterval(this.timer);
if (that._animationLineLayer.getSource() != null) {
that._animationLineLayer.getSource().clear();
}
if (that._animationPointLayer.getSource() != null) {
that._animationPointLayer.getSource().clear();
}
} //播放速度
that.speed = _speed;
//计时器默认40ms
if (!that.speed) {
that.speed = 40;
}
replayIndex = 0;
this.timer = setInterval(function () {
console.log(that.timer);
//暂停
if (!isRun) {
return;
}
//播放完成,停止定时器
if (replayIndex > that._pointArray.length - 2) {
clearInterval(that.timer);
return;
}
//创建轨迹线
var line = new ol.Feature({
geometry: new ol.geom.LineString([that._pointArray[replayIndex], that._pointArray[++replayIndex]])
});
line.set("arrIndex", replayIndex);
//设置线的样式
line.setStyle(that._strokestyle);
that._animationLineLayer.getSource().addFeature(line); //创建轨迹点
var point = new ol.Feature({
geometry: new ol.geom.Point(that._pointArray[replayIndex])
});
point.setStyle(that._Iconstyle);
that._animationPointLayer.getSource().clear();
that._animationPointLayer.getSource().addFeature(point);
}, that.speed);
}

3、暂停/播放:这里设置了一个变量isRun控制,如果false则timer里直接返回,不执行绘制

    /**
* 暂停/继续播放
* @param {Boolean} isRun 返回暂停还是播放
*/
this.paused = function () {
//如果没有定时器,则不暂停
if (this.timer) {
isRun = !isRun;
return isRun;
}
else {
return null;
}
};

4、重新播放:清空上一个计时器,重新播放

/**
* 重新播放
*/
this.restart = function () {
clearInterval(this.timer);
isRun = true;
// this._animationLineLayer.getSource().clear();
// this._animationPointLayer.getSource().clear();
this.play(that.speed); }

5、点击处重新播放:这个select事件放在初始化时注册完成的;使用了数组filter方法过滤数组,并控制全局游标replayIndex;找到播放到的数组元素,从那里开始

        //注册点击查询事件,点击暂停/从此播放
let selecthover = new ol.interaction.Select({
condition: ol.events.condition.click,
layers: [animationLineLayer]
});
selecthover.set("arrPoints", that._pointArray);
// selecthover.set("tmpPoints", that._pointArray);
selecthover.set("_strokestyle", that._strokestyle);
selecthover.set("_Iconstyle", that._Iconstyle);
selecthover.set("_animationLineLayer", that._animationLineLayer);
selecthover.set("_animationPointLayer", that._animationPointLayer);
_map.encmap.addInteraction(selecthover);
var me = that;
//查询结果
selecthover.on("select", function (evt) {
if (evt.selected[0] == null) return;
//取消选中要素高亮
this.getFeatures().clear();
//暂停/继续
//isRun = !isRun;
// console.log(replayIndex); //从点击处开始播放
isRun = true;
replayIndex = evt.selected[0].get("arrIndex"); var tmpPointsArray = this.getProperties()["arrPoints"];
var tmpPoints = this.getProperties()["tmpPoints"];
var _strokestyle = this.getProperties()["_strokestyle"];
var _Iconstyle = this.getProperties()["_Iconstyle"];
var _animationLineLayer = this.getProperties()["_animationLineLayer"];
var _animationPointLayer = this.getProperties()["_animationPointLayer"]; //保留走完的线
_animationLineLayer.getSource().clear();
// tmpPointsArray.filter(e => e <= replayIndex);
var pts = [];
pts.push(tmpPointsArray);
pts = pts[0]; for (var m = 0; m <= replayIndex - 1; m++) {
//创建轨迹线
var line = new ol.Feature({
geometry: new ol.geom.LineString([pts[m], pts[m + 1]])
});
line.set("arrIndex", m);
// //设置线的样式
line.setStyle(_strokestyle);
_animationLineLayer.getSource().addFeature(line);
} //添加点击点
var clickPt = new ol.Feature({
geometry: new ol.geom.Point(tmpPointsArray[replayIndex])
});
clickPt.setStyle(_Iconstyle);
_animationPointLayer.getSource().clear();
_animationPointLayer.getSource().addFeature(clickPt);
});

6、提速/减速:这里控制计时器的速度,其实还有另一种做法就是控制插值的密度。

    /**
* 提速
*/
this.faster = function () {
clearInterval(this.timer);
isRun = true;
//如果速度小于10,则不允许再提速
if (that.speed > 10) {
that.speed = that.speed - 1;
}
this.play(that.speed);
return that.speed;
}; /**
* 减速
*/
this.slower = function () {
clearInterval(this.timer);
isRun = true;
that.speed = that.speed + 1;
this.play(that.speed);
return that.speed;
};

7、最后附上全部代码(需要改造才能使用,因为这里map以及findlayerbyid都是封装好的方法)

RoadLineShow = function (_map, animationLineLayer, animationPointLayer, linePatrolArray, strokestyle, Iconstyle) {
var that = this;
var timer = this.timer;//连续定时器
var speed = this.speed;//定时器速度
var ref;//断续定时器
var j = 0;
//播放与暂停标识
var isRun = true;
/**
* @description 初始化轨迹
*/
(function init() {
//地图容器
that._map = _map;
//轨迹线图层
that._animationLineLayer = animationLineLayer;
//轨迹点图层
that._animationPointLayer = animationPointLayer;
//轨迹样式
that._strokestyle = strokestyle;
//轨迹样式
that._Iconstyle = Iconstyle;
//轨迹点集(带插值)
that._pointArray = [];
//轨迹点集(不带插值)
that._linePatrolArray = linePatrolArray; //设置图层id
animationLineLayer.set('layerId', 'animationLineLayer');
animationPointLayer.set('layerId', 'animationPointLayer');
//没有传坐标点过来就返回
if (linePatrolArray.length == 0) return;
//如果连续定时器没有清空,则清空定时器
clearInterval(this.timer);
//移除路径图层
if (_map.findLayerByID("animationLineLayer") != null) {
_map.encmap.removeLayer(_map.findLayerByID("animationLineLayer"));
}
//移除动画点的图层
if (_map.findLayerByID("animationPointLayer") != null) {
_map.encmap.removeLayer(_map.findLayerByID("animationPointLayer"));
} //记录插值后的所有轨迹点,给pointArray
for (var i = 0; i < linePatrolArray.length - 1; i++) {
interpolation(linePatrolArray[i], linePatrolArray[i + 1]);
} var curentLineLayer = _map.findLayerByID("animationLineLayer");
var curentPointLayer = _map.findLayerByID("animationPointLayer"); //如果此时map对象中有路径animationLineLayer图层
if (curentLineLayer != null) {
//如果此时路径animationLineLayer图层没有清空,清空里面的内容
if (curentLineLayer.getSource() != null) {
curentLineLayer.getSource().clear();
}
} else {
//如果此时map对象中没有路径图层,添加路径animationLineLayer图层
_map.encmap.addLayer(animationLineLayer);
}
//如果此时map对象中有移动动画点animationPointLayer图层
if (curentPointLayer != null) {
if (curentPointLayer.getSource() != null) {
//清空动画点animationPointLayer图层的内容
curentPointLayer.getSource().clear();
}
} else {
//如果此时map对象中没有移动点图层,添加移动点animationPointLayer图层
_map.encmap.addLayer(animationPointLayer);
} //注册点击查询事件,点击暂停/从此播放
let selecthover = new ol.interaction.Select({
condition: ol.events.condition.click,
layers: [animationLineLayer]
});
selecthover.set("arrPoints", that._pointArray);
// selecthover.set("tmpPoints", that._pointArray);
selecthover.set("_strokestyle", that._strokestyle);
selecthover.set("_Iconstyle", that._Iconstyle);
selecthover.set("_animationLineLayer", that._animationLineLayer);
selecthover.set("_animationPointLayer", that._animationPointLayer);
_map.encmap.addInteraction(selecthover);
var me = that;
//查询结果
selecthover.on("select", function (evt) {
if (evt.selected[0] == null) return;
//取消选中要素高亮
this.getFeatures().clear();
//暂停/继续
//isRun = !isRun;
// console.log(replayIndex); //从点击处开始播放
isRun = true;
replayIndex = evt.selected[0].get("arrIndex"); var tmpPointsArray = this.getProperties()["arrPoints"];
var tmpPoints = this.getProperties()["tmpPoints"];
var _strokestyle = this.getProperties()["_strokestyle"];
var _Iconstyle = this.getProperties()["_Iconstyle"];
var _animationLineLayer = this.getProperties()["_animationLineLayer"];
var _animationPointLayer = this.getProperties()["_animationPointLayer"]; //保留走完的线
_animationLineLayer.getSource().clear();
// tmpPointsArray.filter(e => e <= replayIndex);
var pts = [];
pts.push(tmpPointsArray);
pts = pts[0]; for (var m = 0; m <= replayIndex - 1; m++) {
//创建轨迹线
var line = new ol.Feature({
geometry: new ol.geom.LineString([pts[m], pts[m + 1]])
});
line.set("arrIndex", m);
// //设置线的样式
line.setStyle(_strokestyle);
_animationLineLayer.getSource().addFeature(line);
} //添加点击点
var clickPt = new ol.Feature({
geometry: new ol.geom.Point(tmpPointsArray[replayIndex])
});
clickPt.setStyle(_Iconstyle);
_animationPointLayer.getSource().clear();
_animationPointLayer.getSource().addFeature(clickPt);
});
})(); /**
* 提供坐标数组,展示轨迹
* @param _map 实例化map对象
* @param Coordinates 坐标数组例如[123458.421,123432]
* @param lineStyle 轨迹的式样
* @returns {ol.layer.Vector} 返回一个layer实例
*/
this.getRoadLineLayer = function (_map, Coordinates, lineStyle) {
var route = new ol.geom.LineString(Coordinates);
//获取直线的坐标
var Featureroute = new ol.Feature({
type: 'route',
geometry: route
});
var routeFeature = [Featureroute];
var routeSource = new ol.source.Vector(
{
features: routeFeature
}
);
var vectorLayer = new ol.layer.Vector({
source: routeSource,
style: lineStyle
});
var myFeatureExtent = vectorLayer.getSource().getExtent();
if (myFeatureExtent != null) {
let view = _map.encmap.getView();
//改变视图view
view.fit(myFeatureExtent);
}
return vectorLayer;
}; //动画播放
this.play = function (_speed) {
//var me = this;
//定位到轨迹范围
var featureExtent = new ol.Feature({
geometry: new ol.geom.LineString(that._linePatrolArray)
});
that._map.encmap.getView().fit(featureExtent.getGeometry().getExtent()); //如果连续定时器没有清空,则清空定时器
if (this.timer != null) {
clearInterval(this.timer);
if (that._animationLineLayer.getSource() != null) {
that._animationLineLayer.getSource().clear();
}
if (that._animationPointLayer.getSource() != null) {
that._animationPointLayer.getSource().clear();
}
} //播放速度
that.speed = _speed;
//计时器默认40ms
if (!that.speed) {
that.speed = 40;
}
replayIndex = 0;
this.timer = setInterval(function () {
console.log(that.timer);
//暂停
if (!isRun) {
return;
}
//播放完成,停止定时器
if (replayIndex > that._pointArray.length - 2) {
clearInterval(that.timer);
return;
}
//创建轨迹线
var line = new ol.Feature({
geometry: new ol.geom.LineString([that._pointArray[replayIndex], that._pointArray[++replayIndex]])
});
line.set("arrIndex", replayIndex);
//设置线的样式
line.setStyle(that._strokestyle);
that._animationLineLayer.getSource().addFeature(line); //创建轨迹点
var point = new ol.Feature({
geometry: new ol.geom.Point(that._pointArray[replayIndex])
});
point.setStyle(that._Iconstyle);
that._animationPointLayer.getSource().clear();
that._animationPointLayer.getSource().addFeature(point);
}, that.speed);
}
/**
* 重新播放
*/
this.restart = function () {
clearInterval(this.timer);
isRun = true;
// this._animationLineLayer.getSource().clear();
// this._animationPointLayer.getSource().clear();
this.play(that.speed);
} /**
* 暂停/继续播放
* @param {Boolean} isRun 返回暂停还是播放
*/
this.paused = function () {
//如果没有定时器,则不暂停
if (this.timer) {
isRun = !isRun;
return isRun;
}
else {
return null;
}
}; /**
* 提速
*/
this.faster = function () {
clearInterval(this.timer);
isRun = true;
//如果速度小于10,则不允许再提速
if (that.speed > 10) {
that.speed = that.speed - 1;
}
this.play(that.speed);
return that.speed;
}; /**
* 减速
*/
this.slower = function () {
clearInterval(this.timer);
isRun = true;
that.speed = that.speed + 1;
this.play(that.speed);
return that.speed;
}; //插入临时点,每两个点之间插入39个点
function interpolation(pointA, pointB, speed) {
var tmp = [];
if (speed == undefined) {
speed = 1;
}
speed = speed - 0.5; //不能大于播放速度
var count = Math.abs(speed) * 25;
var pointA_X = pointA[0];
var pointA_Y = pointA[1];
var pointB_X = pointB[0];
var pointB_Y = pointB[1];
var disX = (pointB_X - pointA_X) / count;
var disY = (pointB_Y - pointA_Y) / count;
var i = 0;
var x_y_point = [];
while (i <= count) {
var x = pointA_X + i * disX;
var y = pointA_Y + i * disY;
that._pointArray.push([x, y]);
i++;
}
}
};

Openlayers 实现轨迹播放/暂停/重新播放/从点击处播放/提速/减速的更多相关文章

  1. Cocos2d-x中背景音乐播放暂停与继续

    背景音乐播放暂停与继续似乎我们很少使用,事实上也正是如此,背景音乐播放暂停与继续实例代码如下: SimpleAudioEngine::getInstance()->pauseBackground ...

  2. 31.JS实现控制HTML5背景音乐播放暂停

    实现控制网站背景音乐的播放暂停在html5中是非常容易和简单的,仅仅几行代码即可实现.首先在网页中嵌入背景音乐,html5代码为: <script src="http://wuover ...

  3. JavaScript多个h5播放器video,点击一个播放其他暂停

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. js-音乐播放器,播放|暂停|滑块的功能

    音乐播放器,播放|暂停|滑块的功能 document.addEventListener('DOMContentLoaded', function loaded(event) { var audio = ...

  5. HTML5-video(播放暂停视频;打开关闭声音;进度条)

    <!DOCTYPE html> <html> <head> <title>HTML5-video(播放暂停视频:打开关闭声音:进度条)</titl ...

  6. Lily_music 网页音乐播放器 -可搜索(附歌词联动播放效果解说)

    博客地址:https://ainyi.com/59 写在前面 这是我今年(2018)年初的小项目,当时也是手贱,不想用别的播放器,想着做一个自己的网页播放器,有个歌曲列表.可关键词搜索.歌词滚动播放的 ...

  7. javascript JSMpeg.js 播放视频解决不用全屏也能播放(也支持自动播放哦)

    javascript JSMpeg.js 播放视频解决不用全屏也能播放(也支持自动播放哦) 缺陷就是 因为采用的是 MPEG1解码器 所以清晰度有点低 做直播可以考虑下 如果要清晰度高点 可以采取序列 ...

  8. HTML5播放暂停音乐

    查看效果:http://hovertree.com/code/jquery/ueyf7gn4.htm 代码如下: <!DOCTYPE html> <html> <head ...

  9. 使用jQuery播放/暂停 HTML5视频

    文章来自:http://blog.okbase.net/jquery2000/archive/4485.html 我尝试用jQuery控制HTML5视频,两个视频分别在两个tab中,我希望点中tab后 ...

随机推荐

  1. 【Java必修课】四类方法删除List里面的所有null值

    1 简介 万恶的null已经折磨程序员许久了,也带来了许多难以发现却造成严重损失的NullPointerException.我们需要尽可能的避免它,有一种简单的办法就是在它进入下轮处理前,我们就把它扼 ...

  2. Dubbo配置完全外部化实践,使用动态配置中心的注意事项

    问题描述 近期开发项目,将Dubbo的配置全部外部化到动态配置中心.这里配置中心我使用的是Apollo. @Configuration public class DubboConfig { @Bean ...

  3. day20作业

    1.下面这段代码的输出结果将是什么?请解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): ...

  4. django-URL重定向(八)

    HttpResponseRedirect()不常用 redirect(to,permanent=False,*args,**kwargs) to:指重定向的位置,可以是视图,也可以是url地址,也可以 ...

  5. 爬虫链接mongodb 以及多线程多进程的操作

    一.连接mongodb 1.            设置数据库 client=pymongo.MongoClient(‘localhost’) 2.            db=client[‘lag ...

  6. CSAPP:代码优化【矩阵读写】

    转载请注明出处:https://www.cnblogs.com/ustca/p/11790314.html 写程序最主要的目标就是使它在所有可能的情况下都正确工作,另一方面,在很多情况下,让程序运行得 ...

  7. mybatis代理机制讲解

    问题描述 在使用Mybatis开发中,或者和Spring整合中,在Dao层中的Mapper接口与xml中的sql对应着,在service中直接调用Dao中的方法就可以直接访问sql.如下所示: /** ...

  8. 作为一名程序员,你真正了解CDN技术吗?

    本文导读: 物流仓库配送如何加速 静态资源文件部署方式 静态资源加速之CDN技术 解析过程中的名词解释 最后的总结 1.物流仓库配送如何加速 我们还是从生活中购物的例子来展开. 将时光倒回到几年前,在 ...

  9. Azure上MySQL的离线备份:将备份拷贝到Azure Blob上

    公司在Azure的Iaas虚拟机上部署有好几台MySQL数据库,至于没有选择Azure Database for MySQL,是因为预算有限(钱不够啊!说多了也是泪,坑的还是DBA自己).选择了Iaa ...

  10. 文件I/O——文件打开函数(open/openat)

    一.open函数 1.函数原型:int open(const char *path,int oflag,.../* mode_t mode */); 2.头文件:#include <fcntl. ...