threejs 给地图添加3d标签 学习笔记

threejs yekong

threejs 不同gdp拉伸不同高度并添加颜色变化,在此基础上,我们实践在地图上给地图添加3d标签标注地名

threejs 给地图添加3d标签 学习笔记

threejs 给地图添加3d标签实例

threejs 给地图添加3d标签

3d标签代码

import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
// 创建一个HTML标签
function tag(name) {
  // 创建div元素(作为标签)
  var div = document.createElement('div');
  div.innerHTML = name;
  div.style.padding = '4px 10px';
  div.style.color = '#fff';
  div.style.fontSize = '16px';
  div.style.position = 'absolute';
  div.style.backgroundColor = 'rgba(25,25,25,0.5)';
  div.style.borderRadius = '5px';
  //div元素包装为CSS3模型对象CSS3DObject
  var label = new CSS3DObject(div);
  div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
  // 设置HTML元素标签在three.js世界坐标中位置
  // label.position.set(x, y, z);
  return label;//返回CSS3模型标签
}

// 创建一个CSS3渲染器CSS3DRenderer
var labelRenderer = new CSS3DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
// // 避免renderer.domElement影响HTMl标签定位,设置top为0px
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.left = '0px';
// //设置.pointerEvents=none,以免模型标签HTML元素遮挡鼠标选择场景模型
labelRenderer.domElement.style.pointerEvents = 'none';
document.body.appendChild(labelRenderer.domElement);

export {tag,labelRenderer}

读取地图数据

loader.load(modelUrl + 'json/china.json', function (data2) {
    // 访问所有子行政区(省份)边界坐标数据:data.features
    data2.features.forEach(function (area) {
        // "Polygon":省份area有一个封闭轮廓
        //"MultiPolygon":省份area有多个封闭轮廓
        if (area.geometry.type === "Polygon") {
            // 把"Polygon"和"MultiPolygon"的geometry.coordinates数据结构处理为一致
            area.geometry.coordinates = [area.geometry.coordinates];
        }
        var name = area.properties.name;//省份名
        if (name) {
            // height:行政区轮廓拉伸高度,和gdp大小正相关,不过注意相机渲染范围(或者说地图尺寸范围)
            var height = gdpObj[name] / 10000;//拉伸高度
            var mesh = ExtrudeMesh(area.geometry.coordinates, height)
            mesh.name = name;//设置mesh对应的省份名字
            meshGroup.add(mesh);//省份轮廓拉伸Mesh插入组对象mapGroup
            // 颜色插值计算
            var color = color1.clone().lerp(color2.clone(), gdpObj[mesh.name] / gdpMax);
            mesh.material.color.copy(color);
        }
        if (name) {
            var tag3D = tag(mesh.name);
            var center = area.properties.center;//行政区几何中心经纬度坐标
            tag3D.position.set(center[0], center[1], height + 0.01)
            //缩放CSS3DObject模型对象
            tag3D.scale.set(0.04, 0.04, 0.04);//根据相机渲染范围适当缩放
            // tag3D.rotateX(Math.PI / 2);//从XOY平面旋转到XOZ平面
            scene.add(tag3D);
        }

        // 解析所有封闭轮廓边界坐标area.geometry.coordinates
        var line = metesBounds(area.geometry.coordinates);
        lineGroup.add(line);//省份边界轮廓插入组对象lineGroup
        var line2 = line.clone();
        line2.position.z = height;//顶部边界线跟随轮廓拉伸高度保持一致
        lineGroup2.add(line2);
    });
})

渲染

function render() {
    //渲染场景中的HTMl元素包装成的CSS3模型对象
    labelRenderer.render(scene, camera);
    renderer.render(scene, camera); //执行渲染操作
    requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}

最终实现效果

webGL 3D地图可视化实例

喜欢