近期由于业务的需求,让我这从未想过要碰Web Gis的业余前端开发者,走了Web Gis的开发道路。功能需求很简单,但却也是让自己难为了好几天。如,应该选择那个Gis框架,Gis框架的兼容性如何,直接Ie哪些版,能不能简单到只有一张图片就行解决问题,等等。。。。。。

在如此多的技术盲点,以及不确定的因素,我开始了征程,现将一些心得做些记录。

一、需求分析

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

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

二、效果展示

三、伪代码实现

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

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实现路径运动的更多相关文章

  1. 简单聊一聊那些svg的沿路径运动

    之前遇见动画就很想用css实现,显然有些效果是我们力所不能及,实现起来麻烦,效果不好,让人捉急.其实归结起来,不同的动画有自己的优势,根据实际情况进行取舍.本文就告诉大家如何用SVG写出个简单动画.就 ...

  2. u3d 逐个点运动,路径运动。 U3d one by one, path motion.

    u3d 逐个点运动,路径运动. U3d one by one, path motion. 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-m ...

  3. WPF编程,通过Path类型制作沿路径运动的动画一种方法。

    原文:WPF编程,通过Path类型制作沿路径运动的动画一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/de ...

  4. WPF编程,通过Path类型制作沿路径运动的动画另一种方法。

    原文:WPF编程,通过Path类型制作沿路径运动的动画另一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/d ...

  5. canvas 实现光线沿不规则路径运动

    canvas 实现光线沿不规则路径运动 此文章为原创,请勿转载 1.svg实现 2.canvas实现 3.坑点 svg让动画沿着不规则路径运动 查阅svg文档后发现,svg动画运动有两种实现方式,且都 ...

  6. ThreeJS模拟人沿着路径运动-路径箭头使用纹理offset偏移

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

  7. Canvas中点到点的路径运动

    /*随机生成两个点,然后以两点为端点,进行运动,主要使用了SetInterval,对画布进行不断的擦除描绘的操作*/1 <!DOCTYPE html> <html xmlns=&qu ...

  8. 探秘神奇的运动路径动画 Motion Path

    CSS 中有一个非常有意思的模块 -- CSS Motion Path Module Level 1,翻译过来也就是运动路径.本文将对 motion path 一探究竟,通过本文,你可以了解到: 什么 ...

  9. 用CAKeyframeAnimation构建动画路径

    复杂路径的动画,我们可以借助关键关键帧动画(CAKeyframeAnimation)来实现,给其的path属性设置相应的路径信息即可. 以下为一个红色的小球按照指定的路径运动的动画. 此动画关键在于如 ...

随机推荐

  1. 解决Select标签的Option在IE浏览中display:none不生效的问题

    页面的Select标签,需要控制Select的Option不需要显示,根据条件来隐藏某些Option选项. 正常情况下使用hide()就能实现,hide()方法实际是给Option加上display属 ...

  2. 基于Cloudera Search设计数据灾备方案

    当实际项目上线到生产环境中,难以避免一些意外情况,如数据丢失.服务器停机等.对于系统的搜索服务来说,当遇到停机的情况意味着在停机这段时间内,用户都不能通过搜索的相关功能进行访问数据,停机意味着将这一段 ...

  3. 部署网站: 配置项目到iis上运行报目录错误

    配置项目到iis上运行报目录错误 以下三种方法可使用: 1.添加文件访问权限 everyone  (线上环境慎用) 2.重新注册iis 3.web.config 加一段话 在<system.we ...

  4. mysql数据库死锁的产生原因及解决办法

    这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下   数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...

  5. JVM配置参数详解(目前不够完善)

    最近看了有关虚拟机的书籍,发现有很多虚拟机配置参数不知道,特来记录一下, -XX: MaxDirectMemorySize--->设置直接内存,不设置与Java堆内存最大值一致 -XX:Perm ...

  6. netty的编解码器理解(转)

    一.简介 在网络应用中需要实现某种编解码器,将原始字节数据与自定义的消息对象进行互相转换.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码. 编解码器由 ...

  7. 安装VirtualBox中的增强功能包VBoxLinuxAdditions

    首先,增强功能包VBoxLinuxAdditions有什么作用呢?请看: (1)实现客户机和主机间的鼠标切换. (2)与主机实现文件共享. (3)自动调整客户机分辨率. (4)与主机共享剪贴板的内容. ...

  8. ucloud mysql

    [root@--- bin]# yum install mysql-server Loaded plugins: fastestmirror Setting up Install Process Lo ...

  9. nake_api_protect 请求保护器——防止请求被恶意刷

    github : https://github.com/xjnotxj/wechat_interaction_auth -- nake_api_protect 接口请求保护器,根据 频率 + 次数 的 ...

  10. 微机原理基础(四)—— MSC51

    一.MCS51基本组成(STC89C52) CPU(8051CPU) + 存储器(4KB ROM/256B RAM)+外设(4组IO口,两个定时器,一个串口) 1.组成结构简图             ...