スポンサーリンク

D3.jsとThree.jsで日本地図を可視化してみた

D3.js JavaScript three.js データビジュアライゼーション 地理データ

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に描画できるようになりましたので、データものせて作ってみました。

コメント