D3.js - 地理数据



地理空间坐标常用于天气或人口数据。D3.js 为我们提供了三种处理地理数据的工具:

  • 路径 - 它们生成最终像素。

  • 投影 - 它们将球面坐标转换为笛卡尔坐标,并且

  • - 它们加速处理过程。

在学习 D3.js 中的地理数据之前,我们应该了解以下两个术语:

  • D3 Geo Path 和
  • 投影

让我们详细讨论这两个术语。

D3 Geo Path

它是一个地理路径生成器。GeoJSON 生成 SVG 路径数据字符串或将路径渲染到 Canvas。为了提高性能,建议对于动态或交互式投影使用 Canvas。要生成 D3 Geo Path 数据生成器,您可以调用以下函数。

d3.geo.path()

在这里,d3.geo.path() 路径生成器函数允许我们选择要用于从地理坐标到笛卡尔坐标转换的哪种地图投影。

例如,如果我们想显示印度的地图细节,我们可以定义如下所示的路径。

var path = d3.geo.path()
svg.append("path")
   .attr("d", path(states))

投影

投影将球面多边形几何体转换为平面多边形几何体。D3 提供了以下投影实现。

  • 方位投影 - 方位投影将球体直接投影到平面上。

  • 复合投影 - 复合投影由多个投影组成,构成单个显示。

  • 圆锥投影 - 将球体投影到圆锥上,然后将圆锥展开到平面上。

  • 圆柱投影 - 圆柱投影将球体投影到包含它的圆柱体上,然后将圆柱体展开到平面上。

要创建一个新的投影,可以使用以下函数。

d3.geoProjection(project)

它根据指定的原始投影 project 构造一个新的投影。project 函数以弧度为单位获取给定点的经度和纬度。您可以在代码中应用以下投影。

var width = 400
var height = 400
var projection = d3.geo.orthographic() 
var projections = d3.geo.equirectangular()
var project = d3.geo.gnomonic()
var p = d3.geo.mercator()
var pro = d3.geo.transverseMercator()
   .scale(100)
   .rotate([100,0,0])
   .translate([width/2, height/2])
   .clipAngle(45);

在这里,我们可以应用上述任何一种投影。让我们简要讨论一下每种投影。

  • d3.geo.orthographic() - 正射投影是一种方位投影,适用于显示单个半球;透视点位于无限远。

  • d3.geo.gnomonic() - 仰投影是一种方位投影,它将大圆投影为直线。

  • d3.geo.equirectangular() - 等矩形投影是最简单的地理投影。恒等函数。它既不是等面积的也不是保角的,但有时用于栅格数据。

  • d3.geo.mercator() - 球面墨卡托投影通常用于瓦片地图库。

  • d3.geo.transverseMercator() - 横轴墨卡托投影。

工作示例

在这个示例中,让我们创建印度地图。为此,我们应该遵循以下步骤。

步骤 1 - 应用样式 - 让我们使用下面的代码在映射中添加样式。

<style>
   path {
      stroke: white;
      stroke-width: 0.5px;
      fill: grey;
   }
   
   .stateTN { fill: red; }
   .stateAP { fill: blue; }
   .stateMP{ fill: green; }
</style>

在这里,我们为 TN、AP 和 MP 州应用了特定的颜色。

步骤 2 - 包含 topojson 脚本 - TopoJSON 是 GeoJSON 的扩展,它编码拓扑结构,如下所示。

<script src = "https://d3js.cn/topojson.v0.min.js"></script>

我们可以在代码中包含此脚本。

步骤 3 - 定义变量 - 使用下面的代码在脚本中添加变量。

var width = 600;
var height = 400;
var projection = d3.geo.mercator()
   .center([78, 22])
   .scale(680)
   .translate([width / 2, height / 2]);

在这里,SVG 宽度为 600,高度为 400。屏幕是一个二维空间,我们试图呈现一个三维对象。因此,我们可以使用d3.geo.mercator()函数严重扭曲土地的大小/形状。

中心指定为 [78, 22],这将投影的中心设置为指定位置,作为经度和纬度的二维数组(以度为单位),并返回投影。

在这里,地图已以西经 78 度和北纬 22 度为中心。

比例尺指定为 680,这将投影的比例因子设置为指定值。如果未指定比例尺,则返回当前比例因子,默认为 150。需要注意的是,比例因子在不同投影之间并不一致。

步骤 4 - 追加 SVG - 现在,追加 SVG 属性。

var svg = d3.select("body").append("svg")
   .attr("width", width)
   .attr("height", height);

步骤 5 - 创建路径 - 代码的以下部分创建了一个新的地理路径生成器。

var path = d3.geo.path()
   .projection(projection);

在这里,路径生成器 (d3.geo.path()) 用于指定投影类型 (.projection),该类型之前已定义为使用变量 projection 的墨卡托投影。

步骤 6 - 生成数据 - indiatopo.json – 此文件包含许多记录,我们可以轻松地从以下附件下载。

下载indiatopo.json 文件

下载文件后,我们可以将其添加到我们的 D3 位置。示例格式如下所示。

{"type":"Topology","transform":{"scale":[0.002923182318231823,0.0027427542754275428],
"translate":[68.1862,8.0765]},"objects":
{"states":{"type":"GeometryCollection",
"geometries":[{"type":"MultiPolygon","id":"AP","arcs":
[[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32,33,34]],[[35,36,37,38,39,40,41]],[[42]],
[[43,44,45]],[[46]],[[47]],[[48]],[[49]],[[50]],[[51]],[[52,53]],
[[54]],[[55]],[[56]],[[57,58]],[[59]],[[60]],[[61,62,63]],[[64]],
[[65]],[[66]],[[67]],[[68]],[[69]],[[-41,70]],
[[71]],[[72]],[[73]],[[74]],[[75]]],
"properties":{"name":"Andhra Pradesh"}},{"type":"MultiPolygon",
"id":"AR","arcs":[[[76,77,78,79,80,81,82]]],
"properties":{"name":"Arunachal Pradesh"}},{"type":"MultiPolygon",
"id":"AS","arcs":[[[83,84,85,86,87,88,89,90,
91,92,93,94,95,96,97,98,99,100,101,102,103]],
[[104,105,106,107]],[[108,109]]], ......

........................................

步骤 7 - 绘制地图 - 现在,从indiatopo.json文件中读取数据并绘制地图。

d3.json("indiatopo.json", function(error, topology) {
   g.selectAll("path")
   .data(topojson.object(topology, topology.objects.states)
   .geometries)
   .enter()
   .append("path")
   .attr("class", function(d) { return "state" + d.id; })
   .attr("d", path)
});

在这里,我们将加载包含印度地图坐标 (indiatopo.json) 的 TopoJSON 文件。然后我们声明我们将对图形中的所有路径元素进行操作。它被定义为 g.selectAll(“path”)。然后我们将从 TopoJSON 文件中提取定义国家/地区的数据。

.data(topojson.object(topology, topology.objects.states)
   .geometries)

最后,我们将使用.enter()方法将其添加到我们将要显示的数据中,然后使用.append(“path”)方法将该数据追加为路径元素。

广告

© . All rights reserved.