three.js 中国城市PM2.5 可视化

该博客详细介绍了如何利用Three.js库结合JSON数据,绘制中国城市PM2.5分布的3D可视化图表。通过加载透明圆形贴图作为精灵模型,创建并设置每个城市的坐标、大小和颜色,实现交互式的鼠标移动高亮效果。同时,还展示了城市标注的显示和隐藏功能。
摘要由CSDN通过智能技术生成

一、效果图:

模拟绘制中城市PM2.5图

二、实现过程

1、加载json数据和贴图,绘制城市PM.25分布图

var cityInfo = document.getElementById('cityInfo');
//定义一个数组存放坐标点
var points = [];
var shape;
var geometry,material,line;

/**
 * 一个精灵模型对象表示一个城市的位置和数据
 */
// 加载一个背景透明的圆形贴图,矩形精灵显示为圆形效果
var texture = new THREE.TextureLoader().load("picture/圆形.png");
// 创建组对象,包含所有精灵对象
let group = new THREE.Group();
// 文件加载对象
var loader = new THREE.FileLoader().setResponseType('json');
// 加载PM2.5数据
loader.load('./json/pmdata.json', function(data) {
    //遍历数据
    data.forEach(elem => {
        // 精灵材质
        var spriteMaterial = new THREE.SpriteMaterial({
            color:"#1A41E5",
            map: texture, //设置精灵纹理贴图
            transparent: true,
            opacity: 0.8,
        });
        // 创建精灵模型对象
        var sprite = new THREE.Sprite(spriteMaterial);
        group.add(sprite);

        // 控制精灵大小   使用PM2.5大小设置精灵模型的大小
        // 注意适当缩放pm2.5大小,以便得到更好的显示效果
        var k = elem.value / 200
        sprite.scale.set(k, k, 1);
        sprite.name = elem.name;
        //获得城市坐标设置精灵模型对象的位置
        sprite.position.set(elem.coordinate[0], elem.coordinate[1], 0)
    });
    // 中国城市坐标整体的几何中心不在坐标原点,需要适当的平移
    group.position.set(-110, -30, 0);
    scene.add(group);//把精灵群组插入场景中

})

2、显示城市标注

 function showCity(name, flag) {  //显示当前鼠标移动到的城市名称
  if (flag) {
         document.getElementById('cityInfo').style.visibility = 'visible';
         document.getElementById('cityInfo').innerText = name;
     }
     else document.getElementById('cityInfo').style.visibility = 'hidden';
 }

3、监听鼠标移动事件,鼠标拾取位置更新

 raycaster = new THREE.Raycaster();
 mouse = new THREE.Vector2();
 var eventOffset = {};
 function onMouseMove( event ) {
     // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
     mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
     mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
     eventOffset.x = event.clientX;
     eventOffset.y = event.clientY;
     cityInfo.style.left = eventOffset.x + 4 + 'px';
     cityInfo.style.top = eventOffset.y + 4 + 'px';

 }

4、渲染方法,更新鼠标选中的颜色

function  render()
{
    // 通过摄像机和鼠标位置更新射线
    raycaster.setFromCamera( mouse, camera );
    // 计算物体和射线的焦点    true代表包括后代模型
    let intersects = raycaster.intersectObjects( scene.children, true );
   // console.log(intersects)
    if (intersects.length > 0) {  //判断鼠标移动到的模型数量
        if (currentSprite != intersects && currentSprite) {
            for (let i = 0; i < currentSprite.length; i++ )
            {
                currentSprite[i].object.material.color.set( '#1A41E5' );
            }
            }
            for (let i = 0; i < intersects.length; i++ )
            {
               intersects[i].object.material.color.set( '#F7AA07' );
            }
            currentSprite = intersects;
            if (!currentSpriteTitle || currentSpriteTitle != currentSprite[0].object.title) {    // 判断是否在城市上,和城市名是否改变
                currentSpriteTitle = currentSprite[0].object.name;
                showCity(currentSpriteTitle, true)
            }
    }
    //更新矩阵,将相机位置更新到正确的位置
    // camera.updateMatrixWorld();
    update();
    renderer.render(scene,camera); //执行渲染操作
    requestAnimationFrame(render);  //请求再次执行渲染函数render,渲染下一帧

}

5、初始化对象

<!DOCTYPE html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值