D3.js - 地图绘製

D3 除了绘製图表外还可以拿来绘製地图,而这篇的目标是绘製一个世界地图,那就开始吧!

地图格式

绘製地图前我们要先了解一下会使用到的资料格式,比较常看见的会有 SHP、GeoJSON 与 TopoJSON,而其中 D3 可用的格式为 GeoJSON 与 TopoJSON,详细的就让我们往下看

Shapefile

ESRI Shapefile(shp),或简称 shapefile,是美国环境系统研究所公司(ESRI)开发的空间资料开放格式,目前该档案格式已经成为了地理资讯软体界的开放标準。
shapefile 档案用于描述几何体物件:点、折线与多边形。例如其可以储存井、河流、湖泊等空间物件的几何位置。除了几何位置,shp档案也可以储存这些空间物件的属性,例如河流的名字、城市的温度等等。

而 Shapefile 又有分为好几种格式,我们会用到的是副档名为 .shp 的格式,可以将其转换成 D3 可用的格式,也就是 GeoJSON 与 TopoJSON

GeoJSON

GeoJSON 是一种基于 JSON 的地理空间数据交换格式,它定义了几种类型 JSON 对象以及它们组合在一起的方法,以表示有关地理要素、属性和它们的空间範围的数据。

GeoJSON 同样是属于 JSON 的一种,只不过是对它的名称进行规範后,专门用于表示地理信息的格式,此格式为 D3 主要使用的格式

TopoJSON

TopoJSON 是 GeoJSON 的扩展,由 D3 的作者所发明,透过将共享边(arcs)整合的方法组成,消除了一些 GeoJSON 冗余的部分,使档案大小大幅缩小,缩小幅度约可达 80% 左右

格式转换

首先我们先找到提供 shp 的网站将档案下载下来,里面会有 Shapefile 的各种格式,我们需要的是副档名为 shp 的档案,再来就是将它转换成 GeoJSON 或是 TopoJSON 了

线上服务(shp 转 GeoJSON、TopoJSON)

线上转换可使用 mapshaper 的服务,它除了转换还可以预览,可以说是非常好用

将下载下来的档案 import 进去
mapshaper操作步骤一预览确认档案正确后,将档案 Export 并下载下来就完成啰
mapshaper操作步骤二

shapefile 套件(shp 转 GeoJSON)

首先安装 shapefile 这个套件,它可以帮我们将 .shp 转换成 GeoJSON,可以使用它的 API 或是直接使用终端机转换,我们这边使用终端机的方式

安装

$ npm install -g shapefile

转换

$ shp2json ne_110m_land.shp -o map.json<!-- 将 ne_110m_land.shp 转换成 map.json -->$ shp2json ne_110m_land.shp -o map.json --encoding big5<!-- 将 ne_110m_land.shp 转换成 map.json,使用 big5 编码 -->

topojson 套件(TopoJSON、GeoJSON 互相转换)

TopoJSON 无法直接于 D3 使用,所以作者也另外提供了套件,让我们将 TopoJSON 转换为 GeoJSON 的格式,安装一样可以使用 npm 或是 CDN 方式载入,有兴趣可以看看,这边就不做示範了

绘製地图

用上述方法得到 GeoJSON 资料后就可以开始绘製地图了,这边先介绍几个会使用到的方法~

d3.geoMercator:将地图以麦卡托投影法绘製center:设定地图中心点座标scale:设定地图缩放倍率d3.geoPath:将投影资料转换为 path 的路径
// 设定 svg 的宽高const map = d3  .select('.map')  .attr('width', 500)  .attr('height', 500);// 获取 ne_110m_land.json 的档案资讯 ( GeoJSON ),完成后执行 draw 函式fetch('./ne_110m_land.json')  .then(res => res.json())  .then(data => draw(data));function draw(mapData) {  // 设定投影中心点与缩放倍率  const projection = d3    .geoMercator()    .center([200, 10])    .scale(70);  // 将投影资料转换为路径  const path = d3.geoPath(projection);  // 绘製地图  map    .selectAll('path')    .data(mapData.geometries)    .enter()    .append('path')    .attr('d', path)    .attr('stroke', 'black')    .attr('stroke-width', '0.7')    .attr('fill', 'steelblue')    .on('mouseover', function() {      d3.select(this).attr('fill', '#007bff')    })    // 滑鼠碰到后改变颜色    .on('mouseleave',  function() {      d3.select(this).attr('fill', 'steelblue')    })    // 滑鼠离开将颜色变回}

世界地图成品

结语

绘製地图并不难,只要有地图的资料,并且把握好资料格式的转换,相信对大家来说是轻而易举的事情~


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章