气象netCDF数据可视化分析

2019-09-19 15:34:22 自走棋 阅读数 162更多

分类专栏: web前端
 
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

前言

  • NetCDF(network Common Data Form)网络通用数据格式是由美国大学大气研究协会(University Corporation for Atmospheric Research,UCAR)的Unidata项目科学家针对科学数据的特点开发的,是一种面向数组型并适于网络共享的数据的描述和编码标准。

对程序员来说,它和zip、jpeg、bmp文件格式类似,都是一种文件格式的标准。netcdf文件开始的目的是用于存储气象科学中的数据,现在已经成为许多数据采集软件的生成文件的格式。

特点:NetCDF文件是自描述的二进制数据格式,即自带描述属性信息。通常包含了变量、维度和属性,变量包含了维度、属性(如数据单位)信息及变量的值。维度部分记录的是每个变量的维度名及长度。属性部分包含了一些额外信息,比如文件创建者等。

  • 很多工具都可以处理NetCDF文件,比如MATLAB,Python,Java,NCL,GrADS,CDO,NCO,Panoply,ArcMap等等。NetCDF文件数据下载地址
  • 这里主要讲一下如何利用D3在前端处理NetCDF文件进行可视化分析。
  • 核心代码如下
<script>
//--------------------------------------
// 缩放控制
function zoomed() {
var transform = d3.event.transform;
projection.scale(scale * transform.k);
updatePaths(svg);
}
//--------------------------------------
function dragstarted() {
v0 = versor.cartesian(projection.invert(d3.mouse(this)));
r0 = projection.rotate();
q0 = versor(r0);
}
//--------------------------------------
// 拖拽控制
function dragged(d) {
var v1 = versor.cartesian(projection.rotate(r0).invert(d3.mouse(this))),
q1 = versor.multiply(q0, versor.delta(v0, v1)),
r1 = versor.rotation(q1);
projection.rotate(r1);
updatePaths(svg);
}
//--------------------------------------
function updatePaths(svg) {
svg.forEach(function(e) {
e.selectAll('path.contours').attr("d", geoPath);
e.selectAll('path.graticule').attr('d', geoPath);
e.selectAll('path.land').attr('d', geoPath);
});
}
//--------------------------------------
function createMap(id, values, range) {
var svg = d3.select('body').select(id).append('svg')
.attr('width', width)
.attr('height', height);
var group = svg.append("g").datum([]);
var extent = d3.extent(values);
// 颜色插值
var color = d3.scaleSequential(d3.interpolatePlasma)
//.domain(d3.extent(values));
.domain(range);
// console.log(d3.extent(values));
// 生成等值线
var contours = d3.contours()
.thresholds(d3.range(Math.floor(extent[0]/delta)*delta, Math.ceil(extent[1]/delta)*delta, delta))
.smooth(true)
.size([isize, jsize]);
// 对生成的等值线进行填色
group
//.attr("class", "contour-stroke")
.selectAll("path")
.data(contours(values).map(invert))
.enter().append("path")
.attr('class', 'contours')
.attr("fill", function(d) { return color(d.value); })
.attr("d", geoPath);
group.append('path')
.datum(graticule)
.attr('class', 'graticule')
.attr('d', geoPath);
group.append("path")
.datum(world)
.attr("class", "land")
.attr("d", geoPath);
// zoom on svg; drag on group
group.call(d3.drag().on('start', dragstarted)
.on('drag', dragged));
svg.call(d3.zoom().on('zoom', zoomed));
return svg;
}
//==========================================
function invert(d) {
var shared = {};
var p = {
type: "Polygon",
coordinates: d3.merge(d.coordinates.map(function(polygon) {
return polygon.map(function(ring) {
return ring.map(function(point) {
return [point[0] / isize * 360 - 180, 90 - point[1] / jsize * 180];
}).reverse();
});
}))
};
// Record the y-intersections with the antimeridian.
p.coordinates.forEach(function(ring) {
ring.forEach(function(p) {
if (p[0] === -180 || p[0] === 180) {
shared[p[1]] |= p[0] === -180 ? 1 : 2;
}
});
}); // Offset any unshared antimeridian points to prevent their stitching.
p.coordinates.forEach(function(ring) {
ring.forEach(function(p) {
if ((p[0] === -180 || p[0] === 180) && shared[p[1]] !== 3) {
p[0] = p[0] === -180 ? -179.9995 : 179.9995;
}
});
}); p = d3.geoStitch(p); // If the MultiPolygon is empty, treat it as the Sphere.
return p.coordinates.length
? {type: "Polygon", coordinates: p.coordinates, value: d.value}
: {type: "Sphere", value: d.value};
}
//==========================================
function reverseVar(values) {
values = nj.array(values).reshape(jsize,isize);
values = values.slice([null, null, -1],null);
values = values.flatten().tolist(); return values;
} //==========================================
var svg = [];
var world;
var graticule; var width = 400,
height = 400,
scale = 200,
origin = {x: 55, y: -40}; var v0, // Mouse position in Cartesian coordinates at start of drag gesture.
r0, // Projection rotation as Euler angles at start.
q0; // Projection rotation as versor at start.
// 正交投影
var projection = d3.geoOrthographic()
.scale(scale)
.translate([width/2, height/2])
.rotate([origin.x, origin.y])
.center([0, 0]);
// 确定投影坐标系
var geoPath = d3.geoPath()
.projection(projection); var min = -12;
var max = 12;
var delta = 2;
var nbLevels = Math.abs(max-min)/delta + 1; var color = d3.scaleSequential(d3.interpolatePlasma)
.domain([min,max]); //==========================================
var urlpath = "navy_winds_2.nc"
var reader;
var isize, jsize;
// 读取netCDF文件数据
var oReq = new XMLHttpRequest();
oReq.open("GET", urlpath, true);
oReq.responseType = "blob"; oReq.onload = function(oEvent) {
var blob = oReq.response;
reader_url = new FileReader(); reader_url.onload = function(e) {
//====================================================================================
reader = new netcdfjs(this.result); isize = reader.dimensions[0].size;
jsize = reader.dimensions[1].size; var dim0Name = reader.dimensions[0].name;
var dim1Name = reader.dimensions[1].name;
axis0 = reader.getDataVariable(dim0Name);
axis1 = reader.getDataVariable(dim1Name); var valuesVar1 = reader.getDataVariable('UWND');
valuesVar1 = reverseVar(valuesVar1);
var valuesVar2 = reader.getDataVariable('VWND');
valuesVar2 = reverseVar(valuesVar2); range = [-12, 12]; d3.json("world-110m.json", function(error, worldJSON) {
if (error) throw error;
world = topojson.feature(worldJSON, worldJSON.objects.land);
graticule = d3.geoGraticule(); svg1 = createMap("#map1", valuesVar1, range);
svg.push(svg1); svg2 = createMap("#map2", valuesVar2, range);
svg.push(svg2); svgLegend = d3.select("#legend").append('svg')
.attr('width', 60)
.attr('height', 800);
svgLegend.append("g").attr("class", "legendLinear");
var legendLinear = d3.legendColor()
.shapeWidth(15)
.shapeHeight(15)
.shapePadding(1)
.cells(nbLevels)
.orient('vertical')
.ascending(true)
.labelAlign('start')
.scale(color);
svgLegend.select(".legendLinear")
.call(legendLinear); }); //====================================================================================
} reader_url.readAsArrayBuffer(blob); }
oReq.send(); //start process </script>

风场数据可视化结果图

 

气象netCDF数据可视化分析的更多相关文章

  1. PLUTO平台是由美林数据技术股份有限公司下属西安交大美林数据挖掘研究中心自主研发的一款基于云计算技术架构的数据挖掘产品,产品设计严格遵循国际数据挖掘标准CRISP-DM(跨行业数据挖掘过程标准),具备完备的数据准备、模型构建、模型评估、模型管理、海量数据处理和高纬数据可视化分析能力。

    http://www.meritdata.com.cn/article/90 PLUTO平台是由美林数据技术股份有限公司下属西安交大美林数据挖掘研究中心自主研发的一款基于云计算技术架构的数据挖掘产品, ...

  2. 爬虫综合大作业——网易云音乐爬虫 & 数据可视化分析

    作业要求来自于https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075 爬虫综合大作业 选择一个热点或者你感兴趣的主题. 选择爬取的对象 ...

  3. 学机器学习,不会数据分析怎么行——数据可视化分析(matplotlib)

    前言 前面两篇文章介绍了 python 中两大模块 pandas 和 numpy 的一些基本使用方法,然而,仅仅会处理数据还是不够的,我们需要学会怎么分析,毫无疑问,利用图表对数据进行分析是最容易的, ...

  4. 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析

    前言:大数据,人工智能,工业物联网,5G 已经或者正在潜移默化地改变着我们的生活.在信息技术快速发展的时代,谁能抓住数据的核心,利用有效的方法对数据做数据挖掘和数据分析,从数据中发现趋势,谁就能做到精 ...

  5. 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析【转载】

    前言:大数据,人工智能,工业物联网,5G 已经或者正在潜移默化地改变着我们的生活.在信息技术快速发展的时代,谁能抓住数据的核心,利用有效的方法对数据做数据挖掘和数据分析,从数据中发现趋势,谁就能做到精 ...

  6. Cloudera HUE大数据可视化分析

    下载版本 cdh版本 http://archive-primary.cloudera.com/cdh5/cdh/5/ 我们下载这个 这个是我下载好的 我们解压一下 下载需要的系统包 yum insta ...

  7. 新闻实时分析系统Hive与HBase集成进行数据分析 Cloudera HUE大数据可视化分析

    1.Hue 概述及版本下载 1)概述 Hue是一个开源的Apache Hadoop UI系统,最早是由Cloudera Desktop演化而来,由Cloudera贡献给开源社区,它是基于Python ...

  8. 新闻网大数据实时分析可视化系统项目——13、Cloudera HUE大数据可视化分析

    1.Hue 概述及版本下载 1)概述 Hue是一个开源的Apache Hadoop UI系统,最早是由Cloudera Desktop演化而来,由Cloudera贡献给开源社区,它是基于Python ...

  9. nmon+Java Nmon Analyser进行nmon监控数据可视化分析

    我们知道nmon是一款轻量级的系统占用极少,监控功能非常强大支持跨平台ARM,centos,ubuntu等等系统的工具下载地:centos7 wget http://sourceforge.net/p ...

随机推荐

  1. 【后缀数组】【LuoguP2408】 不同子串个数

    题目链接 题目描述 给你一个长为N的字符串,求不同的子串的个数 我们定义两个子串不同,当且仅当有这两个子串长度不一样 或者长度一样且有任意一位不一样. 子串的定义:原字符串中连续的一段字符组成的字符串 ...

  2. nodejs之mysql查询

    示例代码中的mysql版本 2.14.1 参考代码 /** * 测试mysql连接 */ var mysql = require('mysql'); var connection = mysql.cr ...

  3. C语言博客作业—2019-指针

    0.展示PTA总分 1.本章学习总结 1.1学习内容总结 指针做循环变量:即将指针作为循环变量,在指针移动到某一个位置的时候,达到了循环结束的条件,循环结束. for (p = a; p <= ...

  4. centos 7 下安装 redis

    一.安装redis服务 第一步:下载redis安装包 命令:wget http://download.redis.io/releases/redis-4.0.6.tar.gz [root@chenzh ...

  5. DDL 语言

    数据库模式定义语言并非程序设计语言,DDL数据库模式定义语言是SQL语言(结构化查询语言)的组成部分. SQL语言包括四种主要程序设计语言类别的语句:数据定义语言(DDL),数据操作语言(DML),数 ...

  6. NoSql数据库Redis系列(6)——Redis数据过期策略详解

    本文对Redis的过期机制简单的讲解一下 讲解之前我们先抛出一个问题,我们知道很多时候服务器经常会用到redis作为缓存,有很多数据都是临时缓存一下,可能用过之后很久都不会再用到了(比如暂存sessi ...

  7. 【mybatis源码学习】mybatis的参数处理

    一.mybatis的参数处理以及参数取值 1.单个参数 mybatis不做任何处理 取值方式: ​ #{参数名/任意名} <!-- Employee getEmpById(Integer id) ...

  8. JBoss服务器的安装和使用(关联到IDEA)

    1. 下载安装jboss服务器 wildfly-16.0.0.Final.zip(更名为wildfly了,选择合适的版本) 2. 解压,配置环境变量. JBOSS_HOME=D:\Program Fi ...

  9. go-micro框架学习1-准备工作

    下载golang环境,地址:https://studygolang.com/dl,这里使用的是1.11.10版本. 下载golang IDE,这里使用Lite,下载地址:http://liteide. ...

  10. JetBrainsIDEA-structure结构继承的图标说明

    图标3表示重写继承类中方法 图标2表示实现继承类抽象方法或接口中的方法 图标1表示未使用继承类中的方法 类中方法并非只统计显示继承类或实现接口中方法,而是对该类中所有方法进行分类,有可能某些方法是继承 ...