数据
数据可视化主要旨在借助于图形化手段,清晰有效地传达与沟通信息。因此做数据可视化前需要想明白2件事:

  • 你有什么数据?
  • 你要传达什么信息?

本文中的示例中,将以不同的颜色显示澳大利亚不同地区的客户数量。



因此,首先需要澳大利亚的地图数据,D3中的Geo模块可以处理GeoJSON格式的地理数据。(GeoJSON是一种对各种地理数据结构进行编码的格式。GeoJSON对象可以表示几何、特征或者特征集合。GeoJSON支持下面几何类型:点、线、面、多点、多线、多面和几何集合。GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。参见:http://www.oschina.net/translate/geojson-spec?cmp

开发者可以从Natural Earth(http://www.naturalearthdata.com/)获取到全球所有的地理数据,使用其地理数据需要 注意2点:

  • 其有3种比例的数据1:10m,1:50m和1:110m。1:10m比例的数据拥有更细节的数据,只有它才有州(省)的信息。
  • 其数据不是GeoJSON格式的(Shapefile),需要通过GDAL(Geospatial Data Abstraction Library)库转换为GeoJSON格式。

在Mac下安装GDAL非常方便,感谢Homebrew:

  1. brew install gdal

然后通过如下命令就可以Shapefile中的澳大利亚的数据提取出来。

  1. ogr2ogr -f GeoJSON -where "sr_adm0_a3 = 'AUS'" aus.states.json 10m_cultural/ne_10m_admin_1_states_provinces_lakes_shp.shp

是一个类似下文这样的一个GeoJSON格式数据。

  1. {
  2. "type": "FeatureCollection",
  3. "features": [
  4. {
  5. "type": "Feature",
  6. "properties": {
  7. ...
  8. },
  9. "geometry": {
  10. "type": "Polygon",
  11. "coordinates": [
  12. [
  13. ....
  14. ]
  15. ]
  16. }
  17. },
  18. ......

顺道提一下,Geo数据一般都比较大,尤其是GeoJSON格式下的数据,像上面生成的数据就有741KB,这对于Web应用来说已经是很大的一个数值。开发者可以通过Topojson(https://github.com/mbostock/topojson/wiki)压缩数据。Topojson是GeoJSON的一个扩展,使用方式大致相同,这儿就不讲Topojson了,下图可以让开发者大致了解一下三种格式下数据的大小:





画图

有了数据,接下来就开始画图。D3画图都有一定的套路,首先需要确定把矢量图SVG放到那儿,以及图的大小

  1. var width  = 960;
  2. var height = 580;
  3. var svg = d3.select("#geo_distribution").append("svg")
  4. .attr("width", width)
  5. .attr("height", height)
  6. .append("g")
  7. .attr("transform", "translate(0,0)");

接着,需要创建一个路径生成器,路径生成器可以接收一个投射函数,该投射函数存在的目的是把圆形地球上的经纬度投射到平面的Web界面上。D3自带了各种各样的投射函数(https://github.com/mbostock/d3/wiki/Geo-Projections),本例中使用的是墨卡托投影(http://baike.baidu.com/view/301981.htm?fr=aladdin)。

  1. var projection = d3.geo.mercator()
  2. .center([132, -28])
  3. .scale(850)
  4. .translate([width/2, height/2]);
  5. var path = d3.geo.path()
  6. .projection(projection);

然后,根据读取的GeoJSON数据绘制路径:

  1. var color = d3.scale.category20();
  2. var states = svg.append("svg:g")
  3. .attr("id", "states");
  4. d3.json("data/aus.states.json", function(error, root) {
  5. if (error)
  6. return console.error(error);
  7. states.selectAll("path")
  8. .data( root.features)
  9. .enter()
  10. .append("path")
  11. .attr("stroke","#000")//路径线颜色
  12. .attr("stroke-width",1)//路径线宽度
  13. .attr("fill", function(d,i){
  14. return color(i);//color函数可根据数据设置每个州板块的颜色,示例中使用的是D3自带的颜色函数。
  15. })
  16. .attr("d", path )
  17. .on("mouseover",function(d,i){//添加鼠标事件
  18. d3.select(this)
  19. .attr("fill","yellow");
  20. })
  21. .on("mouseout",function(d,i){
  22. d3.select(this)
  23. .attr("fill",color(i));
  24. });
  25. });

画到这儿一个澳大利亚的地图就是下面这个样子了:





加点佐料

画了地区之后,纯属个人乐趣,还想画点城市在上面,做法也是一样的, 首先获取Geo数据,还是可以从Natural Earth的地理数据中转换得到(注:转换数据时,开发者可以根据个人爱好过滤掉一些数据,比方说下面的命令中我过滤掉了规模上第四等级以后的小城市):

  1. ogr2ogr -f GeoJSON -where "ADM0_A3 = 'AUS' and SCALERANK <=4" aus.big.cities.json 10m_cultural/ne_10m_populated_places.shp

接着,把用于描述城市的小圆点和城市名字的SVG添加到底层SVG上:

  1. var circles = svg.append("svg:g")
  2. .attr("id", "circles");
  3. var texts = svg.append("svg:g")
  4. .attr("id", "texts");

然后,根据前面得到的数据在创建的SVG上画图

  1. d3.json("data/aus.cities.json", function(error, root) {
  2. circles.selectAll("circle")
  3. .data(root.features)
  4. .enter().
  5. append("svg:circle")
  6. .attr("cx", function(d){return projection([d.properties['LONGITUDE'],d.properties['LATITUDE']])[0];})//根据城市的经纬度投射确定圆点坐标
  7. .attr("cy",function(d){return projection([d.properties['LONGITUDE'],d.properties['LATITUDE']])[1];})
  8. .attr("r", 3)
  9. .attr('fill','#29FF57');
  10. texts.selectAll("text")
  11. .data(root.features)
  12. .enter()
  13. .append("svg:text")
  14. .text(function(d){return d.properties['NAME'];})
  15. .attr("x", function(d){
  16. return projection([ d.properties['LONGITUDE'],d.properties['LATITUDE']])[0];})
  17. .attr("y",function(d){
  18. return projection([d.properties['LONGITUDE'],d.properties['LATITUDE']])[1];
  19. })
  20. .attr('fill','#000')
  21. .attr('font-size','9px');
  22. });

最后得到的结果如下:





参考:



http://www.tnoda.com/blog/2013-12-07

https://github.com/mbostock/d3/wiki/Geo-Paths#path

使用D3 Geo模块画澳大利亚地图的更多相关文章

  1. nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录

    geo指令使用ngx_http_geo_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_geo_module.ngx_http_geo_modu ...

  2. c语言贪吃蛇详解1.画出地图

    c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...

  3. Nginx geo模块

    geo 模块默认编译进nginx 可以通过--without-http_geo_module禁用 Syntax: geo [$address] $variable { ... } Default: — ...

  4. (转)nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录

    nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录 原文:http://www.cnblogs.com/kevingrace/p/6165572.html Nginx的geo模块 ...

  5. nginx 变量相关的map模块与split_clients模块及geo模块和geoip模块及keepalive介绍

    map 模块指令默认编译进nginx的 Syntax: map string $variable { ... } # 表示string匹配到{}里的值或变量赋值给$variable Default: ...

  6. nginx使用geo模块进行接口访问限制

    背景需求: 对api接口 /api/inner 进行ip访问限制 # ip白名单geo $ip_list { default 0; 111.111.111.111 1; } server { list ...

  7. 使用SVGDeveloper画svg地图详细过程

    使用步骤 1.  安装svg 2.  具体操作 1.     打开svg,点击file ,new,默认svg,点击ok 显示界面如下: 然后点击image 把鼠标放到代码下面的的桌面上,鼠标箭头会变成 ...

  8. echarts画中国地图并上色

    任务是画一个中国地图,并在指定区域上颜色,学姐说用arcgis画,乖乖,4个g的安装文件,算了, 还是echarts大法好..如果想熟悉这个牛X的工具,请移步https://www.w3cschool ...

  9. D3.JS V4 绘制中国地图

    参考:http://bl.ocks.org/almccon/fe445f1d6b177fd0946800a48aa59c71 http://blog.csdn.net/lzhlzz/article/d ...

随机推荐

  1. JSP编译为Java类

    JSP编译为Java类: 注意可以随便写import的内容:可以写类属性.方法.main函数.内部类:可以使用内部类: JSP: <%@ page language="java&quo ...

  2. MySQL各存储引擎

    MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术,你能够获得额外的速度或 ...

  3. Docker 1.13 管理命令

    1.12 CLI 的问题 Docker1.12 命令行接口(CLI)有40多个顶级命令,这些命令存在以下问题: 没有归类组织,这让docker 新手很难学习: 有些命令没有提供足够的上下文环境,以至于 ...

  4. 打开phpmyadmin显示高级功能尚未完全设置部分功能未激活

    问题:老师,打开phpmyadmin显示高级功能尚未完全设置部分功能未激活,应该如何解决? 这是前一阵子学生问过我的一个问题,今天我就在博客里解答你的疑问吧. 总共三步可以搞定 1.导入相关文件到数据 ...

  5. C++ 头文件系列(iosfwd)

    简介 输入输出历来都是语言的重要部分,在C++中,该库也是占据了相当大的一部分. C++的输入输出库是其遵循面向对象设计的结果,并结合了泛型编程. 以下是这些库类的关系图(箭头标示继承,白框表示摸板, ...

  6. android 项目更改包名的方法

    本文章全文转载: http://www.2cto.com/kf/201304/206747.html 1.在项目上右键,选择android tools->rename application p ...

  7. WEB前端性能优化之二——css优化

    1.把样式表置于顶部 现把样式表放到文档的< head />内部似乎会加快页面的下载速度.这是因为把样式表放到< head />内会使页面有步骤的加载显示.HTML规范清 楚指 ...

  8. SQLite基础回顾

    SQLite基础回顾 SQLite iOS中的数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding(N ...

  9. PHP基础学习(函数一)

    PHP(Hypertext Preprocessor):超文本预处理器,一种嵌入在HTML中并且运行在服务器端的脚本语言. var_dump--打印变量相关信息 说明:  <?php var_d ...

  10. #define宏与const的区别

    1.#define宏的用法 #define用宏名代替一个字符串,这样便于修改,提高了程序的可移植性.编译器在编译预处理时只对宏做文本替换,而不进行类型检查,所以替换后可能产生一些副作用. 带参数的宏类 ...