zoukankan      html  css  js  c++  java
  • three.js 绘制3d地图(转载)

    通过地图数据配合three可以做出非常酷炫的地图,在大数据展示中十分常见。

    这篇郭先生就来说说使用three.js几何体制作3D地图。在线案例点击原文地址

    地图的数据是各个地图块的点数组,通过THREE.ExtrudeGeometry方法挤压出地图的版块,然后通过THREE.Line方法画出地图的分割线。地图的数据参见DATAV.GeoAtlas,鼠标悬浮到地图版块高亮,效果如图

    1. 得到数据,遍历数据,处理数据

    复制代码
    rawMap() {
        this.worldGeometry = mapJson; //mapJson就是地图的json数据
        this.worldGeometry.features.forEach((worldItem, worldItemIndex) => {
            worldItem.geometry.coordinates.forEach(worldChildItem => {
                worldChildItem.forEach(countryItem => { //每个版块的点数组
                    this.drawExtrude(this.drawShape(countryItem)) //传递数据画出地图的shape,返回结果再传到drawExtrude方法得到ExtrudeGeometry网格
                    this.drawLine(countryItem); //传递数据画出地图边线
                });
            });
        });
            group.scale.y = 1.2; //group里面包含所有版块网格
        scene.add(group);
        lineGroup.scale.y = 1.2; //lineGruop里面包含所有线的网格
        scene.add(lineGroup);
        this.render();
    }
    复制代码

    2. 传递数据画出地图的shape,返回结果再传到drawExtrude方法得到ExtrudeGeometry网格。

    复制代码
    drawShape(posArr) {
        var shape = new THREE.Shape();
        shape.moveTo(posArr[0][0] - this.offsetX, posArr[0][1] - this.offsetY);
        posArr.forEach(item => {
            shape.lineTo(item[0] - this.offsetX, item[1] - this.offsetY);
        });
        return shape;
    }
    drawExtrude(shapeObj) {
        var geometry = new THREE.ExtrudeGeometry(shapeObj, this.options);
        var material1 = new THREE.MeshPhongMaterial({
            color: this.bgColor,
            specular: this.bgColor
        });
        var material2 = new THREE.MeshBasicMaterial({
            color: 0x008bfb
        });
        let shapeGeometryObj = new THREE.Mesh(geometry, [material1, material2]);
        shapeGeometryObj.name = 'board';
        group.add(shapeGeometryObj);
    }
    复制代码

    3. 传递数据画出地图边线

    复制代码
    drawLine(posArr) {
        let geometry1 = new THREE.Geometry();
        let geometry2 = new THREE.Geometry();
            posArr.forEach(item => {
            geometry1.vertices.push(
                new THREE.Vector3(
                    item[0] - this.offsetX,
                    item[1] - this.offsetY,
                    1.01
                )
            );
            geometry2.vertices.push(
                new THREE.Vector3(
                    item[0] - this.offsetX,
                    item[1] - this.offsetY,
                    -0.01
                )
            );
        });
        let lineMaterial = new THREE.LineBasicMaterial({ color: 0x008bfb });
        let line1 = new THREE.Line(geometry1, lineMaterial);
        let line2 = new THREE.Line(geometry2, lineMaterial);
        lineGroup.add(line1);
        lineGroup.add(line2);
    }
    复制代码

    4. 鼠标悬浮后高亮版块

    复制代码
    handleMousemove(event) {
        event.preventDefault();
        let mouse = new THREE.Vector2(0, 0);
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
        this.raycaster.setFromCamera(mouse, camera);
        let intersects = this.raycaster.intersectObjects(group.children);
        this.previousObj.material[0].color = new THREE.Color(this.bgColor);
        if(intersects[0] && intersects[0].object) {
            intersects[0].object.material[0].color = new THREE.Color(0xffaa00);
            this.previousObj = intersects[0].object; //previousObj保存悬浮的对象,鼠标移开后恢复颜色。
        }
    }
    复制代码

    主要代码部分就是这样,我们也可以在颜色改变时加入一些渐变动画,three.js可以写出各种各样的地图,这是入门级的版本,希望给萌新一些启发。

    转载请注明地址:郭先生的博客

    原文链接:https://www.cnblogs.com/vadim-web/p/13320838.html

  • 相关阅读:
    二分专题
    数据结构-图
    Linux文件基本属性(以ls -l输出为例解释)
    shell脚本版素数筛
    Linux whereis,which
    Linux外网代理配置
    Linux三剑客
    Elasticsearch集群搭建(Linux)
    测试之路
    我的另一半
  • 原文地址:https://www.cnblogs.com/cmd-/p/13320868.html
Copyright © 2011-2022 走看看