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彪叔”

监管大屏系统_高速公路监管系统大屏可视化相关推荐

  1. 监管大屏系统_『Udesk数据大屏』独家上线,对客户服务监管一目了然·一览无遗。...

    数据大屏是企业沟通与交流的有效途径之一,当前,大屏已经成为一种新型媒体,他可以帮助企业进行品牌宣传.实力展示.商业交流.数据监控等重要的作用.像天猫双11活动中,阿里的双11大屏让人印象深刻,该大屏不 ...

  2. 安卓程序 静默 截屏工具_安卓定制系统开放性对比测试:到底谁最自由?

    国内的安卓环境相当特殊,由于谷歌服务的缺位,各大厂商都要推出自己的定制化UI,以满足国内用户更加本地化的需求.这样一来,不同品牌的手机,系统体验上也会有很多不同. 相比iOS等封闭系统,安卓的一大优势 ...

  3. 会员计费系统c语言_高速公路计费系统 (代码)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include float sum1,sum2;int sk=0; struct carr{int st; /*车辆数*/   float k; /*公 ...

  4. 华为手机如何升级鸿蒙系统_华为鸿蒙系统真正要做的是什么?华为鸿蒙系统新升级即将揭秘...

    鸿蒙在去年的华为开发者大会上受到了空前的关注,也标志着,华为做操作系统这件事,正式从幕后走到了台前. 但很多人对鸿蒙是有误解的. 这种误解源于多层因素的影响,比如在美国制裁事件后,一些人会想当然地将鸿 ...

  5. MySQL信息发布系统_信息发布系统

    系统介绍 由盾华科技自主研发的,用于在网络环境下,对多媒体信息进行编辑处理和控制发布的专业系统平台.联网多媒体信息发布系统融合网络技术.信息技术和多媒体技术,可对音视频.图片.流媒体等多种素材编辑制作 ...

  6. 比赛打分智能展示系统_评委计分系统-双屏标准版】隆重推出。

    [涉及词汇:打分系统,打分软件,评分系统,评分软件,评委打分,比赛评分,比赛打分,竞赛评比] [应用场合] 应用于文艺比赛.演讲比赛.模特比赛等需要评委打分的场合.如果结合投影或电视,会制造出强烈的视 ...

  7. carplay是否可以用安卓系统_苹果CarPlay系统是什么?安卓系统手机能用吗?

    展开全部 由于carpaly是专门为苹果系统适配的车载互联32313133353236313431303231363533e4b893e5b19e31333366303736系统,所以安卓系统手机现在 ...

  8. 华为哪款手机是鸿蒙系统_华为鸿蒙系统不会用于手机?

    今天和大家聊聊鸿蒙系统. 7 月 12 日上午消息,华为董事长梁华在谈及鸿蒙系统时表示,鸿蒙系统是为物联网开发的,用于自动驾驶.远程医疗等低时延场景.华为手机还是把开放的安卓系统和生态作为首选,如果美 ...

  9. 华为手机如何更新鸿蒙系统_华为鸿蒙系统可以更新用上啦

    华为鸿蒙OS是一款分布式的操作系统,面向未来,基于微内核面向多种场景,鸿蒙OS1.0可实现更全面的系统安全,基于开源架构,关键模块自研的全新的系统,现在鸿蒙os2.0系统已经发布,那么很多小伙伴就想知 ...

最新文章

  1. 【通知】深度学习之人脸图像算法重印,欢迎读者支持!
  2. swagger配置分组
  3. mysql中having的例子_mysqlgroupby/having/distinct查询使用例子_MySQL
  4. 图论--欧拉回路(模板)
  5. vue form validate 多个input_Vue表单校验插件Vuerify使用详细教程及示例
  6. Encoding非常用编码转换
  7. Beta版本冲刺(四)
  8. 一线大厂都在跑的微服务,真有这么香吗?
  9. Atitit 函数式常用子操作与组合 目录 1. 集合类的操作 1 1.1. Transform、map 1 1.2. paip.提升效率---filter map reduce 的java 函
  10. macbook pro M1Pro安装java开发环境,jdk和eclipse安装包快速下载方式
  11. Cmd命令检测电脑配置:
  12. 6步教你zencart模板制作
  13. Frenet坐标系与Cartesian坐标系互转(二):Python代码函数实现
  14. 【Android 学习】之二维码扫描开发(闪光灯功能)
  15. SQL: 第二高的薪水
  16. 百度地图API学习---隐藏百度版权标志
  17. 程序员必知的编程4大祖师爷,C语言之父堪称编程界的牛顿!
  18. 简单聊聊PostgreSQL buffer与OS cache
  19. 【大屏】 amap + echarts 踩坑以及避免办法
  20. 【解决方案】EasyNVR视频边缘计算网关如何实现智慧消防?

热门文章

  1. 6 OC中 isa 和 superclass 的总结
  2. 反向春运成为新趋势 客流年增9%
  3. MySQL如何判别InnoDB表是独立表空间还是共享表空间
  4. python爬虫 智联招聘 工作地点
  5. 简单ajax类, 比较小, 只用ajax功能时, 可以考虑它
  6. PHP-Fpm应用池配置
  7. 你不知道的对称密钥与非对称密钥
  8. Regular Expression Matching
  9. linux下配置ip地址的方法
  10. .NET Winform也能画出类似QQ、飞信这样的窗口风格和控件效果