最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

OpenLayer怎么实现小车按路径运动

来源:动视网 责编:小OO 时间:2020-11-27 19:26:32
文档

OpenLayer怎么实现小车按路径运动

客户需要的功能就是能在一张Gis图上实现小车根据路径进行移动,为什么一定要Gis呢(这是客户指定需求,无语一该)。并且客户还说底图要很容易更换,但他想要用Gis表现的却是室内的地理信息,我也没办法用baidu.高德等现成的Gis接口。针对上述需求,我没有去了解过多的web gis框架。因为客户对Gis的概念就是能放大,缩小,可以做路径规划等。所以我就选择ol,利用他的静态图片(选择这个是为满足客户灵活更新底图的需求)做Gis底图的功能来解决此问题。相关教程:js视频教程二、效果展示。三、伪代码实现。由于是技术验证代码,有些杂乱,现只给出关键性代码。如有业务需要欢迎共同讨论。3.1 实现路径的绘制。
推荐度:
导读客户需要的功能就是能在一张Gis图上实现小车根据路径进行移动,为什么一定要Gis呢(这是客户指定需求,无语一该)。并且客户还说底图要很容易更换,但他想要用Gis表现的却是室内的地理信息,我也没办法用baidu.高德等现成的Gis接口。针对上述需求,我没有去了解过多的web gis框架。因为客户对Gis的概念就是能放大,缩小,可以做路径规划等。所以我就选择ol,利用他的静态图片(选择这个是为满足客户灵活更新底图的需求)做Gis底图的功能来解决此问题。相关教程:js视频教程二、效果展示。三、伪代码实现。由于是技术验证代码,有些杂乱,现只给出关键性代码。如有业务需要欢迎共同讨论。3.1 实现路径的绘制。
 本篇文章主要讲述的是在openlayer上实现路径运动,下面和小编一起去看看具体都是如何实现的吧,感兴趣的朋友可以看看。

一、需求分析

客户需要的功能就是能在一张Gis图上实现小车根据路径进行移动,为什么一定要Gis呢(这是客户指定需求,无语一该)。并且客户还说底图要很容易更换,但他想要用Gis表现的却是室内的地理信息,我也没办法用baidu, 高德等现成的Gis接口。

针对上述需求,我没有去了解过多的web gis框架。因为客户对Gis的概念就是能放大,缩小,可以做路径规划等。所以我就选择ol,利用他的静态图片(选择这个是为满足客户灵活更新底图的需求)做Gis底图的功能来解决此问题。

相关教程:js视频教程

二、效果展示

三、伪代码实现

由于是技术验证代码, 有些杂乱,现只给出关键性代码。如有业务需要欢迎共同讨论。

3.1 实现路径的绘制

此步骤还是相对简单的,主要用到Ol的Draw对象,代码哪下:

draw(type){
 this.stopdraw();
 this._draw = new Draw({
 source: this.layer.getSource(),
 type: type == 'Icon' ? 'Point' : type
 });
 this._draw.on('drawend', (event)=>{
 if(type == 'LineString'){
 this.traceLine = event.feature;
 }
 if(type != 'Icon') return;
 let f = event.feature;
 f.setStyle(new Style({
 image: new Icon({
 src: '/content/battery.gif'
 }),
 text: new Text({
 text: 'new item',
 fill: new Fill({
 color: "red"
 })
 })
 }));
 f.type = 'battery';
 });
 this.map.addInteraction(this._draw);
 this._snap = new Snap({source: this.layer.getSource()});
 this.map.addInteraction(this._snap);
 }

关键代码在于drawend事件的监听,如果是LineString情况,就将此feature放在一个共公变量,方便路径运行时使用。

3.2 分解路径数据

此部分就是获取到3.1步骤的路径路径,然后进行解析,因为3.1上的linestring是多个线段的集合,但运动其本质就是改变图标的坐标,使其快速且连续的变化就形成了移动效果。所以这里有一个方法进行路径细分,代码如下:

cutTrace(){
 let traceCroods = this.traceLine.getGeometry().getCoordinates(); 
 let len = traceCroods.length;
 let destCroods = [];
 for(let i = 0; i < len - 1; ++i){
 let bPoint = traceCroods[i];
 let ePoint = traceCroods[i+1];
 let bevelling = Math.sqrt(Math.pow(ePoint[0] - bPoint[0], 2)
 + Math.pow(ePoint[1] - bPoint[1], 2) );
 let cosA = (ePoint[0] - bPoint[0]) / bevelling;
 let sinA = (ePoint[1] - bPoint[1]) / bevelling;
 
 let curStep = 0;
 let step = 5;
 destCroods.push(new Point([bPoint[0], bPoint[1]]));
 do{
 curStep++;
 let nextPoint;
 if(curStep * step >= bevelling){
 nextPoint = new Point([ePoint[0], ePoint[1]]);
 }else{
 nextPoint = new Point([
 cosA * curStep * step + bPoint[0]
 ,
 sinA * curStep * step + bPoint[1]
 ]);
 }
 destCroods.push(nextPoint);
 }while(curStep * step < bevelling);
 }
 return destCroods;
 }

其中用到了一些数学上的三角函数和计算方法。此方法最终选一个根据步长计算后的坐标集合。

3.3 利用postcompose实现运动效果

代码如下:

tracerun(){
 if(!this.traceLine) return;
 this.traceCroods = this.cutTrace();
 this.now = new Date().getTime();
 this.map.on('postcompose', this.moveFeature.bind(this));
 this.map.render();
 }
 moveFeature(event){
 let vCxt = event.vectorContext;
 let fState = event.frameState;
 let elapsedTime = fState.time - this.now;
 let index = Math.round(300 * elapsedTime / 1000);
 let len = this.traceCroods.length;
 if(index >= len){
 //stop
 this.map.un('postcompose', this.moveFeature);
 return;
 }
 let dx, dy, rotation;
 if(this.traceCroods[index] && this.traceCroods[index + 1]){
 let isRigth = false;
 let bCrood = this.traceCroods[index].getCoordinates();
 let eCrood = this.traceCroods[index + 1].getCoordinates();
 if(bCrood[0] < eCrood[0]){
 //左->右
 isRigth = true
 }
 dx = bCrood[0] - eCrood[0];
 dy = bCrood[1] - eCrood[1];

 rotation = Math.atan2(dy,dx);
 if(rotation > (Math.PI / 2)){
 //修正
 rotation = Math.PI - rotation;
 }else if(rotation < -1 * (Math.PI / 2)){
 rotation = -1 * Math.PI - rotation;
 }else{
 rotation = -rotation;
 }
 console.log(dx + ' ' + dy + ' ' + rotation);
 let curPoint = this.traceCroods[index];
 var anchor = new Feature(curPoint);
 let style = new Style({
 image: new Icon({
 img: isRigth ? this.carRight : this.carImg,
 imgSize: [32,32],
 rotateWithView: false,
 rotation: rotation
 }),
 text: new Text({
 text: 'Car',
 fill: new Fill({
 color: 'red'
 }),
 offsetY: -20
 })
 }); 
 vCxt.drawFeature(anchor, style);
 //this.map.getView().setCenter(bCrood);
 }
 this.map.render();
 }

此移动代码的是用ol的postcompose事件进行实现的,因为render方法执行完成后会触发postcompose事件,所以就代替了定时器的的实现方案。其中rotation根据两点坐标计算出移动图标的斜度、以及移动的方向等,更为影响的展示。

文档

OpenLayer怎么实现小车按路径运动

客户需要的功能就是能在一张Gis图上实现小车根据路径进行移动,为什么一定要Gis呢(这是客户指定需求,无语一该)。并且客户还说底图要很容易更换,但他想要用Gis表现的却是室内的地理信息,我也没办法用baidu.高德等现成的Gis接口。针对上述需求,我没有去了解过多的web gis框架。因为客户对Gis的概念就是能放大,缩小,可以做路径规划等。所以我就选择ol,利用他的静态图片(选择这个是为满足客户灵活更新底图的需求)做Gis底图的功能来解决此问题。相关教程:js视频教程二、效果展示。三、伪代码实现。由于是技术验证代码,有些杂乱,现只给出关键性代码。如有业务需要欢迎共同讨论。3.1 实现路径的绘制。
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top