监管大屏系统_高速公路监管系统大屏可视化
0x00 项目背景
该项目用于高速公路监管。高速公路监管包括:高速公路的设备运行情况,设备维护情况,道路维护情况;交通流量分析,交通拥堵分析,拥堵溯源;事故分析,事件信息发布等。
0x01设计图
该项目目前主要是一个预演形式的项目,所以设计图层面主要还是用了客户提供的图片。 我们的设计团队参与的并不多。下面是客户的设计图纸:
设计图
0x02 绘制公路
公路的实际效果还是比较复杂的,比如公路上面有各种线(斑马线,黄线,白线,实线,虚线等等)。但是这些在本系统不是最重要的要素,因此考虑忽略。因此我们使用带边线效果的路径进行模拟,效果如下所示:
公路效果
绘制的逻辑其实也很简单,首先用较大的线宽绘制路径,然后改为较小的线宽和不同颜色在绘制一次路径。 大致的绘制逻辑如下:
ctx.save();
ctx.beginPath();
ctx.lineJoin = 'round';
// ctx.lineCap = 'round';
points.forEach(({
x,
y
}, index) => {
ctx[index ? 'lineTo' : 'moveTo'](x, y);
})
ctx.lineWidth = width;
ctx.strokeStyle = sideColor;
ctx.stroke();
ctx.shadowBlur = 0;
ctx.globalCompositeOperation = 'source-over';
ctx.lineWidth = width * 0.5;
ctx.strokeStyle = midColor;
ctx.stroke();
在编辑器中,增加一个公路组件,点击下公路组件,便可以开始绘制公路:
公路组件
通过打点编辑路径,即可以对公路的走向进行编辑。 需要注意的是,技术上使用了自动平滑的技术,原本的尖锐的角都会变成平滑的效果。
export function createSmoothCurvePoints(
points,
tension = 0.5,
closed = false,
numberOfSegments = 16
) {
if (points.length < 2) {
return points;
}
// 展开数组
points = expandPointArr(points);
let ps = points.slice(0), // clone array so we don't change the original
result = [], // result points
x,
y, // our x,y coords
t1x,
t2x,
t1y,
t2y, // tension vectors
c1,
c2,
c3,
c4, // cardinal points
st,
t,
i; // steps based on number of segments
// The algorithm require a previous and next point to the actual point array.
// Check if we will draw closed or open curve.
// If closed, copy end points to beginning and first points to end
// If open, duplicate first points to befinning, end points to end
if (closed) {
ps.unshift(points[points.length - 1]);
ps.unshift(points[points.length - 2]);
ps.unshift(points[points.length - 1]);
ps.unshift(points[points.length - 2]);
ps.push(points[0]);
ps.push(points[1]);
} else {
ps.unshift(points[1]); // copy 1st point and insert at beginning
ps.unshift(points[0]);
ps.push(points[points.length - 2]); // copy last point and append
ps.push(points[points.length - 1]);
}
// 1. loop goes through point array
// 2. loop goes through each segment between the 2 points + 1e point before and after
for (i = 2; i < ps.length - 4; i += 2) {
// calculate tension vectors
t1x = (ps[i + 2] - ps[i - 2]) * tension;
t2x = (ps[i + 4] - ps[i - 0]) * tension;
t1y = (ps[i + 3] - ps[i - 1]) * tension;
t2y = (ps[i + 5] - ps[i + 1]) * tension;
for (t = 0; t <= numberOfSegments; t++) {
// calculate step
st = t / numberOfSegments;
// calculate cardinals
c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1;
c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2);
c3 = Math.pow(st, 3) - 2 * Math.pow(st, 2) + st;
c4 = Math.pow(st, 3) - Math.pow(st, 2);
// calculate x and y cords with common control vectors
x = c1 * ps[i] + c2 * ps[i + 2] + c3 * t1x + c4 * t2x;
y = c1 * ps[i + 1] + c2 * ps[i + 3] + c3 * t1y + c4 * t2y;
//store points in array
result.push(x);
result.push(y);
}
}
return contractPointArr(result);
0x03 门架的绘制
门架的最终效果如下图所示:
门架
可以看出门架是由几个立方体组合而成的。我们只需要理解立方体的绘制逻辑,便可以很轻松理解门架的绘制逻辑。
绘制立方体
编辑器中本身也存在立方体组件:
立方体组件
其显示效果如下:
立方体效果
绘制立方体的思路并不复杂,只是借助了一些三维的思路。首先借助了三维的投影变换的思路,当然此处使用的是正投影:
/**
* 3d坐标转2d坐标
*
* @param {Object} point - 3d坐标
* @param {Object} offset - 一点偏移
* @returns {Object} - 2d坐标
*/
getProjectionPoint(point) {
const network = this._network,
p = vec3.create(),
itMat = network.getMVMatrix();
vec3.transformMat4(
p,
[point.x, point.y, point.z],
itMat
);
const {
x,
y
} = this.getLocation()
return {
x: p[0] + x,
y: -p[1] + y
};
}
对立方体的8个顶点计算出其在平面上的位置,并计算出其现在在外面的三个面(注意:最多只会有三个面显示在外面)。 然后把三个面绘制值出来:
drawSide(ctx, points, isFill = false, color = "#00ccff") {
ctx.save();
ctx[isFill ? 'fillStyle' : 'strokeStyle'] = color;
ctx.lineWidth = 1;
ctx.beginPath();
points.forEach(({
x,
y
}, index) => {
ctx[index ? 'lineTo' : 'moveTo'](x, y);
})
ctx.closePath();
ctx[isFill ? 'fill' : 'stroke']();
ctx.restore();
}
最终绘制的效果如上图所示。
门架的绘制,就是多个立方体的组合的绘制。需要注意的一点就是,要注意多个立方体绘制的顺序,这会涉及到遮挡关系的正确性。
在编辑器中,可以通过调整其长宽高和y轴旋转角度来改变其显示形态:
门架
0x04 标志牌的绘制
标志牌是公路上面常见的对象。 用于各种提示,在本系统,标志牌显示效果如下:
标志牌
其绘制思路其实和前面的门架类似,都是通过立方体组合而成的。因此此处不再赘述。
0x05 山的绘制
由于山是比较复杂的模型,因此程序直接使用了设计人员的设计的图形。如下图所示:
山
使用设计人员设计的图片作为网元的图片,直接拖拽进入场景即可。
0x05 图表的绘制
编辑器中集成了常用的echarts图表和扩展的图表。应此可以直接拖拽到场景之中,比如下图截出了部分的图表,包括柱状图、饼图、曲线图:
图表组件
把图表直接拖到场景中即可生成图表效果,如下图所示:
图表效果
并可以在属性框配置图表的数据,此处为了演示,使用的是静态数据;也可以对接动态的数据上俩。
0x06 最终效果
综合上述所有的效果,最终编辑出来了一个演示页面,如下图所示:
最终效果
另欢迎关注个人公众号 “ITman彪叔”
相关文章:

Android(java)学习笔记96:layout_weight使用注意事项
1. android:layout_weight使用说明: layout_weight是权重的意思,也就是各个控件所占的比重,用在LinearLayout布局中。当我们使用layout_weight的时候,layout_width和layout_height有三种表示方法 2. android:layout_weight使用之 …

41.uniq命令
uniq命令: 选项:-c:显示每行的重复次数;-u:仅显示未曾重复过的行;-d:仅显示重复过的行; 实例: 转载于:https://blog.51cto.com/itxuezhe/2354162

[JS-JQuery]基础
<noscript> If you see this message, your web browser doesnt support JavaScript or JavaScript is disabled. Please enable JavaScript in your browser settings so Newegg.com can function correctly.</noscript> $(tr:odd) //选择表格的奇数行$(div:visi…

位置偏移问题 绘制_AutoCAD教程之绘制螺栓连接组合图
螺栓、螺母是机械连接件中最为常用的标准件,螺栓连接通常需要组合在一起。下面我们以绘制螺栓连接组合件为例,学习在AutoCAD 2019中移动、复制、旋转等操作的应用方法。1. 新建文件及图层新建一个“无样板公制”文件,新建粗实线、细实线、中心…

spring mvc 控制器方法传递一些经验对象的数组
由于该项目必须提交一个表单,其中多个对象,更好的方法是直接通过在控制器方法参数的数组。 因为Spring mvc框架在反射生成控制方法的參数对象的时候会调用这个类的getDeclaredConstructor方法来获得构造函数, 可是一直报NoSuchMethodException的异常。 依据这种方法…

sendmail configuration on HP-UX
使用mailx 发送邮件mailx -s "Msg title here" xxxxxx.comhello,this is the mail body<--------邮件正文. <-----------------一个点,表示正文结束EOT<--------------上面输入点之后,系统自动出现EOT,表示邮件输入完毕-s…

数据齿轮(DataGear)数据库管理系统 v1.1.1 发布
数据齿轮(DataGear)数据库管理系统v1.1.1版本发布,此版本是v1.1版本的紧急BUG修复版本,更新内容如下: 修复:修复集成软件包在JRE8及以上版本无法正常运行的BUG;数据齿轮(DataGear&am…

带哨兵节点的链_【算法导论】10.2不带哨兵节点和带哨兵节点的双向链表
不带哨兵节点的双向链表即一般的双向链表,有一个头指针指向第一个节点,每个节点有key值和两个指针next和pre,分别指向前后相邻的节点,头结点的preNULL,尾节点的nextNULL,比较明了,但是也有麻烦的…
Android环境结构--安装Eclipse错
在学习安卓第一步。成立了一个开发环境。经验,知道,所以这一步是不容易,因为你觉得,我可能是太幸运了。我见到 题。 首先,安装Eclipse的时候。 【Problem 1】 【问题原因】: (1) 安装…

ThinkPHP的标签制作
thinkphp的默认标签解析器在Lib/Template/TagLib/TagLibCx.class中里面定义了常用的volist php 等常用thinkphp的标签这里笔者在这个类中添加一个<category>的标签解析标签格式:<category parentid0 ><{$cat.catname}></category>标签作用&…
Go进阶:反射3定律
各位学习Go语言的朋友,周末好,这次跟大家聊一聊Go语言的一个高级话题:反射。 这篇文章是从我过去的学习笔记修改来的,内容主要来自Go Blog的一篇文章《The law of reflection》。 这篇文章主要介绍反射和接口的关系,解…

qlabel可以选中吗_Qt QLabel详解
Qt QLabel详解Qt QLabel详解一、QLabel常用方法1. QLabel设置文本内容ui.label->setText(QStringLiteral("测试中文\n"));2. QLabel设置颜色通过设计器里面的改变样式进行设置:同时可以设置字体、文本对齐方式、背景图片color: rgb(255, 85, 0);backgr…

数据库种类 以及优缺点
1.MySQL MySQL是最受欢迎的开源SQL数据库管理系统,它由 MySQL AB开发、发布和支持。MySQL AB是一家基于MySQL开发人员的商业公司,它是一家使用了一种成功的商业模式来结合开源价值和方法论的第二代开源公司。MySQL是MySQL AB的注册商标。 MySQL是一个快速…

xcode 4.2 不再支持 Window-Based Application 的解决办法(转载)
xcode 4.2 不再支持 Window-Based Application 的解决办法: 1.创建空项目 Empty Application。(在Xcode4.2下创建的这个空项目不再有MainWindow.xib文件了。) 2.CtrlN,创建User Interface下面的Window(选择“i…

java知识概论
转载于:https://www.cnblogs.com/arrows/p/10432301.html

及cp含义_当我们谈论CP时,我们在谈论什么?
2015年B站UP主剪刀手轩辕投稿了一个名为《【魔性拉郎群像】你问我爱你有多深》的视频,让伏黛(伏地魔林黛玉)这个CP走进了众多二次元观众的视野,让这个超级冷门的小众CP一跃成为微博超话,甚至还上了当时的微博热搜。其实早在2010年,…
40个出色的Wordpress cms插件
WordPress is a great blogging platform with a potential of being an easy to use content management system. This is the third article of our three-part series, “The Comprehensive Guide for a Powerful CMS using WordPress”. We are taking a look at 40 qualit…

Xcode 添加代码块
我们经常会定义一些retain的property,而且大概每次我们都会像这样写: property (nonatomic, retain) Type *name; 每次都要老老实实的把“property (nonatomic, retain)”敲一遍,这样太累了。 那么能不能像XCode自带的代码提示功能一样&…
软考自查:计算机网络
计算机网络 内容提要 七层模型网络技术标准与协议网络类型与拓扑结构网络规划与设计IP地址与子网划分特殊含义IP地址HTML无线网网络接入技术IPv6OSI/RM七层模型 七层模型练习题 某IP网络连接如图所示,在这种配置下IP全局广播分组不能够通过的路径是_B_。A࿱…

restful url 设计规范_restFul接口设计规范
1. 域名应该尽量将API部署在专用域名之下。https://api.example.com如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下。https://example.org/api/2. 版本(Versioning)应该将API的版本号放入URL。http://www.example.com/app/1.0/foohttp://www.…

Dictionary作为数据源绑定,调用c++库中返回为BYTE*的函数,listView项排序
最近在做一个电子档案管理的项目。现在还处于初期,只是做一个简单demo拿去跟客户演示。至于最后谈不谈得下来,到底做不做,反正我是不看好,但没因为这样就马马虎虎、草草了事。这个项目算是b/s加c/s混合体,现在已经做的…

ES6 新特性
ES6 先阅读这个http://gejiawen.github.io/2015/07/28/Javascript/ECMAScript6%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E7%B3%BB%E5%88%97/ECMAScript6%E6%96%B0%E7%89%B9%E6%80%A7%E7%AE%80%E4%BB%8B/ ES6的特性在chrome中默认是关闭的 Visit chrome://flags/#enable-javascrip…
一次被僵尸网络病毒攻击的过程
事件背景 回想起来应该算是去年的事情了, 时值 2019 年 1 月 24 日早上, 当时我正忙碌于开发手头的一个珠宝分销系统项目, 由于已经进行了多日封闭式开发, 项目初见效果, 准备放到内网服务器 A 上跑跑看. 项目的一些功能需要通过公网才能访问, 于是便打算通过一台之前就架设在公…

c2 链路_POS链路不能打开的解决办法
介绍的是POS链路不能打开的解决办法,其原因是C2字节不匹配,这里以华为路由器为组网环境。一、网络环境路由器A有GE接口和2.5G POS接口与其他路由器连接,启动路由器A后,发现GE端口的状态为正常开启,但2.5G POS端口无法开…
“寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
如果第二次看到我的文章,欢迎下方扫码订阅我的个人公众号(跨界架构师)哟~本文长度为5723字,建议阅读15分钟。坚持原创,每一篇都是用心之作~这是一篇以程序员视角写的文章,但是内容是互联网行业通…

TCP拥塞控制算法内核实现剖析(二)
内核版本:2.6.37 主要源文件:linux-2.6.37/ net/ ipv4/ tcp_bic.c 本文主要分析BIC算法实现 1. 相关结构体和参数 /* BIC TCP Parameters */struct bictcp {u32 cnt ; /* increase cwnd by 1 after ACKs */u32 last_max_cwnd ; /* last maximum snd_cw…

关于IOS中的self关键字
在C#、Java中都有一个关键字this用于表示当前对象,其实在ObjC中也有一个类似的关键字self,只是self不仅可以表示当前对象还可以表示类本身,也就是说它既可以用在静态方法中又可以用在动态方法中。-(void)setName:(NSString *)name andAge:(in…

中值定理符号怎么读_微分、微分中值定理、泰勒公式
问对问题,找对方法,做对的事~ 黑莓 2020/10/09 温习001-031逻辑、集合、空间 线性代数00线性代数研究什么内容?-上海交大032-047行列式的定义、性质与计算10/03048-078矩阵的定义、运算10/03079-117可逆矩阵、初等变换与秩10/04…
Java高级特性增强-多线程
请戳GitHub原文: https://github.com/wangzhiwub... 大数据成神之路系列: 请戳GitHub原文: https://github.com/wangzhiwub... Java高级特性增强-集合 Java高级特性增强-多线程 Java高级特性增强-Synchronized Java高级特性增强-volatile Java高级特性增强-并发集合…

微软企业库4.1学习笔记(八)创建对象 续集2
3.3通过配置指定和Unity的整合 另外一种方法是在配置源中指定配置的需要,你可以指定下面的一条或者多条: 你可以在Unity配置中指定想要的BlockExtensions 你可以在Unity配置中的type配置节指定如何创建企业库对象,指定类型映射的关系&…