D3 让地图变得简单

发布日期:2026-07-09 05:07:03   来源 : 杭州电子商务研究院    浏览量 :2
杭州电子商务研究院 发布日期:2026-07-09 05:07:03  
2

介绍

D3 是一个功能强大且灵活的 JavaScript 可视化库,其可视化效果不仅限于条形图和饼图。地理空间数据通常以地图形式呈现。D3 提供了完整的 API,用于在线可视化中生成、显示和与地理空间数据交互。本指南将介绍如何使用 D3 呈现在线地图。

成分

要使用 D3 中的地图,您需要了解三个概念:

  • GeoJSON
  • 预测
  • 生成器

如果您一直在使用 D3,那么您会遇到用于制作形状的生成器。事实证明,D3 使用的生成器是形状生成器。它们是一种特殊的形状生成器,可将 GeoJSON 数据转换为 SVG 形状。但什么是 GeoJSON?

GeoJSON

您可能知道 JSON 是什么。您可能知道“Geo”意味着什么。因此,GeoJSON 是用 JSON 表示地理数据的标准也就不足为奇了。从 GeoJSON 开始,D3 可以创建表示地图的形状。有很多地方可以获取 GeoJSON 数据。最简单的方法之一是自己在 https://geojson.io 上生成它。

这个简单的界面可让您根据地图上绘制的形状生成 GeoJSON 数据。为了演示,请放大美国犹他州。

我选择犹他州有两个原因。首先,它是 Pluralsight 的所在地;其次,它的边界是直线,很容易绘制。现在,使用线条工具绘制该州的轮廓。要完成形状,请再次单击第一个点。在下图中,我从左上角开始,逆时针旋转。

完成的线称为特征,并存储在GeoJSON 中的features数组中。绘制线条时,坐标存储在 GeoJSON 中特征的coordinates键中。在properties键中,您可以添加特征的元数据,例如name

Pluralsight 位于犹他州法明顿,就在盐湖城以北。放大到盐湖城(大盐湖东南)。您会在 15 号州际公路上看到法明顿。

使用标记工具在 Farmington 上放置标记并向 GeoJSON 添加另一个特征。

添加标识新特征的名称后,将 GeoJSON 保存到文件中。

预测

投影是一种函数,它获取 GeoJSON 文件中的纬度和经度坐标,并将其转换为 D3 可用于绘制形状的 xy 坐标。如果这听起来很难,那是因为它确实很难,但 D3 提供了许多函数来为您执行投影。

例如,墨卡托投影经常用于地图,因为恒定路径始终是直线。以下是使用墨卡托投影的犹他州 GeoJSON 的样子。

投影功能在d3 npm 包中可用

      import * as d3 from 'd3';

let projection = d3.geoMercator();
    

如果切换到等圆锥投影,形状会变形。但特征之间的相对面积是恒定的。

创建它的代码与前面的示例类似。

      let projection = d3.geoConicEqualArea();
    

D3 中有大量投影。完整列表可从在线文档中获取。

生成器

生成器将使用 GeoJSON 中的特征根据投影创建形状。

      d3.json("../data/utah.geojson").then(geodata => {
  let projection = d3.geoConicEqualArea()
    .fitSize([360, 480], geodata);
  let generator = d3.geoPath().projection(projection);
  d3.select("g.map")
    .selectAll("path")
    .data(geodata.features)
    .join("path")
    .attr("d", generator)
    .attr('stroke', '#000')
    .attr('fill', '#fff')
});
    

此代码生成了上一个示例。使用json函数读取 GeoJSON 数据。它还用于调整投影的几何形状,使其适合某个区域。使用geoPath方法创建生成器,并将投影应用于生成器。然后,您可以通过选择元素、传递 GeoJSON 中的特征并使用生成器将点的坐标提供给d属性来让 D3 创建地图填充描边属性是装饰性的。

命中测试

为了获得更准确的地图,网上有很多 GeoJSON 来源。这是从 Github 上的 PublicaMundi 存储库中的 GeoJSON 文件生成的美国地图。

地图可以交互。假设你想检查鼠标是否在州界内点击。获取鼠标点击的坐标很容易。

      d3.select('g.map')
  .on('mousedown', function() {
    console.log(d3.mouse(this));
  });
    

d3.mouse方法将返回相对于地图元素的 xy 坐标。问题是您可能需要纬度和经度。projection 函数将把 xy 坐标转换为纬度和经度。在 project 上调用invert将反转该过程。

      d3.select('g.map')
  .on('mousedown', function() {
    console.log(projection.invert(d3.mouse(this)));
  });
    

有了鼠标单击的经纬度,您现在需要获取州的边界并检查鼠标坐标是否在边界内。与地理空间分析中的许多任务一样,这很困难。但 D3 为您提供了一个 API 来简化这一过程。首先,您需要获取特征本身。特征只是对象,每个特征都有一个与州名称相对应的name属性。

      var feature_utah = geodata.features.find(
	f => f.properties.name === 'Utah'
);
    

要执行命中测试,请使用geoContains函数并向其传递特征和坐标。如果坐标在特征内,它将返回布尔值 true。

      console.log(d3.geoContains(feature_utah, coords));
    

在鼠标单击的位置生成一个圆圈也很容易。geoCircle方法将在指定坐标处生成一个圆形。

      var circle = d3.geoCircle()
	.center(coords)
	.radius(0.5);
    

圆圈代表一个 GeoJSON 对象,传递给生成器时将转换为 SVG路径字符串。该 SVG 可以附加到地图路径中。

      d3.select('g.map')
	.append('path')
	.attr('d', generator(circle()));
    

结论

本指南向您展示了如何使用 GeoJSON 通过 D3 在 JavaScript 中呈现在线地图。D3 API 提供了对象和方法来处理复杂的地理空间分析工作。如您所见,创建地理空间可视化的部分挑战在于获取准确的地图数据。网上有很多存储库和数据库,您可以从中获取 GeoJSON 数据。您还可以将其他格式(包括 Shapefile)转换为 GeoJSON。

您还了解了投影如何允许您在 2d 坐标和纬度与经度之间进行转换。这使得创建交互式地理空间可视化成为可能。您了解了如何检查某个点是否包含在 GeoJSON 特征中,以及如何通过生成 GeoJSON 对象并将其添加到 SVG 路径来向地图添加形状。

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据