专栏首页郭先生的博客three.js 绘制3d地图

three.js 绘制3d地图

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

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

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

drawMap() {
    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可以写出各种各样的地图,这是入门级的版本,希望给萌新一些启发。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • three.js 制作一个三维的推箱子游戏

    今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可...

    郭先生的博客
  • three.js 数学方法之Plane

    今天郭先生就来继续说一说three.js数学方法中的plane(平面)。在三维空间中无限延伸的二维平面,平面方程用单位长度的法向量和常数表示。构造器为Plane...

    郭先生的博客
  • three.js 郭先生制作太阳系

    今天郭先生收到评论,想要之前制作太阳系的案例,因为找不到了,于是在vue版本又制作一版太阳系,在线案例请点击three.js制作太阳系(加载时间比较长,请稍等一...

    郭先生的博客
  • Arcgis for JS之Cluster聚类分析的实现(基于区域范围的)

    咱们书接上文,在上文,实现了基于距离的空间聚类的算法实现,在本文,将继续介绍空间聚类之基于区域范围的实现方式,好了,闲言少叙,先看看具体的效果:

    lzugis
  • 【译】5个对Linux新手来说最好的包管理器

    译者按:作为Linux新手来说,选择一个Linux发行版、熟悉Linux系统,无论做什么都离不开软件的安装与卸载。那么,软件包管理器的相关知识就显得非常重要了。...

    小小科
  • vue学习笔记

    当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项...

    用户6362579
  • SAP Spartacus产品转盘页面的产品数据批量加载实现细节

    果然最后还是调用Angular的http module,逐一从Commerce Cloud服务器读取数据。没有批量读取的方法。

    Jerry Wang
  • (六十三)c#Winform自定义控件-箭头(工业)

    GitHub:https://github.com/kwwwvagaa/NetWinformControl

    冰封一夏
  • ActiveReports 报表中 RDF 文件解析

    AcitveReport 提供两种报表模板,XML(RPX)模板和Code-Based 模板。两者都可以用于设计报表。 但是 RDF 格式文件我们大多不是很了...

    葡萄城控件
  • Spring NettyWebServer 启动运行机制

    在运行 Spring Boot Reactive 应用时,需要在应用内启动一个 WebServer,那么 WebServer 的启动过程是怎样的呢?通过以下源码...

    安宁

扫码关注云+社区

领取腾讯云代金券