D3.js - 地理位置

地理空間座標通常用於天氣或人口資料。D3.js 為我們提供了三種地理資料工具 -

  • Paths- 它們產生最終畫素。

  • Projections- 它們將球體座標轉換為笛卡爾座標

  • Stream - 他們加快了速度。

在瞭解 D3.js 中的地理位置之前,我們應該瞭解以下兩個術語 -

  • D3 地理路徑
  • 投影

讓我們詳細討論這兩個術語。

D3 地理路徑

它是一個地理路徑生成器。GeoJSON 生成 SVG 路徑資料字串或呈現 Canvas 的路徑。建議使用 Canvas 進行動態或互動式投影以提高效能。要生成 D3 地理路徑資料生成器,你可以呼叫以下函式。

d3.geo.path()

這裡, d3.geo.path() 路徑生成器函式允許我們選擇我們想要用於從地理座標到笛卡爾座標的平移的地圖投影。

例如,如果我們想要顯示印度的地圖細節,我們可以定義如下所示的路徑。

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

投影

投影將球面多邊形幾何轉換為平面多邊形幾何。D3 提供以下投影實現。

  • Azimuthal - Azimuthal 投影將球體直接投射到平面上。

  • Composite - Composite 由多個投影組成,這些投影組成一個顯示。

  • Conic - 將球體投影到圓錐體上,然後將圓錐體展開到平面上。

  • Cylindrical - 圓柱形投影將球體投射到容納圓柱體上,然後將圓柱體展開到平面上。

要建立新投影,可以使用以下功能。

d3.geoProjection(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() - gnomonic 投影是一個方位投影,將大圓投影為直線。

  • d3.geo.equirectangular() - 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),之前使用變數投影定義為墨卡託投影。

步驟 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) 方法將該資料作為路徑元素追加。