说明:

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

解决方案:

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. 玩转u8g2 OLED库,一篇就够

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  2. MyBatis 示例-传递多个参数

    映射器的主要元素: 本章介绍 select 元素中传递多个参数的处理方式. 测试类:com.yjw.demo.MulParametersTest 使用 Map 传递参数(不建议使用) 使用 MyBat ...

  3. 使用JRebel插件实现SpringBoot应用代码热加载

    前言 在实际的开发过程中,我们经常修改代码之后,手动的重启项目,查看修改效果.那么有没有一种方式能够快速的.自动的帮我们将修改代码自动更新,避免手动重启,从而提高开发效率呢?是有的,在我之前的文章里面 ...

  4. 在非洲运营互联网系统-PAYGo方案

    ​ 尼日利亚当地经济.支付.网络.供电.交通等基建都比较落后,虽然各方面都在缓慢增长,但当地人对高额的刚需产品仍望而却步. 其他非洲国家也有同样的问题. 同理国内,一些低收入人群都想买房,但房价动辄几 ...

  5. 爬虫连接mongodb、多线程多进程的使用

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

  6. fenby C语言 P30

    int a[5],*p=a; int a[5],*p=&a[0]; #include <stdio.h> int main(void){ int a[5],*p=a,i; for( ...

  7. [springboot 开发单体web shop] 3. 用户注册实现

    目录 用户注册 ## 创建数据库 ## 生成UserMapper ## 编写业务逻辑 ## 编写user service UserServiceImpl#findUserByUserName 说明 U ...

  8. scrapy爬取京东iPhone11评论(一)

    咨询行业中经常接触到文本类信息,无论是分词做词云图,还是整理编码分析用,都非常具有价值. 本文将记录使用scrapy框架爬取京东IPhone11评论的过程,由于一边学习一边实践,更新稍慢请见谅. 1. ...

  9. Java IO编程——转换流

    所谓的转换流指的是可以实现字节流与字符流操作的功能转换,例如:进行输出的时候OutputStream需要将内容变为字节数组后才可以进行输出,而Writer可以直接输出字符串,这一点是方便的,所以很多人 ...

  10. python之带有参数的装饰器

    一个小demo def set_level(level_num): def set_func(func): def call_func(*args, **kwargs): if level_num = ...