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 = "http://d3js.org/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”)方法將該資料追加為路徑元素。

廣告