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


<<:  初学者跪着学JavaScript Day16 : 阵列Array 迭代的小小秘密

>>:  [Day19]-档案读取与写入

远端连线 GCE 的 MySQL 资料库

情境 每次查询API执行後都得进vm下MySQL指令用CLI看成果? 身为免费仔推荐一个好用的 da...

DAY22 类神经网路之架设与训练

前面我们介绍了影像辨识的资料前处理方法,今天就要开始教大家架设一个神经网路,并将资料丢入来看看实际的...

D22-(9/22)-长荣航(2618)-差了一个字,就是涨倍和涨十倍的差别

注:发文日和截图的日期不一定是同一天,所以价格计算上和当日不同,是很正常的。 声明:这一系列文章并无...

Day14. 时光时光慢些吧,让世界慢下来 - TimeScale

昨天看到运镜这词,大家是不是会想到拍电影呢?今天的主题也是跟电影有关的(?),大家看电影的时候,遇到...

Day15:Channel 的第一堂课

在前面的文章中,我们介绍了 coroutine 的基本原理,如何使用 launch 、 async ...