使用D3 Geo模块画澳大利亚地图
数据可视化主要旨在借助于图形化手段,清晰有效地传达与沟通信息。因此做数据可视化前需要想明白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:
- brew install gdal
然后通过如下命令就可以Shapefile中的澳大利亚的数据提取出来。
- ogr2ogr -f GeoJSON -where "sr_adm0_a3 = 'AUS'" aus.states.json 10m_cultural/ne_10m_admin_1_states_provinces_lakes_shp.shp
是一个类似下文这样的一个GeoJSON格式数据。
- {
- "type": "FeatureCollection",
- "features": [
- {
- "type": "Feature",
- "properties": {
- ...
- },
- "geometry": {
- "type": "Polygon",
- "coordinates": [
- [
- ....
- ]
- ]
- }
- },
- ......
顺道提一下,Geo数据一般都比较大,尤其是GeoJSON格式下的数据,像上面生成的数据就有741KB,这对于Web应用来说已经是很大的一个数值。开发者可以通过Topojson(https://github.com/mbostock/topojson/wiki)压缩数据。Topojson是GeoJSON的一个扩展,使用方式大致相同,这儿就不讲Topojson了,下图可以让开发者大致了解一下三种格式下数据的大小:

画图
有了数据,接下来就开始画图。D3画图都有一定的套路,首先需要确定把矢量图SVG放到那儿,以及图的大小
- var width = 960;
- var height = 580;
- var svg = d3.select("#geo_distribution").append("svg")
- .attr("width", width)
- .attr("height", height)
- .append("g")
- .attr("transform", "translate(0,0)");
接着,需要创建一个路径生成器,路径生成器可以接收一个投射函数,该投射函数存在的目的是把圆形地球上的经纬度投射到平面的Web界面上。D3自带了各种各样的投射函数(https://github.com/mbostock/d3/wiki/Geo-Projections),本例中使用的是墨卡托投影(http://baike.baidu.com/view/301981.htm?fr=aladdin)。
- var projection = d3.geo.mercator()
- .center([132, -28])
- .scale(850)
- .translate([width/2, height/2]);
- var path = d3.geo.path()
- .projection(projection);
然后,根据读取的GeoJSON数据绘制路径:
- var color = d3.scale.category20();
- var states = svg.append("svg:g")
- .attr("id", "states");
- d3.json("data/aus.states.json", function(error, root) {
- if (error)
- return console.error(error);
- states.selectAll("path")
- .data( root.features)
- .enter()
- .append("path")
- .attr("stroke","#000")//路径线颜色
- .attr("stroke-width",1)//路径线宽度
- .attr("fill", function(d,i){
- return color(i);//color函数可根据数据设置每个州板块的颜色,示例中使用的是D3自带的颜色函数。
- })
- .attr("d", path )
- .on("mouseover",function(d,i){//添加鼠标事件
- d3.select(this)
- .attr("fill","yellow");
- })
- .on("mouseout",function(d,i){
- d3.select(this)
- .attr("fill",color(i));
- });
- });
画到这儿一个澳大利亚的地图就是下面这个样子了:

加点佐料
画了地区之后,纯属个人乐趣,还想画点城市在上面,做法也是一样的, 首先获取Geo数据,还是可以从Natural Earth的地理数据中转换得到(注:转换数据时,开发者可以根据个人爱好过滤掉一些数据,比方说下面的命令中我过滤掉了规模上第四等级以后的小城市):
- ogr2ogr -f GeoJSON -where "ADM0_A3 = 'AUS' and SCALERANK <=4" aus.big.cities.json 10m_cultural/ne_10m_populated_places.shp
接着,把用于描述城市的小圆点和城市名字的SVG添加到底层SVG上:
- var circles = svg.append("svg:g")
- .attr("id", "circles");
- var texts = svg.append("svg:g")
- .attr("id", "texts");
然后,根据前面得到的数据在创建的SVG上画图
- d3.json("data/aus.cities.json", function(error, root) {
- circles.selectAll("circle")
- .data(root.features)
- .enter().
- append("svg:circle")
- .attr("cx", function(d){return projection([d.properties['LONGITUDE'],d.properties['LATITUDE']])[0];})//根据城市的经纬度投射确定圆点坐标
- .attr("cy",function(d){return projection([d.properties['LONGITUDE'],d.properties['LATITUDE']])[1];})
- .attr("r", 3)
- .attr('fill','#29FF57');
- texts.selectAll("text")
- .data(root.features)
- .enter()
- .append("svg:text")
- .text(function(d){return d.properties['NAME'];})
- .attr("x", function(d){
- return projection([ d.properties['LONGITUDE'],d.properties['LATITUDE']])[0];})
- .attr("y",function(d){
- return projection([d.properties['LONGITUDE'],d.properties['LATITUDE']])[1];
- })
- .attr('fill','#000')
- .attr('font-size','9px');
- });
最后得到的结果如下:

参考:
http://www.tnoda.com/blog/2013-12-07
https://github.com/mbostock/d3/wiki/Geo-Paths#path
使用D3 Geo模块画澳大利亚地图的更多相关文章
- nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录
geo指令使用ngx_http_geo_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_geo_module.ngx_http_geo_modu ...
- c语言贪吃蛇详解1.画出地图
c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...
- Nginx geo模块
geo 模块默认编译进nginx 可以通过--without-http_geo_module禁用 Syntax: geo [$address] $variable { ... } Default: — ...
- (转)nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录
nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录 原文:http://www.cnblogs.com/kevingrace/p/6165572.html Nginx的geo模块 ...
- nginx 变量相关的map模块与split_clients模块及geo模块和geoip模块及keepalive介绍
map 模块指令默认编译进nginx的 Syntax: map string $variable { ... } # 表示string匹配到{}里的值或变量赋值给$variable Default: ...
- nginx使用geo模块进行接口访问限制
背景需求: 对api接口 /api/inner 进行ip访问限制 # ip白名单geo $ip_list { default 0; 111.111.111.111 1; } server { list ...
- 使用SVGDeveloper画svg地图详细过程
使用步骤 1. 安装svg 2. 具体操作 1. 打开svg,点击file ,new,默认svg,点击ok 显示界面如下: 然后点击image 把鼠标放到代码下面的的桌面上,鼠标箭头会变成 ...
- echarts画中国地图并上色
任务是画一个中国地图,并在指定区域上颜色,学姐说用arcgis画,乖乖,4个g的安装文件,算了, 还是echarts大法好..如果想熟悉这个牛X的工具,请移步https://www.w3cschool ...
- D3.JS V4 绘制中国地图
参考:http://bl.ocks.org/almccon/fe445f1d6b177fd0946800a48aa59c71 http://blog.csdn.net/lzhlzz/article/d ...
随机推荐
- Android开发系列之adb常用命令
对于Android开发者来说,如果没有adb的帮助,那肯定就跟少了一只手那样别扭.其实笔者在刚刚学习Android开发的时候,也没有意识到adb的重要性.想想只要用IDE画出界面,然后实现后台的逻辑代 ...
- Linux笔记(六) - 压缩解压命令
(1)压缩文件( gz):gzip-d 解压只能压缩文件,不保留原文件例:gzip a.txt(2)解压文件( gz):gunzip 例:gunzip a.txt.gz(3)打包目录(tar):tar ...
- 使SSH不用输入密码
1. 自动ssh/scp方法== A为本地主机(即用于控制其他主机的机器) ;B为远程主机(即被控制的机器Server), 假如ip为192.168.60.110;A和B的系统都是Linux 在A上运 ...
- windows环境下使用git客户端、github和tortoisegit管理项目代码
一.为什么 为什么不用svn? svn是一个优秀的代码和版本管理工具,使用svn只需要搭建好svn中央仓库,配置本地svn客户端即可,自从google code关闭服务之后,互联网上已经没有非常好的公 ...
- bzoj1061--线性规划
线性规划裸题... 根据题目很容易可以得到线性规划方程(以样例为例): Min(2*x1+5*x2+2*x3) x1+ 0+ 0>=2 x1+x2+ 0>=3 0+x2+x3>=4 ...
- HTML css 格式布局
CSS(cascading style sheets,层叠样式表),作用是美化HTML网页. /*注释*/ 注释语法 2.1 样式表的基本概念 2.1.1样式表的分类 1.内联样式表 和HTML联 ...
- 双击startup.bat启动tomcat时闪退原因及解决方案
在启动免安装tomcat时,很容易遇到双击startup.bat,启动窗口闪退而tomcat服务未启动的状况. 具体原因:tomcat在启动时,需要读取环境变量和配置信息,如果缺少Java环境,即缺少 ...
- linux之sed的常用操作
Sed命令: sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(patter ...
- gRPC中Any类型的使用(Java和NodeJs端)
工作中要把原来Java服务端基于SpringMVC的服务改为使用gRPC直接调用.由于原Service的返回值为动态的Map类型,key值不确定,且value的类型不唯一,因此使用了protobuf ...
- Git本地操作相关介绍
本地使用git时遇到问题及解决方案总结: 1.git push origin master 后,终端上出现错误信息: push失败,原因多半是因为github上远程仓库中有Reademe.md文件 解 ...