初始化创建画布_使用HTML5,画布和开放数据创建全球降水(雨)可视化

初始化创建画布

我目前正在为Three.js编写下一本书,其中一章涉及可视化开放数据。 在寻找可以使用的数据时,我遇到了来自NOAA的一组数据。 通过此站点,您可以以网格格式下载一组全世界的每月降水报告。 因此,我下载了它们,然后开始处理数据以查看其外观和使用方式。 在本文中,我不会向您展示基于Three.js的结果,但是我将为您提供一个快速概述,如何获得最初用于调试目的的格式:

2012-07-PERC

在此图像中,您可以看到2012年7月全球对月降水量的对数。我还创建了一个简单的站点来显示此动画以及正在运行的动画。

因此,您需要做什么才能将可以从NOAA站点下载的集转换为可视的内容。

  • 下载并转换NetCDF格式。
  • 加载生成的CSV文件
  • 将CSV数据处理到世界网格中
  • 动画化两个月之间的过渡
  • 作为奖励:还可以创建图例以显示什么颜色表示什么

但是,首先,我们需要获取数据。

下载并转换NetCDF格式

我们需要做的第一件事就是获取数据。 我使用了以下链接:您可以在其中定义要下载的数据范围。 在此示例中,我使用了2012年1月至2012年12月的范围,并选择了创建子集而不绘制图的选项。

但是,下载它的格式不能直接用作我们基于HTML5画布的可视化的输入。 您可以使用ncdump-json创建一个JSON文件,但是仍然需要能够解释它,因此我选择了另一种方法。 我刚刚编写了一个简单的Java程序,将NetCDF格式转换为简单的CSV文件。

我使用了以下Maven依赖项:

<dependencies><dependency><groupId>edu.ucar</groupId><artifactId>netcdf</artifactId><version>4.2.20</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency></dependencies>

并使用以下一段Java代码:

public class NetCDFDump {public static void main(String[] args) throws IOException, InvalidRangeException {String year = "2012";NetcdfFile nc = NetcdfFile.open("src/main/resources/X84.31.143.145.44.1.47.49.nc");Variable precip = nc.findVariable("precip");// use the shapes to create an arrayint[] shapes = precip.getShape();// month, lat, lonfloat[][][] data = new float[shapes[0]][shapes[1]][shapes[2]];// iterate over 12 (or 11) monthsint[] pos = new int[3];int[] shape = {1,1,1};for (int i = 0 ; i < shapes[0] ; i++) {pos[0]=i;for (int lat = 0 ; lat < shapes[1]; lat++) {pos[1] = lat;for (int lon = 0 ; lon < shapes[2]; lon++) {pos[2] = lon;Array result = precip.read(pos, shape);data[pos[0]][pos[1]][pos[2]] = result.getFloat(0);}}}// output data like this// month, lat, lon, humidityfloat[][] combined = new float[data[0].length][data[0][0].length];for (int m = 0 ; m < data.length ; m++) {File outputM = new File(year + "-out-" + m + ".csv");for (int lat = 0 ; lat < data[m].length ; lat++) {for (int lon = 0 ; lon < data[m][lat].length; lon++) {float value = data[m][lat][lon];if (value > -1000) {combined[lat][lon]+=value;} else {combined[lat][lon]+=-1000;}// write the string for outputfileStringBuffer bOut = new StringBuffer();bOut.append(m);bOut.append(',');bOut.append(lat);bOut.append(',');bOut.append(lon);bOut.append(',');bOut.append(value);bOut.append('\n');// write to month fileFileUtils.write(outputM,bOut,true);}}}// now process the combinedFile outputM = new File(year + "-gem.csv");for (int i = 0; i < combined.length; i++) {for (int j = 0; j < combined[0].length; j++) {StringBuffer bOut = new StringBuffer();bOut.append(i);bOut.append(',');bOut.append(j);bOut.append(',');bOut.append(combined[i][j]/data.length);bOut.append('\n');FileUtils.write(outputM, bOut, true);}}}
}

我不会详细介绍正在发生的事情,但是这段代码会生成许多文件,每个文件一个月,其中一个包含平均值。

每月以以下格式显示

...
0,65,78,32.65
0,65,79,35.09
0,65,80,31.14
0,65,81,42.7
0,65,82,49.57
...

这些值分别表示:月份,纬度,经度和降水。 对于平均值,除了省略第一个条目外,它看起来几乎相同。

...
59,94,59.874165
59,95,65.954994
59,96,57.805836
...

现在,我们已经获得了易于使用的格式的数据,可以使用它来创建可视化。

加载生成的CSV文件

要加载文件,我们只使用一个简单的XMLHttpRequest,如下所示:

// create an XMLHttpRequest to get the datavar xmlhttp = new XMLHttpRequest();xmlhttp.onreadystatechange = function() {if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {var coords = CSVToArray(xmlhttp.responseText,",");// and process each of the coordinates...}}// make the call and use the callback to process the resultxmlhttp.open("GET", "location/of/the/file", true);xmlhttp.send();

现在,coords变量包含所有坐标,并为每个坐标显示值。 实际上,将其转换为画布非常容易。

将CSV数据处理到世界网格中

在XMLHttpRequest的回调中,我们检查是否已接收到数据并将其转换为一组坐标。 我们唯一需要做的就是将这些坐标转换为画布上的可视化图像。

var coords = CSVToArray(xmlhttp.responseText,",");coords.forEach(function(point) {var offset = 0;if (point.length > 3) {offset = 1;}if (parseFloat(point[2+offset]) >= 0) {var lat = parseInt(point[0+offset]);var lon = parseInt(point[1+offset]);var value = parseFloat(point[2+offset]);if (value > max) max = value;// lat is from 0 to 180// lon is from 0 to 360var x = canvas.width/360*((lon)-180);if (x<=0) {x=canvas.width-(x*-1);}var y = canvas.height/180*lat;if (value >= 0) {context.beginPath();context.rect(x,y,4,4);context.fillStyle = scale(value).hex();context.fill();}}});

如您所见,非常简单的代码就是我们将位置取下来,将它们转换为画布上的X和Y坐标,并创建具有特定颜色的小方块。 为了生成颜色,我们使用Chroma.js比例尺。

var scale = chroma.scale(['red' , 'yellow', 'green', 'blue']).domain([1,1700], 100, 'log');

此调用创建从红色到黄色到绿色到蓝色的色标。 值的范围是1到1700,分为100步,并使用对数刻度。 这将产生以下图像(这次是2012年1月的降水:

2012-01-PERC

由于我们拥有所有月份的数据,因此我们现在可以轻松创建简单的动画。

动画化两个月之间的过渡

对于动画,我们将创建类似于以下电影中所示的内容,其中我们在各个月份之间缓慢过渡:

只需将图像彼此叠加显示并更改不透明度,即可轻松创建此动画。 因此,首先设置一些css,它将大部分图像隐藏起来,然后将它们全部放在另一个顶部。

#cf {position:relative;margin:0 auto;height: 700px;}#cf img {position:absolute;left:0;width: 1600px;}

现在我们可以添加图像,并使用“ bottom”类仅显示第一个图像:

<div id="cf"><img id="img-1" class="top" src="./assets/images/2012-01-perc.png" /><img id="img-2" class="bottom" src="./assets/images/2012-02-perc.png" /><img id="img-3" class="bottom" src="./assets/images/2012-03-perc.png" /><img id="img-4" class="bottom" src="./assets/images/2012-04-perc.png" /><img id="img-5" class="bottom" src="./assets/images/2012-05-perc.png" /><img id="img-6" class="bottom" src="./assets/images/2012-06-perc.png" /><img id="img-7" class="bottom" src="./assets/images/2012-07-perc.png" /><img id="img-8" class="bottom" src="./assets/images/2012-08-perc.png" /><img id="img-9" class="bottom" src="./assets/images/2012-09-perc.png" /><img id="img-10" class="bottom" src="./assets/images/2012-10-perc.png" /><img id="img-11" class="bottom" src="./assets/images/2012-11-perc.png" /><img id="img-12" class="bottom" src="./assets/images/2012-12-perc.png" />
</div>

现在,我们只需要一些JavaScript即可将所有内容捆绑在一起:

var month=[];month[0]="January";month[1]="February";month[2]="March";month[3]="April";month[4]="May";month[5]="June";month[6]="July";month[7]="August";month[8]="September";month[9]="October";month[10]="November";month[11]="December";var allTweens;init();animate();function init() {// create a chain of tweensallTweens = setupTweens(12);allTweens[0].start();}function setupTweens(imageCount) {var tweens = [];for (var i = 0 ; i < imageCount ; i++) {var tween = new TWEEN.Tween( { opac: 0, image: i, max: imageCount } ).to( { opac: 100 }, 2500 ).easing( TWEEN.Easing.Linear.None ).onUpdate( function () {// on update, lower the opacity of image i and update the opacity of// image i+1;var currentImage = document.getElementById('img-'+(this.image+1));if (this.image == imageCount -1) {var nextImage = document.getElementById('img-'+1);} else {var nextImage = document.getElementById('img-'+(this.image+2));}currentImage.style.opacity = 1- this.opac / 100;nextImage.style.opacity = this.opac / 100;} );tween.onComplete(function() {document.getElementById('title-2012').textContent = "Showing precipitation: " + month[this.image] + " " + 2012;// Set the inner variable to 0.this.opac = 0;// we're done, restartif (this.max-1 == this.image) {allTweens[0].start();}});// connect to each anotherif (i > 0) {tweens[i-1].chain(tween);}tweens.push(tween);tweens[0].repeat();}return tweens;}function animate() {requestAnimationFrame(animate);TWEEN.update();}

在这里,我们使用tween.js设置图像之间的过渡。

作为奖励:还可以创建图例以显示什么颜色表示什么

在动画中,您可以在底部看到图例。 此图例创建为简单的画布,另存为图像。 为了完整起见,此处显示执行此操作的代码:

var canvas = document.createElement("canvas");canvas.width = 435;canvas.height = 30;var context = canvas.getContext('2d');var domains = scale.domain();document.body.appendChild(canvas);// from 1 to 1700for (var i = 0 ; i < domains.length ; i++) {context.beginPath();context.rect(10+i*4,0,4,20);console.log(domains[i]);context.fillStyle = scale(domains[i]).hex();context.fill();}context.fillStyle = 'black';context.fillText("0 mm", 0, 30);context.fillText(Math.round(domains[25]) + " mm", 100, 30);context.fillText(Math.round(domains[50]) + " mm", 200, 30);context.fillText(Math.round(domains[75]) + " mm", 300, 30);context.fillText("1700 mm", 390, 30);

在这里,我们只使用我们更容易看到的比例,并遍历各个域以创建彩色图例。

参考: 使用HTML5,Canvas创建全球降水(降雨)可视化,并从Smart Java博客的JCG合作伙伴 Jos Dirksen 打开数据 。

翻译自: https://www.javacodegeeks.com/2014/02/create-global-precipitation-rain-visualizations-with-html5-canvas-and-open-data.html

初始化创建画布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344198.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤教育】电大中专药品储存与养护技术 (2)作业 题库

1.在能够预见到某种药品经过短时间储存易发生质量变化时&#xff0c;该种药品的出库原则是&#xff08;&#xff09;。 A.近效期先出 B.先产先出 C.先进先出 D.易变先出 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;B 2.药品批准文号的格式为&#xff08;&#xff…

星之卡比镜之迷宫机器人_机器人工程师入门(0)

前言&#xff1a;多年前看到一片知乎文章YY硕&#xff1a;机器人工程师学习计划​zhuanlan.zhihu.com当时看到这个&#xff0c;只觉醍醐灌顶&#xff0c;能看到有如此详尽的关于机器人工程师的个人技术发展规划&#xff0c;又不禁觉得有些遗憾&#xff0c;因为这个规划是本科大…

8代主板装服务器系统,微星B365主板搭配intel 8代cpu安装win7及bios设置教程

就在前不久发布华硕和华擎分别发布了b365主板&#xff0c;近期微星也发布了b365主板&#xff0c;有很多使用微星主板的网友问&#xff0c;微星B365主板其搭载intel 酷睿8代cpu可以安装安装win7吗&#xff1f;微星B365主板预装的是win10系统&#xff0c;用户还是喜欢win7系统&am…

【渝粤教育】电大中专计算机职业素养 (12)作业 题库

1.&#xff08; &#xff09;就是职业技能的标准化、规范化、制度化。 A.职业行为 B.职业意识 C.职业道德 D.职业化 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;未作答 2.&#xff08; &#xff09;就是合适的时间、合适的地点、做合适的事 A.职业意识 B.职业习惯…

修订和不变性

这是一个简短的帖子。 我不确定如何启动它。 这是审阅一些现有代码时“为什么我没有想到”的时刻之一。 由于存在NDA&#xff0c;我无法共享实际代码。 它与处理修订有关。 与我最相关的是WordPress&#xff08;WP&#xff09;如何处理博客文章和修订。 在WP中&#xff0c; wp…

[渝粤教育] 西南科技大学 农业推广学 在线考试复习资料

农业推广学——在线考试复习资料 一、单选题 1.“ 百千万”示范是指在村建百亩( )。 A.示范片 B.试验田 C.示范区 D.示范方 2.一个随机区组试验有8个处理,四次重复,误差自由度是( )。 A.27 B.21 C.32 D.28 3.在推广教师的指导下,学员运用已有的知识、经验,从事一定的实践工作…

autowired注入为 mapper为null_兰新高铁为区域经济发展注入活力

央视网消息 &#xff1a;连接甘肃兰州至新疆乌鲁木齐的兰新高铁&#xff0c;是我国“八纵八横”高速铁路网的重要组成部分。开通运营近六年来&#xff0c;兰新高铁已累计运输旅客6760多万人次&#xff0c;在推动地区协调发展&#xff0c;便捷旅客出行等方面发挥了重要作用。乘坐…

[渝粤教育] 西南科技大学 制造业信息化导论 在线考试复习资料

制造业信息化导论——在线考试复习资料 一、单选题 1.产品设计应面向( ),与用户保持密切联系,将用户纳入产品开发过程,以多变的产品、尽可能短的交货期来满足用户的需要。 A.用户 B.供应商 C.销售商 D.物流 2.企业的生产、经营状况可通过其产品结构、产值产量、经营总额、利税…

织梦同步静态文件到服务器,某猫织梦插件-织梦dedecms静态文件生成速度的区块插件...

经常使用织梦的朋友都可能都知道织梦cms 的静态生成速度有时候让人无法忍受&#xff1b;如果是企业展的几百篇的文章&#xff0c;那当然绰绰有余&#xff0c;但是一般数据量打起来生成速度也会大幅的降低&#xff0c;与同类的其他cms比如说帝国cms&#xff0c;还有phpcms相比差…

[渝粤教育] 西南科技大学 动态网页设计(JSP) 在线考试复习资料

动态网页设计&#xff08;JSP&#xff09;——在线考试复习资料 一、单选题 1.下面关于通过JDBC访问数据库哪项说明正确? A.对数据库操作一定要驱动程序 B.对数据库操作一定要DriverManager.getConnection C.对数据库操作一定要ResultSet对象 D.对数据库的操作一定要调用存储 …

webpack 异步加载配置文件_详解webpack异步加载业务模块

虽然把我们用到的JS文件全部打包一个可以节省请求数&#xff0c;但如果打包后的JS文件过大&#xff0c;那么也容易出现白屏现象&#xff0c;许多操作失灵。而且一些区域是点到才出现&#xff0c;那么相关的JS其实可以剥离出这个大JS文件外。这就涉及到异步加载了。异步加载是SP…

[渝粤教育] 西南科技大学 基础工业工程 在线考试复习资料

基础工业工程——在线考试复习资料 一、单选题 1.线路图是以作业现场为对象,对( )进行分析。 A.现场布置及物料和作业者的实际流通路线 B.物料的加工路线 C.人员的流通路线 D.机器、工作台的相互位置 2.流程程序图是对生产现场的整个制造程序作( )的记录。 A.全面 B.大概 C.详…

antlr4 代码 语法树_使用ANTLR4,用于代码镜像和基于Web的DSL的Primefaces扩展

antlr4 代码 语法树DSL是很酷的东西&#xff0c;但我不清楚它们有什么用。 然后我意识到它们对以下方面有好处&#xff1a; 摆脱复杂的UI 意思是 更快的做事方式 而已。 当我阅读此博客时&#xff0c;我得出了这个结论。 如果您的用户是技术人员&#xff0c;并且不惧怕类…

[渝粤教育] 西南科技大学 工程力学 在线考试复习资料

工程力学——在线考试复习资料 一、判断题 1.平面图形的静矩与坐标系无关。 2.弯矩图上的极值就是梁内最大的弯矩。 3.悬臂梁或外伸梁的自由端处弯矩必定为零。 4.弯矩图应画在梁受拉的一侧。 5.当挤压面为圆柱形侧面时&#xff0c;挤压面的计算面积按该圆柱侧面的正投影面…

appium的python教程_移动App Appium自动化测试教程Appium+Python 【2018年新】_IT教程网...

资源名称&#xff1a;移动App Appium自动化测试教程AppiumPython 【2018年新】资源目录&#xff1a;第一章&#xff1a;App自动化测试概述1-1 Appium自动化课程简介1-2 课程大纲1-3 移动设备操作系统兴亡简史1-4 移动App自动化测试兵器发展历程1-5 移动App自动化测试兵器发展历…

Derby数据库备份

抽象 我已经发布了许多有关Derby的博客&#xff1a; 同一主机上的多个Derby网络服务器 Apache Derby数据库用户和权限 与Maven和内存中Derby数据库的集成测试 这本不打算是一个系列。 但是多年来&#xff0c;我越来越多地使用Derby。 最近&#xff0c;我开始将Derby用作微服…

[渝粤教育] 西南科技大学 市场营销理论与实务 在线考试复习资料2021版(1)

市场营销理论与实务——在线考试复习资料2021版 一、单选题 1.处于市场不景气或原料.能源供应紧张时期,( )产品线反而能使总利润上升。 A.增加 B.扩充 C.延伸 D.缩减 答案:看左边查询 2.以高于价值的价格将新产品推入市场,然后…

[渝粤教育] 西南科技大学 建筑经济与企业管理 在线考试复习资料

建筑经济与企业管理——在线考试复习资料 一、单选题 1.某建筑公司预计今后5年中,每年末拿出50万元作为生产基金,将其投资生产预制构件,投资年利率为12%。到第五年末,该公司共得( )万元 A.305.3 B.317.64 C.320.7 D.330 2.某公司拟投资一个项目,预计建成后每年能获利50万元…

cnn 一维时序数据_蚂蚁集团智能监控的时序异常检测:基于 CNN 神经网络的异常检测...

1背景在蚂蚁集团智能监控领域&#xff0c;时序异常检测是极重要一环&#xff0c;异常检测落地中&#xff0c;业务方参考业界标准输出 Metrics 指标数据&#xff0c;监控不同业务、应用、接口、集群的各项指标&#xff0c;包含 Metrics 指标(总量、失败量、耗时等)和系统服务指标…

[渝粤教育] 西南科技大学 投资经济学 在线考试复习资料(1)

投资经济学——在线考试复习资料 一、单选题 1.投资决策是经济决策的重要组成部分,是选择和决定( )的过程 A.投资资金 B.投资行动方案 C.投资机会 D.投资目的 2.下面属于第三产业的行业是( ) A.制造业 B.建筑业 C.农业 D.商业 3.重视资金的( )是正确确定项目成本和收益的不可…