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

互联网 19-4-30
本篇文章主要讲述的是在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);     }

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怎么实现小车按路径运动的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: html
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:Web学习之怎么使用纹理贴图

相关资讯