完美地图:使用 D3.js 制作精美的 Web 地图

已发表: 2022-03-11

Data Driven Documents,或 D3.js,是“一个基于数据操作文档的 JavaScript 库”。 或者更简单地说,D3.js 是一个数据可视化库。 它是由 Mike Bostock 开发的,旨在弥合静态数据显示与交互式和动画数据可视化之间的差距。

D3 是一个功能强大的库,具有大量用途。 在本教程中,我将讨论 D3 的一个特别引人注目的应用:地图制作。 我们将讨论构建有用且信息丰富的 web 地图的常见挑战,并展示在每种情况下,D3.js 如何为有能力的 JavaScript 开发人员提供使地图看起来和感觉漂亮所需的一切。

D3.js 是做什么用的?

D3.js 可以将任意数据绑定到文档对象模型 (DOM),然后通过使用 JavaScript、CSS、HTML 和 SVG,对由该数据驱动的文档进行转换。 结果可以是简单的 HTML 输出,也可以是具有动态行为(如动画、过渡和交互)的交互式 SVG 图表。 所有的数据转换和渲染都是在客户端的浏览器中完成的。

在最简单的情况下,D3.js 可用于操作 DOM。 这是一个简单的示例,其中 D3.js 用于将段落元素添加到空文档正文中,并带有“Hello World”文本:

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 Hello World</title> <script src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <script type="text/javascript"> d3.select("body").append("p").text("Hello World"); </script> </body> </html>

然而,D3.js 的优势在于它的数据可视化能力。 例如,它可用于创建图表。 它可用于创建动画图表。 它甚至可以用于集成和动画不同的连接图表。

D3 用于 Web 地图和地理数据可视化

但是 D3.js 不仅可以用于 DOM 操作,也可以用于绘制图表。 D3.js 在处理地理信息方面非常强大。 操作和呈现地理数据可能非常棘手,但使用 D3.js 构建地图非常简单。

这是一个 D3.js 示例,它将根据以 JSON 兼容数据格式存储的数据绘制世界地图。 您只需要定义地图的大小和要使用的地理投影(稍后会详细介绍),定义一个 SVG 元素,将其附加到 DOM,并使用 JSON 加载地图数据。 地图样式是通过 CSS 完成的。

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 World Map</title> <style> path { stroke: white; stroke-width: 0.5px; fill: black; } </style> <script src="http://d3js.org/d3.v3.min.js"></script> <script src="http://d3js.org/topojson.v0.min.js"></script> </head> <body> <script type="text/javascript"> var width = 900; var height = 600; var projection = d3.geo.mercator(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var path = d3.geo.path() .projection(projection); var g = svg.append("g"); d3.json("world-110m2.json", function(error, topology) { g.selectAll("path") .data(topojson.object(topology, topology.objects.countries) .geometries) .enter() .append("path") .attr("d", path) }); </script> </body> </html>
相关:迈向可更新的 D3.js 图表

D3 的地理数据

对于本 D3.js 教程,请记住,地图构建最适合 JSON 格式的数据,尤其是 GeoJSON 和 TopoJSON 规范。

GeoJSON 是“一种用于编码各种地理数据结构的格式”。 它旨在表示离散的几何对象,这些对象被分组为名称/值对的特征集合。

TopoJSON 是 GeoJSON 的扩展,它可以对拓扑进行编码,其中几何“从称为弧的共享线段拼接在一起”。 TopoJSON 通过存储地理特征之间的关系信息而不仅仅是空间信息来消除冗余。 因此,几何图形在几何图形共享特征的情况下更加紧凑和组合。 这导致典型的 TopoJSON 文件比其 GeoJSON 等效文件小 80%。

因此,例如,给定一张地图,其中几个国家相互接壤,边界的共享部分将在 GeoJSON 中存储两次,一次用于边界两侧的每个国家。 在 TopoJSON 中,它将只有一行。

地图库:谷歌地图和 Leaflet.js

今天,最流行的地图库是谷歌地图和传单。 它们旨在快速轻松地在网络上获取“滑地图”。 “Slippy maps”是一个术语,指的是现代 JavaScript 驱动的 web 地图,它允许在地图上进行缩放和平移。

Leaflet 是 Google 地图的绝佳替代品。 它是一个开源 JavaScript 库,旨在制作适合移动设备的交互式地图,并考虑到简单性、性能和可用性。 Leaflet 在利用互联网上可用的大量基于栅格的地图时处于最佳状态,并带来了使用平铺地图及其演示功能的简单性。

当与 D3.js 的数据操作功能结合使用时,Leaflet 可以非常成功地使用,并且可以将 D3.js 用于基于矢量的图形。 将它们结合在一起可以在两个库中发挥出最好的效果。

谷歌地图更难与 D3.js 结合,因为谷歌地图不是开源的。 可以同时使用 Google Maps 和 D3,但这主要限于在 Google Maps 背景地图上使用 D3.js 覆盖数据。 如果没有黑客攻击,更深层次的集成是不可能的。

投影 - 超越球形墨卡托

如何将 3 维球形地球的地图投影到 2 维表面上的问题是一个古老而复杂的问题。 为地图选择最佳投影是每个 web 地图的重要决定。

在我们上面的简单世界地图 D3.js 教程中,我们通过调用d3.geo.mercator()来使用球形墨卡托投影坐标系。 此投影也称为 Web Mercator。 谷歌在推出谷歌地图时推广了这种投影。 后来,其他网络服务也采用了投影,即 OpenStreetMap、Bing Maps、Here Maps 和 MapQuest。 这使得 Spherical Mercator 成为在线滑图的非常流行的投影。

所有映射库都支持开箱即用的球形墨卡托投影。 如果您想使用其他投影,则需要使用例如 Proj4js 库,它可以进行从一个坐标系到另一个坐标系的任何转换。 对于 Leaflet,有一个 Proj4Leaflet 插件。 就谷歌地图而言,什么都没有。

D3.js 将制图投影提升到一个全新的水平,内置支持许多不同的地理投影。 D3.js 将地理投影建模为完整的几何变换,这意味着当直线投影到曲线时,D3.js 应用可配置的自适应重采样来细分线并消除投影伪影。 Extended Geographic Projections D3 插件使支持的投影数量超过 40 个。甚至可以使用d3.geo.projectiond3.geo.projectionMutator创建一个全新的自定义投影。

栅格地图

如前所述,D3.js 的主要优势之一是处理矢量数据。 要使用栅格数据,可以选择将 D3.js 与 Leaflet 结合使用。 但也有一个选项可以使用 d3.geo.tile 仅使用 D3.js 来创建滑动地图。 即使仅使用 D3.js,人们也可以使用栅格地图做出令人惊奇的事情。

即时矢量操作

经典制图的最大挑战之一是地图泛化。 您希望拥有尽可能详细的几何图形,但这些数据需要适应显示地图的比例。 数据分辨率太高会增加下载时间并减慢渲染速度,而分辨率太低会破坏细节和拓扑关系。 使用矢量数据的易滑地图可能会遇到地图泛化的大问题。

一种选择是预先进行地图泛化:拥有不同分辨率的不同数据集,然后针对当前选择的比例显示适当的数据集。 但这会增加数据集,使数据维护复杂化,并且容易出错。 然而,大多数映射库仅限于此选项。

更好的解决方案是动态进行地图泛化。 D3.js 又来了,它具有强大的数据处理功能。 D3.js 允许在浏览器中进行行简化。

我想要更多!

D3.js 不易掌握,学习曲线陡峭。 需要熟悉很多技术,即 JavaScript 对象、jQuery 链式语法、SVG 和 CSS,当然还有 D3 的 API。 最重要的是,需要有一点设计技巧才能最终创造出漂亮的图形。 幸运的是,D3.js 有一个很大的社区,有很多资源可供人们挖掘。 这些教程是学习 D3 的一个很好的起点。

如果您喜欢通过查看示例来学习,Mike Bostock 在他的网页上分享了 600 多个 D3.js 示例。 所有 D3.js 示例都有用于版本控制的 git 存储库,并且是可分叉、可克隆和可注释的。

如果您使用 CartoDB,您会很高兴听到 CartoDB 让 D3 地图变得轻而易举。

最后,为了一点奖励,这是我最喜欢的例子之一,展示了 D3 的惊人能力:

  • earth,一个使用 D3.js 制作的全球动画 3D 风图。 Earth 是全球天气状况的可视化,基于国家环境预测中心、NOAA / 国家气象局的超级计算机做出的天气预报并转换为 JSON。 您可以自定义显示的数据,例如风速读数的高度、更改叠加数据,甚至更改地球投影。
相关:针对 Web 开发人员的最佳在线制图工具调查:路线图的路线图