[d3.js taipei meetup] 地理視覺化簡介 - 以資訊地圖應用為例
TRANSCRIPT
地理視覺化簡介 以資訊地圖應⽤用為例
Kuro Hsu @ Visual Thursday / Taipei D3.js Meetup2015.06.18
⾃自我介紹
• Kuro Hsu
• 前端⼯工程師• ⺫⽬目前任職永慶房仲集團
AGENDA
• 地理視覺化與資訊地圖簡介
• 資訊地圖案例
• Live Demo
空間資訊的視覺化• 以地點位置為主題
• 點圖• 航線圖
• 以地區統計為主題• 等值線圖• 等⾼高線圖• 熱圖
http://www.funtime.com.tw/blog/wp-content/uploads/2014/04/img_routemap_20140121_tw.gif
source: https://zh.wikipedia.org/wiki/%E6%B5%81%E5%9E%8B%E5%9B%BE
source: http://www.twgisonline.com/images/newshop/20091025225552.jpg
http://www.datapointed.net/visualizations/maps/distance-to-nearest-mcdonalds-sept-2010/
source: http://www.foundi.info/lab/market/
source: https://ckim7734.wordpress.com/2009/10/05/swine-flu-vaccine-still-has-a-long-way-to-go/
http://www.nytimes.com/interactive/2008/08/04/sports/olympics/20080804_MEDALCOUNT_MAP.html
Showcases: Visualization For Maps
http://www.morethanamap.com/demos/visualization/flights
http://www.morethanamap.com/demos/visualization/population
水慈善(CHARITY: WATER)
‧2006 年成立的非營利組織,期
許將安全乾淨的水資源帶到發展
中國家。
‧每建置一口泉井即透過 GPS 定
位標示在地圖上,利用照片、影
音告訴捐款者款項的用途,並開
放追蹤掘井的過程。
http://www.charitywater.org/projects/completed-projects/
賽豬公上太空計畫(TWLANDSAT)http://nspo.g0v.tw/
‧一個應用衛星圖的計畫
‧透過 NASA 的 Landsat 地理衛
星取得資料,可免費下載,但須
自行處理圖片。
‧符合 CreativeCommons by-nc-
sa 授權即可自由使用。
ZEIT ONLINEhttp://www.zeit.de/datenschutz/malte-spitz-vorratsdaten
‧德國新聞網站專題頁。
‧將行動電信業者收集到的資訊,
以視覺圖像化的方式,在
Google 地圖中標示出來。
‧在當時引發了電信業者收集資訊
與個人隱私的爭論。
TAXI TRAILShttp://www.taxitrails.se/en
‧集結了斯德哥爾摩計程車的
GPS 軌跡,運用這些資料結合
Google Maps 推出了觀光地
圖。
‧除了景點和餐廳資訊外,也可直
接在線上預約計程車。
TWEETING "HAPPY NEW YEAR" AROUND THE WORLD
http://twitter.github.io/interactive/newyear2014/
STRAVA GLOBAL HEATMAPhttp://labs.strava.com/heatmap/
‧透過 Strava App 記錄使用者慢
跑以及自行車路線。
‧網站結合了 Google Maps 將全
球所有熱門的慢跑和自行車路線
以 Heatmap 的方式標示。
‧提供選項調整地圖顏色、路線透
明度、慢跑或自行車路線。
WIND ANIMATIONhttp://esri.github.io/wind-js/
‧由 ESRI (美國環境系統研究所公
司) 製作的全球風向動態圖。
‧網站使用 HTML5 Canvas 繪圖
技術。
CRIMEMAP.INFO 犯罪地圖http://www.crimemap.info/
‧由澳洲昆士蘭洲警局提供的犯罪
資料,結合 Google Maps 製作
犯罪地圖,從地圖上可以查詢鄰
近的犯罪事件類型並得知目前解
決狀況。
TRULIA MAPShttp://www.trulia.com/local/
‧美國知名房地產情報網站,結
合地圖提供該地區犯罪資訊,
也結合了 GIS 計算通勤時
間,以及行情視覺化等資訊。
‧提供多種房地產資訊的圖像
化搭配 google 地圖顯示。
FOUNDI 房地資訊實驗室http://www.foundi.info/lab/
UNIFORM MAP 制服地圖http://uniform.wingzero.tw/
‧Uniform Map 提供網友完整
的制服資訊,圖片多以網友投
稿為主。
‧目前可選擇台灣,香港,馬來
西亞等地區
‧幾乎都是女生 (y)
永慶房仲網 - 地圖找房http://buy.yungching.com.tw/map/region/
‧永慶房仲網 - 結合地圖搜尋
您心目中的理想物件
‧隨心所欲在地圖上隨畫隨選
‧偷打工商服務之我們在徵人
http://goo.gl/819FwB
LIVE DEMOhttps://github.com/kurotanshi/VisualThursday_demo
Google Maps + D3
http://kuro.tw/posts/2015/05/20/added-to-the-google-map-images-d3-2
http://data.taipei/opendata/datalist/datasetMeta?oid=1d71c478-205f-42c5-8386-35f86d74fdd1
var overlay = new google.maps.OverlayView();
// load data d3.csv("...", function(data){ drawMap(data); });
function drawMap(data){
overlay.onAdd = function() { var layer = d3.select( this.getPanes().overlayMouseTarget ) .append("div") .attr("class", "stations");
overlay.draw = function() { // 處理資料及 SVG 元件 }
}; // 將 overlay 加到 google map overlay.setMap(map);
}
overlay.draw = function() {
var projection = this.getProjection();
var marker = layer.selectAll("svg") .data(d3.entries(mrtData)) .each(transform) .enter() .append("svg") .each(transform);
/* 中間略 */
// 透過 fromLatLngToDivPixel 將經緯度轉為網⾴頁上的座標 function transform(d) { d = new google.maps.LatLng(d.value.lat, d.value.lng); d = projection.fromLatLngToDivPixel(d); return
d3.select(this) .style("left", (d.x -‐ padding) + "px") .style("top", (d.y -‐ padding) + "px"); } }
http://licaschiou.github.io/TaipeiMrtPassengerCount/
利⽤用 D3 打造世界迷霧地圖
GPS: https://maps.google.com/locationhistory/
將下載好的 Kml 檔轉成 Geojson File
npm install -‐g togeojson
togeojson history.kml > history.json
<svg> <defs> <mask id="mask"> <rect x="0" y="0" width="400" height="400" fill="white" /> <!-‐-‐ 這是星狀遮罩 -‐-‐> <path d="M225 150 L175 250 L290 185 L160 185 L275 250 Z" stroke="black" stroke-‐width="50" fill="black" /> </mask> </defs> <rect x="0" y="0" width="400" height="400" fill="rgba(0,0,0, 1)" mask="url(#mask)">
</svg>
https://jsbin.com/hatate/
Svg Mask
Svg Mask
https://jsbin.com/hatate/
Douglas–Peucker Algorithm
‧道格拉斯-普克算法是將曲線近似表
示為一系列點,並減少點的數量的
一種算法。
‧簡單來說,就是將複雜曲線一系列
點簡化的一種演算法。
https://zh.wikipedia.org/wiki/%E9%81%93%E6%A0%BC%E6%8B%89%E6%96%AF-%E6%99%AE%E5%85%8B%E7%AE%97%E6%B3%95
// SVG Mask
var mask = defs.append("mask").attr("id", "mask");
mask.append("rect").attr({ x: 0, y: 0, width: 8000, height: 8000, fill: "rgba(255, 255, 255, 1)" });
// 地圖上的迷霧 var cover = svg.append("rect").attr({ x:0, y:0, width: 8000, height: 8000, fill: "rgba(90,90,90, 0.8)" });
var overlayProjection = this.getProjection();
// Google Projection var googleMapProjection = function (coordinates) { var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(coordinates); return [ pixelCoordinates.x + 4000, pixelCoordinates.y + 4000]; }
.SvgOverlay svg { position: absolute; top: -‐4000px; left: -‐4000px; width: 8000px; height: 8000px; }
overlay.draw = function () { svg.selectAll("path").remove();
mask.append("path") .attr({ "d": line( coords ), "stroke-‐width": 25 * Math.pow(2, map.getZoom() -‐ 14), "fill": "none", "stroke": "black", "stroke-‐linecap": "round", "stroke-‐linejoin": "round" });
cover.attr("mask", "url(#mask)"); };
D3 Voronoi Diagram - 尋找最近停⾞車場
http://data.taipei/opendata/datalist/datasetMeta?oid=d5c0656b-5250-4179-a491-c94daa56ef2c
‧平面上每一處,各自歸類於
最近的點
‧隱含著鄰近的資訊,所以「最
靠近」、「距離最短」之類
的問題,多半可以透過
Voronoi Diagram 解決。
Voronoi Diagram
http://www.csie.ntnu.edu.tw/~u91029/VoronoiDiagram.html
var overlayProjection = markerOverlay.getProjection();
var positions = []; pointdata.forEach(function(d, i) { positions.push(googleMapProjection(d.arr)); });
// Voronoi 圖 var polygons = d3.geom.voronoi(positions); var pathAttr = { "d": function(d, i) { return 'M' + polygons[i].join("L") + 'Z'; },
'stroke-‐width': 1, 'stroke': "#000", 'fill': function(d, i) { return "transparent"; } };
var path = svgoverlay.selectAll("path") .data(pointdata) .attr(pathAttr) .enter() .append("svg:path") .attr(pathAttr);
北市停⾞車場資訊熱圖
var locationCoords = [];
result.map(function(d){ var coords = twd97_to_latlng(d.tw97x, d.tw97y); result.coords = [coords.lat, coords.lng]; locationCoords.push(new google.maps.LatLng(coords.lat, coords.lng) ); });
function draw_heatmap(coords) { var pointArray = new google.maps.MVCArray(coords); heatmap = new google.maps.visualization.HeatmapLayer({ data: pointArray }); heatmap.setMap(map); }
draw_heatmap(locationCoords);
停⾞車場資訊綜合統計與分析 - 蜂巢圖
http://turfjs.org/
turf.hex-grid
http://turfjs.org/static/docs/module-turf_hex-grid.html
if( feature.getProperty('area_sum')){
var n = parseInt(feature.getProperty('area_sum'), 10); if( n > 100 ){ return { fillOpacity: 0.3, fillColor: 'green', strokeWeight: 1, strokeColor: '#333', strokeOpacity: 1 }; } else if ( n > 50 ) { return { fillOpacity: 0.3, fillColor: 'yellow', strokeWeight: 1, strokeColor: '#333', strokeOpacity: 1 }; } else if ( n > 20 ) { return { fillOpacity: 0.3, fillColor: 'orange', strokeWeight: 1, strokeColor: '#999', strokeOpacity: 1 }; } else { return { fillOpacity: 0.3, fillColor: 'red', strokeWeight: 1, strokeColor: '#999', strokeOpacity: 1 }; }
}
// 計算路徑總⻑⾧長度 turf.lineDistance(path, 'kilometers');
$('#range').on("change", function(){ var meter = this.value; $('.distance").text(meter);
// 計算位置 var along = turf.along(line, meter / 1000, 'kilometers');
var result = { "type": "FeatureCollection", "features": [path, along] };
// 移除原有資料,更新 map.data for (var i = 0; i < features.length; i++){ map.data.remove(features[i]); }
features = map.data.addGeoJson(result);
});
// 街景相關 function setStreetView(coords){ var stviewOptions = { // 座標 position: new google.maps.LatLng(coords[1], coords[0]),
// heading: ⾓角度 pov: { heading: 90, pitch: 0 } };
var stview = new google.maps.StreetViewPanorama( document.getElementById('map-‐stview'), stviewOptions); // StreetViewPanorama Handler // map.setStreetView(stview); }
THANKS!
• Kuro Hsu
• kurotanshi [at] gmail.com
• http://kuro.tw
• http://facebook.com/kurotanshi