昨天介紹完關於Web地圖的相關知識之後今天我們要開始使用geojson的資料來繪製一個地圖首先我們到以下的網站下載shp檔案
由於要繪製地圖的時候我們必須使用geojson的格式進行,在網路上得到的資源是屬於shapefile的格式,所以要先進行轉換成geojson
D3jeo官方API文件提到如下圖
D3的作者也進行了開源專案讓shp轉換成geojson有興趣者可以參考以下連結
這邊我們使用另一個方式線上進行轉換
首先進到mapshaper網站之後將從政府開放平台資料下載的檔案解壓縮之後的shp拖曳到畫面當中,按下import
基本上會看到預覽圖如下
另外可以點擊右上角的simplify做壓縮
看到這個畫面之後按Apply
這時候畫面上方會多一個可以拉動0到100%的設定如下圖
你可以嘗試著拉動它這邊拉動至0%試試看如下圖,你就知道為什麼台灣會被說像番薯了
這裡我們調整大概80%左右如下圖
按下右上角的Export應該會看到如下圖
這裡我們選擇topoJson按下export之後應該就會開始下載了,做到這一步基本上你會得到一個json檔案
我們剛剛輸出的是topojson先前提到整體檔案會比geojson來的小,當我們後續要撰寫程式碼的時候也必須將topojson轉換成geojson這邊可以使用CDN的方式也就是載入連結的方式引入到腳本中或是npm安裝,我們使用CDN的方式
基本上打開下面的網頁滾動到下方把這行複製到你的網頁的head
裡面就可以了。
這一次換個解說方式,我們先行給予程式碼來讓各位感受一下,還不了解沒關係,等等將會講解重要函式的作用
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,然後使用geoPath路徑生成器來指定投影方式
這裡projection翻成中文是投影的意思
如下圖
因此我們撰寫程式碼了解一下projection是什麼種類如下
const projection = d3.geoMercator();
console.log(typeof(projection));
這時候我們使用console.log(typeof(projection))
,它會說是一個函式
官方文件程式碼如下圖
官方API文件說明是將球面的多邊形幾何轉換成平面的多邊形幾何,簡單說就是先前地理知識將球影投影到平面上的意思
官方說明如下圖
我們先看官方API說明如下圖
需要知道的第一點是官方提到這裡是一個路徑產生器,可以指定投影方式,我們上一個部分介紹到的projection將會派上用場
需要知道的第二點是這一行說明Renders the given object, which may be any GeoJSON feature or geometry object:這邊意思是path函式
要進行轉換的時候需要帶入的是GeoJSON的feature先記得這個說明之後會用到
這個時候到官方API文件滑到下方點擊這個有寫到轉換topojson到geojson
topojson.feature- convert TopoJSON to GeoJSON.
因此我們要用的是這個函式
官方有提到接受物件如果是GeometryCollection會將每個幾何圖形映射到Feature
這時候我們撰寫程式碼,一樣使用先前提到的json載入資料方式來載入世界地圖,然後觀看一下console.log
的內容
d3.json("World_Countries.json").then(function(topojsonData) {
console.log(topojsonData);
})
如上圖打開console.log
看objects的World_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);
})
上面介紹完這三個函式的用途之後
我們回頭看剛剛所給各位感受的程式碼
具體步驟如下
topojson函式
轉換path
路徑函式將轉換後的geojson提取出features進行繪製因此剛剛的程式碼const projection = d3.geoMercator();
表示宣告變數存放投影方式const path = d3.geoPath() .projection(projection);
表示宣告一個變數存放藉由某種投影方式的路徑產生器const convertedGeojson =topojson.feature
表示topojson的feature函式將GeometryCollection轉換至Geojsonconst getGeoFeature = convertedGeojson.features;
表示宣告getGeoFeature將Geojson的features提取出來當成之後要使用path函式
的參數
最後的樣貌應該會如下圖
明天再來教學如何美化這個地圖和顯示地圖相關區域
本日頁面如下