iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 18
1
Modern Web

30天打造我的WebGIS系列 第 18

[Day 18] Turf.js:空間資料運算及分析

  • 分享至 

  • twitterImage
  •  

前言

今天要介紹turf.js,
前兩天的網球地圖完成了基本的地圖功能及版面,並在地圖上展示、查詢了GIS資料,今天想進一步對資料做空間資料分析,使用的是turf.js

turf.js是Mapbox公司提出用來處理空間資料分析的開源函式庫,打開turf.js的說明文件,可以看到其功能非常的多:

要處理空間資料的手段有很多,常見的方法是使用QGIS等軟體做資料處理,也可以使用其他程式語言的函式庫輔助或手刻,而turf.js是一個十分方便輕巧的工具,最棒的是可以用在webGIS中,client端空間資料處理

至於什麼是空間資料分析呢?主要像是空間資料幾何運算、內插、資料聚合等都算,廢話不多說,我們就先來實作幾個案例。

幾何運算-pointsWithinPolygon

範例目的:

產生隨機的POI,利用新北市polygon,切出新北市內的POI

說明:

首先,先new一個layer

var ramdomLayer = L.geoJson(null, {
  pointToLayer: function (feature, latlng) {
    return L.marker(latlng, {
      icon: L.icon({
        iconUrl: "./dist/assets/img/icon-black.png",
        iconSize: [36, 36],
        iconAnchor: [0, 18]
      }),
    });
  }
});

利用 turf.randomPoint 產生隨機點,設定隨機點的範圍在[121.41, 24.9, 121.8, 25.19] 方框中。

var ramdompts = turf.randomPoint(25, { bbox: [121.41, 24.9, 121.8, 25.19] });
//把成果放入圖層
ramdomLayer.addData(ramdompts);
ramdomLayer.addTo(map);

接著,放入新北市geojson

var ntp = L.geoJson(null);
$.getJSON("./dist/assets/data/ntp.geojson", function (data) {
  ntp.addData(data);
});

在沒有屬性欄位的狀態下,我們用幾何取出新北市範圍內的POI
那就使用turf.pointsWithinPolygon~

//ramdompts為前面產生的隨機點
//data為新北市geojson
var ptsWithin = turf.pointsWithinPolygon(ramdompts, data);
//成果為geojson points

ps.成果跟後面一起展示喔

空間分析-clustersKmeans

範例目的:

對新北市範圍的POI做距離分群

說明:

這邊使用的群聚(cluster)演算法是Kmeans,Kmeans是非監督式學習的分類演算法,
這個演算法要設定分群的數量,流程概述如下:
1.根據預先設定的目標群數n,隨機給n個點作為n群資料的群聚中心
2.資料中距離(空間距離)哪個群聚中心最近,就屬哪類
3.各群以平均值重新計算各群中心點
4.反覆1~3,直到中心點移動量低於設定值或是達到迭代次數而停止

利用turfclustersKmeans為資料作分群,設定分五類:

 var clustered_kmeans = turf.clustersKmeans(ptsWithin, { numberOfClusters: 5 });
 //結果是geojson points

幾何運算-找出Polygon的中心點與計算最鄰近的POI

範例目的:

找出新北市幾何中心及距離該點最近的poi

說明:

turf.js有很多幾何的計算,以下是計算Polygon中心點,及找群POI中距離這個中心點最近的一個,
直接看程式碼:

  //中心
  //data是新北市polygon geojson
  var center = turf.center(data);
  L.geoJson(center).addTo(map).bindPopup('這是新北幾何中心').openPopup();

最短距離:

  var nearest = turf.nearestPoint(center, ptsWithin);
  L.geoJson(center).addTo(map).bindPopup('這是距離新北中心最近的點').openPopup();

成果:
隨機給定POI(黑色),使用空間選取前
(ps.,另有不同icon顯示中心點及最近點。)

只顯示新北市內的poi,並依空間分佈分群(不同顏色為不同群)

後記

turf.js除了今天介紹的功能,還有很多是在webGIS常用的,例如buffer,intersect等等,很多GIS軟體工具提供的功能,turf.js都可以引用參考,非常方便,另外,turf.js相關介紹也可以參考Kuro大的youtube投影片喔^^。

明天會繼續介紹turf.js比較進階的空間分析功能,除了今天的基本運算外,希望能多觸及進階的分析方法!
今天的程式碼一樣放在github(day18的commit)。


上一篇
[Day 17] Leaflet.js: 加入資料及資料互動
下一篇
[Day 19] 使用Turf.js進行空間資料內插
系列文
30天打造我的WebGIS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Kuro Hsu
iT邦新手 1 級 ‧ 2018-01-09 02:02:28
Chimin iT邦新手 5 級 ‧ 2018-01-09 09:52:19 檢舉

大推
/images/emoticon/emoticon34.gif

我要留言

立即登入留言