D3.jsとThree.jsを使って、日本地図を3D的に描画してみました。
D3.js : http://d3js.org/
Three.js : http://threejs.org/
3Dといっても、日本地図は平べったいままです。
D3.jsで日本地図をHTML5のCanvasに描画して、CanvasをThree.jsの平面オブジェクトに貼り付けて描画しています。
ここからデータをどのように乗っけていけるか、さらに研究ですね。
var renderer, scene, camera, light, canvas;
function init(){
$("#target").css("width", window.innerWidth).css("height", window.innerHeight);
init3DMap("target");
initPanel();
}
function init3DMap(targetId){
var target = document.getElementById(targetId);
var mapSize = (target.clientWidth < target.clientHeight ? target.clientWidth : target.clientHeight);
// init three
renderer = new THREE.WebGLRenderer();
if (!renderer) console.log("three.js init error");
renderer.setSize(target.clientWidth, target.clientHeight);
target.appendChild(renderer.domElement);
renderer.setClearColor(0x000000, 1.0);
scene = new THREE.Scene();
// init camera
camera = new THREE.PerspectiveCamera(45, target.clientWidth / target.clientHeight, 1, 10000);
// init canvas
var projection, path, zoom, g;
d3.json("geodata/japan/topojson/japan.topojson", function(error, json){ // d3 topojson data load
if (error) return console.error(error);
canvas = document.createElement("canvas") // create canvas element
var ctx = d3.select(canvas)
.attr("width", mapSize)
.attr("height", mapSize)
.node()
.getContext("2d");
projection = d3.geo.mercator()
.center(d3.geo.centroid(topojson.feature(json, json.objects.japan)))
.translate([mapSize / 2, mapSize / 2])
.scale(1200);
path = d3.geo.path().projection(projection).context(ctx);
var features = topojson.feature(json, json.objects.japan).features;
var renderCanvas = function(){ // init canvas rendering
var start = new Date();
ctx.clearRect(0, 0, mapSize, mapSize);
ctx.fillStyle = "#3cb371";
for(var i = 0; i < features.length; i++){
ctx.beginPath();
path(features[i]);
ctx.fill();
ctx.closePath();
}
var end = new Date();
$("#canvasRenderingTime font").html(end.getTime() - start.getTime() + " ms");
requestAnimationFrame(renderCanvas);
}
renderCanvas();
// init three object
var texture = new THREE.Texture(canvas); // canvas texture
texture.needsUpdate = true;
var geometry = new THREE.PlaneGeometry(400, 400, 50, 50);
var material = new THREE.MeshPhongMaterial({
color: 0xffffff,
map: texture,
});
var plane = new THREE.Mesh(geometry, material);
plane.position.set(0, 0, 0);
scene.add(plane);
light = new THREE.DirectionalLight(0xffffff, 5.0); // light
scene.add(light);
// init rendering
var step = 0;
var render = function(){
var start = new Date();
step++;
var cameraX = 400 * Math.cos(step / 500);
var cameraY = 400 * Math.sin(step / 500);
camera.position.set(cameraX, cameraY, 200);
camera.up.set(0, 0, 1);
camera.lookAt({x: 0, y: 0, z: 0});
var lightX = 500 * Math.cos(step / 500);
var lightY = 500 * Math.sin(step / 500);
light.position.set(lightX, lightY, 200);
renderer.clear();
renderer.render(scene, camera);
var end = new Date();
$("#threeRenderingTime font").html(end.getTime() - start.getTime() + " ms");
requestAnimationFrame(render);
}
render();
});
}
追記(2015-09-14)
さらに更新して、だいぶかっこよくなりました!
D3.jsとThree.jsで日本地図を可視化してみた2
上記の前回記事では、D3.jsとThree.jsを使って日本地図を描画しました。
そこからさらに勉強を進めまして、より3Dに描画できるようになりましたので、データものせて作ってみました。
コメント