iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
Modern Web

從原料到燃料,從資料到預料—資料駕馭網頁之理科的美學系列 第 16

D3JsDay16 It's map birth,It's from path—生成地圖

昨天介紹完關於Web地圖的相關知識之後今天我們要開始使用geojson的資料來繪製一個地圖首先我們到以下的網站下載shp檔案

Natural Earth

政府開放平台SHP

轉換格式工具

工具一 mapshaper

由於要繪製地圖的時候我們必須使用geojson的格式進行,在網路上得到的資源是屬於shapefile的格式,所以要先進行轉換成geojson

D3jeo官方API文件提到如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/20125095V8K9BXb9Av.png
D3的作者也進行了開源專案讓shp轉換成geojson有興趣者可以參考以下連結

D3作者開源專案轉換shapefile

這邊我們使用另一個方式線上進行轉換

首先進到mapshaper網站之後將從政府開放平台資料下載的檔案解壓縮之後的shp拖曳到畫面當中,按下import

https://ithelp.ithome.com.tw/upload/images/20211001/20125095l9rQJZVxc6.png

基本上會看到預覽圖如下

https://ithelp.ithome.com.tw/upload/images/20211001/20125095M7mhKTCNVq.png

另外可以點擊右上角的simplify做壓縮

https://ithelp.ithome.com.tw/upload/images/20211001/20125095TDAxdNjWeq.png

看到這個畫面之後按Apply

https://ithelp.ithome.com.tw/upload/images/20211001/201250954BIc2y8HNL.png

這時候畫面上方會多一個可以拉動0到100%的設定如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/20125095ezF9bVAUxK.png

你可以嘗試著拉動它這邊拉動至0%試試看如下圖,你就知道為什麼台灣會被說像番薯了

https://ithelp.ithome.com.tw/upload/images/20211001/20125095K7w1PDtEwp.png

這裡我們調整大概80%左右如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/201250955xlHV6VvfI.png

按下右上角的Export應該會看到如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/20125095PHyIl9rGhC.png

這裡我們選擇topoJson按下export之後應該就會開始下載了,做到這一步基本上你會得到一個json檔案

工具二 topojson

我們剛剛輸出的是topojson先前提到整體檔案會比geojson來的小,當我們後續要撰寫程式碼的時候也必須將topojson轉換成geojson這邊可以使用CDN的方式也就是載入連結的方式引入到腳本中或是npm安裝,我們使用CDN的方式
基本上打開下面的網頁滾動到下方把這行複製到你的網頁的head裡面就可以了。

https://ithelp.ithome.com.tw/upload/images/20211001/201250951nwxmbZ0sE.png

topojson轉換

感受程式碼

這一次換個解說方式,我們先行給予程式碼來讓各位感受一下,還不了解沒關係,等等將會講解重要函式的作用

const width = 800;
const height = 600;
const svg = d3.select("body").append("svg")
                .attr("width", width)
                .attr("height", height);
const  projection = d3.geoMercator();
console.log(typeof(projection));
const path = d3.geoPath()
.projection(projection);
const g = svg.append("g"); //先行撰寫一個g群組以便之後要插入path屬性
d3.json("World_Countries.json").then(function(topojsonData) {
    console.log(topojsonData);
    const convertedGeojson =topojson
            .feature(topojsonData, topojsonData.objects.World_Countries);
    const getGeoFeature = convertedGeojson.features;
g.selectAll("path")
    .data(
        getGeoFeature
            )
    .join("path")
    .attr("d", path)
    ;
})

Projection函式介紹

打開官方文件在安裝的那一欄就就有寫到要先宣告一個projection,然後使用geoPath路徑生成器來指定投影方式

這裡projection翻成中文是投影的意思

如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/20125095gMxW0Mz3oY.png

d3-geoInstalling

因此我們撰寫程式碼了解一下projection是什麼種類如下

const projection = d3.geoMercator();
console.log(typeof(projection));

這時候我們使用console.log(typeof(projection)),它會說是一個函式

官方文件程式碼如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/20125095ToIo2MvobG.png

官方API文件說明是將球面的多邊形幾何轉換成平面的多邊形幾何,簡單說就是先前地理知識將球影投影到平面上的意思

官方說明如下圖

https://ithelp.ithome.com.tw/upload/images/20211001/201250954zWP9whtuo.png

d3Projection官方說明

geopath函式介紹

我們先看官方API說明如下圖
https://ithelp.ithome.com.tw/upload/images/20211001/20125095crYm4EhZtn.png

  1. 需要知道的第一點是官方提到這裡是一個路徑產生器,可以指定投影方式,我們上一個部分介紹到的projection將會派上用場

  2. 需要知道的第二點是這一行說明Renders the given object, which may be any GeoJSON feature or geometry object:這邊意思是path函式要進行轉換的時候需要帶入的是GeoJSONfeature先記得這個說明之後會用到

d3的geojson官方API

topojson轉換函式

這個時候到官方API文件滑到下方點擊這個有寫到轉換topojsongeojson

topojson.feature- convert TopoJSON to GeoJSON.

因此我們要用的是這個函式

topojsonAPI文件

https://ithelp.ithome.com.tw/upload/images/20211001/20125095dRJ6qHTAHJ.png

官方有提到接受物件如果是GeometryCollection會將每個幾何圖形映射到Feature

https://ithelp.ithome.com.tw/upload/images/20211001/20125095V8IMVkv7cw.png

這時候我們撰寫程式碼,一樣使用先前提到的json載入資料方式來載入世界地圖,然後觀看一下console.log的內容

d3.json("World_Countries.json").then(function(topojsonData) {
    console.log(topojsonData);
})

https://ithelp.ithome.com.tw/upload/images/20211001/201250955rpa95Ozdn.png

如上圖打開console.logobjectsWorld_Countries那一欄顯示裡面的東西是GeometryCollection正是我們需要的東西。

所以我們宣告一個convertedGeojson儲存剛剛的東西,目前為止是將topojson轉換成geojson存入變數convertedgeojson

程式碼如下

d3.json("World_Countries.json")
.then(function(topojsonData) {
        console.log(topojsonData);
        const convertedGeojson =topojson
                .feature(topojsonData, topojsonData.objects.World_Countries);
          
  })

總結—組合程式碼

上面介紹完這三個函式的用途之後
我們回頭看剛剛所給各位感受的程式碼
具體步驟如下

  1. 宣告一個porjection變數來取得某個投影方法函式
  2. 將剛剛的投影方法指定至path路徑產生器
  3. 找尋topojson資料中的GeometryCollection物件來透過topojson函式轉換
  4. 使用path路徑函式將轉換後的geojson提取出features進行繪製

因此剛剛的程式碼
const projection = d3.geoMercator();表示宣告變數存放投影方式
const path = d3.geoPath() .projection(projection);表示宣告一個變數存放藉由某種投影方式的路徑產生器
const convertedGeojson =topojson.feature表示topojson的feature函式將GeometryCollection轉換至Geojson
const getGeoFeature = convertedGeojson.features;表示宣告getGeoFeature將Geojson的features提取出來當成之後要使用path函式的參數

最後的樣貌應該會如下圖
https://ithelp.ithome.com.tw/upload/images/20211001/20125095nTkdcSWHBj.png
明天再來教學如何美化這個地圖和顯示地圖相關區域

本日頁面如下

Gitpage


上一篇
D3JsDay15 了解WEB地圖學,先懂一點地理學—web地圖的科學
下一篇
D3JsDay17 Fill the color,Zoom in on center—地圖各項操作及填色
系列文
從原料到燃料,從資料到預料—資料駕馭網頁之理科的美學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言