threejs 实现地图轮廓的拉伸 学习笔记

threejs yekong

地图拉伸api ExtrudeBufferGeometry

通过three.js的几何体ExtrudeBufferGeometry可以拉伸一个轮廓,这样的话,通过ExtrudeBufferGeometry可以实现一个立体的拉伸地图效果。

  • 注意拉伸高度要参考地图包围盒尺寸,或者说相机渲染范围

设置拉伸前

1674614108006EHztdY

设置拉伸后

设置拉伸后

地图拉伸

 function ExtrudeMesh(pointsArrs, height) {
  var shapeArr = [];//轮廓形状Shape集合
  pointsArrs.forEach(pointsArr => {
    var vector2Arr = [];
    // 转化为Vector2构成的顶点数组
    pointsArr[0].forEach(elem => {
      vector2Arr.push(new THREE.Vector2(elem[0], elem[1]))
    });
    var shape = new THREE.Shape(vector2Arr);
    shapeArr.push(shape);
  });
  // MeshBasicMaterial:不受光照影响
  // MeshLambertMaterial:几何体表面和光线角度不同,明暗不同
  var material = new THREE.MeshLambertMaterial({
    color: 0x004444,
    // transparent: true,
    // opacity: 0.8,
  }); //材质对象
  var geometry = new THREE.ExtrudeBufferGeometry( //拉伸造型
    shapeArr, //多个多边形二维轮廓
    //拉伸参数
    {
      // depth:根据行政区尺寸范围设置,比如高度设置为尺寸范围的2%,过小感觉不到高度,过大太高了
      depth: height, //拉伸高度
      bevelEnabled: false //无倒角
    }
  );
  var mesh = new THREE.Mesh(geometry, material); //网格模型对象
  return mesh;
}
loader.load('./json/china.json', function (data) {
    // 访问所有省份边界坐标数据:data.features
    data.features.forEach(function (area) {
        // "Polygon":省份area有一个封闭轮廓
        //"MultiPolygon":省份area有多个封闭轮廓
        if (area.geometry.type === "Polygon") {
            // 把"Polygon"和"MultiPolygon"的geometry.coordinates数据结构处理为一致
            area.geometry.coordinates = [area.geometry.coordinates];
        }
        // 解析所有封闭轮廓边界坐标area.geometry.coordinates
        lineGroup.add(metesBounds(area.geometry.coordinates));//省份边界轮廓插入组对象mapGroup
        // height:根据行政区尺寸范围设置,比如高度设置为地图尺寸范围的2%、5%等,过小感觉不到高度,过大太高了
        var height = 2;//拉伸高度
        meshGroup.add(ExtrudeMesh(area.geometry.coordinates, height));//省份轮廓拉伸Mesh插入组对象mapGroup
    });
})

设置拉伸的时候,边界线的也要适当调整避免出现轮廓遮挡了边界线

lineGroup.position.z = 2 + 0.1;

演示地址

threejs 实现地图轮廓的拉伸实例

最终实现效果

webGL 3D地图可视化实例

教程地址

WebGL/Three.js前端3D可视化

喜欢