Tiven Wang
Wang Tiven August 20, 2016
425 favorite favorites
bookmark bookmark
share share

据教育部网站消息,2015年全国统一高考于6月7日至8日举行。2015年全国高考报名考生共942万人。回忆我们当年的高考,糊里糊涂的就报了志愿,为了让学弟学妹们能够尽量选择自己喜欢的学校和专业,我们有必要为他们做一些大数据的分析。接下来将要展示如何用Turf和Nodejs做地理信息方面的数据分析,继而用GeoJSON技术标准的文件在地图上展示区域分级统计图(Choropleth map)。

Prerequisites

进行分析之前我们可以先了解一下几个工具

  • Turf.js是一个能用在浏览器或者Node.js环境中做地理信息数据分析的javascript插件。

  • Node.js是一个建立在Chrome’s JavaScript runtime上为方便建立快速、可扩展的网络应用而产生的平台。

  • GeoJSON是一种对各种地理数据结构进行编码的格式。GeoJSON对象可以表示几何、特征或者特征集合。GeoJSON支持下面几何类型:点、线、面、多点、多线、多面和几何集合。GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。如何搭建Node和npm运行环境可以自行查阅相关教程。

  • 对于地理信息数据的图形化有很多种工具或途径,本文使用的是Carto。Carto侧重于对地理空间大数据的分析预测及可视化,它通过创建数据集然后展示在地图上的简单两步过程,上手非常容易。

  • Mapbox则是对地图底图多样化编辑的支持非常强大,可以让你设计出属于自己样式的地图,但过程比较复杂,需要一定的css及编程知识。

分析计算

关于本文的代码可以clone下面的repository

git clone https://github.com/anypossiblew/analyzing-number-of-entrance
.git
cd analyzing-number-of-entrance

使用Node的包管理工具npm安装依赖Turf.js

npm install turf

然后运行javascript文件,即可得到计算结果

node index.js

Turf逻辑介绍

新建一个javascript文件index.js,加载turffilesystemcsv模块

var fs = require('fs');
var csv = require('csv');
var turf = require('turf');

全国各省的区域范围我们使用现成的GeoJSON文件,加载全国各省区域范围GeoJSON数据文件

fs.readFile('china.geojson', 'utf8', function (err, data) {
 if (err) {
  throw err;
 }
 var china = JSON.parse(data);
});

全国各省区域显示如下 Image: China provinces area

下面要计算每个省的面积,这里使用到了turf.area函数。Turf支持很多Geo操作计算的functions可供选择使用,详情可以参见Turf API docs

for(var i = 0; i < china.features.length; i++) {
  china.features[i].properties.area = (Math.round(turf.area(china.features[i].geometry) * 0.000621371))/100000;
}

加载各省高考报考人数csv文件,并用csv模块的parse功能转换成Object数组

fs.readFile('number-of-entrance.csv', 'utf8', function (err, data) {
 if (err) {
  throw err;
 }
 csv.parse(data, {columns: true}, function(err, items){
  if (err) {
   throw err;
  }
 });
});

循环各省进行计算人数/面积的密度

items.map(function(item) {
 for(var i = 0; i < china.features.length; i++) {
  if(china.features[i].properties.name == item[''] ) {
   china.features[i].properties.register_number = item['人数']*10000;
    china.features[i].properties.register_density =  
     (china.features[i].properties.register_number) / china.features[i].properties.area;  
   }
  }
 });

数据计算过之后,我们也可以计算style样式(虽然这里可能使用不到,但像这样可以往properties里添加自定义的属性)

var min = 0, max = 0;
for(var i = 0; i < china.features.length; i++) {
 var registerDensity = china.features[i].properties.register_density;
 if(registerDensity > max) {
  max = registerDensity;
 }
 if(min == 0 || min > registerDensity) {
  min = registerDensity;
 }
}
for(var i = 0; i < china.features.length; i++) {
 var opacity = Math.floor((china.features[i].properties.register_density-min)/(max-min)*10+1)/10;
 china.features[i].properties.style = {
  fillOpacity: opacity
 };
}

把Json格式的结果转换未string类型的变量,然后写入指定文件

fs.writeFileSync('number-of-china-entrance.geojson', JSON.stringify(china));

可视化

通过https://carto.com/网站进行数据的可视化。

Data View

创建Map并上传文件number-of-china-entrance.geojson到Data view。

Image: Carto - Number of entrance table

Map View

在Map View右边栏我们可以在SQL tab里编写SQL以获取不同条件的数据进行展示。在Map layer wizard tab里可以选择数据展示样式,我们这里选择使用Choropleth,并为Column使用register_density

Image: Carto Number of china entrance map

实际的效果图 Image: Carto Number of china entrance

总结

本文通过Node.js强大的javascript运行容器,运行Turf .js丰富的运算函数,及Carto网站便利的可视化功能,为考生对全国各省高考密度进行了大数据分析,以希望能有所帮助。本文旨在抛砖引玉,通过介绍相关的工具,希望能在地理信息大数据分析上有所启发。

References

Similar Posts

Comments

Back to Top