当前位置: 代码网 > it编程>编程语言>其他编程 > cesium 加载3D建筑模型(3D tiles)

cesium 加载3D建筑模型(3D tiles)

2024年08月06日 其他编程 我要评论
上面的模型都是cesium自带的,如果是自己的模型,怎么加载呢?有两种方式:通过方式[官网地址](上传到cesiumion自己的资源中,会生成一个id,然后用前面的方法学习视频参考文章。

cesium# 系列文章目录

加载3d建筑

示例cesium版本为1.116.0

初始化
const viewer = new cesium.viewer("cesiumcontainer", {
    baselayerpicker: false,
    terrainprovider: await cesium.cesiumterrainprovider.fromionassetid(1, {
      requestvertexnormals: true,  //可以增加法线,用于提高光照效果
      requestwatermask: true, //可以增加水面特效
    })
});
加载cesium提供的通用3d建筑

首先要到cesium的个人中心,资源仓库中添加cesium osm buildings到自己的资源中,这种资源的建筑没有高度


const tileset = viewer.scene.primitives.add(
    await cesium.cesium3dtileset.fromionassetid(96188),
);
//移动视角到陆家嘴
viewer.camera.setview({
    destination: cesium.cartesian3.fromdegrees(121.49,31.23, 3000),
    orientation: {
      heading: 0,
      pitch: -90,
      roll: 0
    }
})

未加载模型前:

在这里插入图片描述

加载模型后:

在这里插入图片描述

添加有高度的建筑

纽约3d建筑

cesium的个人中心,资源仓库中添加new york city 3d buildings到自己的资源中


const tileset = viewer.scene.primitives.add(
    await cesium.cesium3dtileset.fromionassetid(75343),
 );
//可以根据高度,修改模型颜色//移动视角到纽约,像上方一样,设置视角,也可以直接这么做
viewer.zoomto(tileset)

结果如下:

在这里插入图片描述

  • 根据高度设置建筑颜色

    ps:高度的顺序,因为我们用的是大于号一定要从大到小,反之则是从小到大

    
    tileset.style = new cesium.cesium3dtilestyle({
      color: {
        conditions: [
          ['${height} >= 300', 'rgba(45,0,75,0.6)'],
          ['${height} >= 200', 'rgba(102,71,151, 1)'],
          ['${height} >= 100', 'rgba(170,62,204, 1)'],
          ['${height} >= 50', 'rgba(224,226,238, 1)'],
          ['${height} >= 25', 'rgba(252,230,200, 1)'],
          ['${height} >= 10', 'rgba(248,176,87, 1)'],
          ['${height} >= 5', 'rgba(198,106,11, 1)'],
          ['true', 'rgba(127,59,8, 1)'],
        ]
      },
      show: '${height} >= 0',
    });
    

    结果如下:

    在这里插入图片描述

  • 根据经纬度设置建筑颜色

    
    tileset.style = new cesium.cesium3dtilestyle({
    color: {
      conditions: [
        ['${latitude} >= 40.712945742423585', 'rgba(255, 0, 0, 1.0)'], //红色
        ['${latitude} >= 40.64859281217332', 'rgba(0, 0, 255, 0.5)'], // 蓝色
        ['${latitude} >= 40.607812909160636', 'rgba(255, 0, 0, 0.7)'], // 红色
      ]
    },
    show: '${height} >= 0',
    });
    

    结果如下:

    在这里插入图片描述

  • 以某一点为圆点,根据到原点的距离设置颜色

    
    tileset.style = new cesium.cesium3dtilestyle({
      defines: {
        distance: "distance(vec2(${latitude},${longitude}),vec2(40.712945742423585, -74.01312421751199))",
      },
      color: {
        conditions: [
          ["${distance} < 0.04", "color('red', 1.0)"],  //红
          ["${distance} < 0.05", "color('orange', 1.0)"], //橙
          ["${distance} < 0.06", "color('yellow', 1.0)"], //黄
          ["${distance} < 0.07", "color('green', 1.0)"], //绿
          ["${distance} < 0.08", "color('cyan', 1.0)"], //青
          ["${distance} < 0.09", "color('blue', 1.0)"], //蓝
          ["${distance} < 0.10", "color('purple', 1.0)"], //紫
          ["true", "color('#add8e6',0.8)"],
        ]
      },
      show: '${height} >= 0',
    });
    

    结果如下:

    在这里插入图片描述

  1. 添加鼠标经过建筑物的事件,这里做两个小功能

    • 鼠标经过建筑物的时候高亮
    • 鼠标经过建筑物的时候,悬浮显示一些关于建筑物的信息
    const scene = viewer.scene
    const handler = new cesium.screenspaceeventhandler(scene.canvas);  //处理事件
    const highlighted = {
      feature: undefined,
      originalcolor: new cesium.color(),
    };
    const selected = {
      feature: undefined,
      originalcolor: new cesium.color(),
    };
    const metadataoverlay = document.createelement("div");
    viewer.container.appendchild(metadataoverlay);
    //弹窗tips的样式
    metadataoverlay.classname = "backdrop";
    metadataoverlay.style.display = "none";
    metadataoverlay.style.position = "absolute";
    metadataoverlay.style.bottom = "0";
    metadataoverlay.style.left = "0";
    metadataoverlay.style["pointer-events"] = "none";  //设置元素是否对鼠标事件做出反应
    metadataoverlay.style.padding = "4px";
    metadataoverlay.style.backgroundcolor = "#303030";
    metadataoverlay.style.whitespace = "pre-line";
    metadataoverlay.style.fontsize = "16px";
    metadataoverlay.style.borderradius = "4px";
    //添加想要处理的回调函数
    handler.setinputaction(function (movement) {
      //movement:startposition开始位置,endposition结束位置(代表当前模型位置)
      if (true) {
        if (cesium.defined(highlighted.feature)) {
          highlighted.feature.color = highlighted.originalcolor;
          highlighted.feature = undefined;
        }
        //返回一个带有“primitive”属性的对象,该属性包含场景中位于特定窗口坐标处的第一个图元(顶部),如果该位置没有任何内容,则返回undefined
        const feature = scene.pick(movement.endposition);
        const featurepicked = feature instanceof cesium.cesium3dtilefeature;
        //是否包含此属性
        const isbuildingfeature =
              featurepicked && feature.hasproperty("majority_ownership_type");if (isbuildingfeature) {
          if (feature !== selected.feature) {
            highlighted.feature = feature;
            cesium.color.clone(feature.color, highlighted.originalcolor);
            feature.color = cesium.color.aqua;
          }
          metadataoverlay.style.display = "block";
          metadataoverlay.style.bottom = 
            `${viewer.canvas.clientheight - movement.endposition.y}px`;
          metadataoverlay.style.left = `${movement.endposition.x}px`;
          var tablehtmlscratch = 
              `<div style="color: #fff">${feature.getproperty(
            "majority_ownership_type")}</div>`
          metadataoverlay.innerhtml = tablehtmlscratch;
        } else {
          metadataoverlay.style.display = "none";
        }
      }
    }, cesium.screenspaceeventtype.mouse_move);
    
自定义模型

上面的模型都是cesium自带的,如果是自己的模型,怎么加载呢?有两种方式:

  1. 通过cesium3dtileset.fromurl方式[官网地址](cesium3dtileset - cesium documentation)

    
    const tileset = viewer.scene.primitives.add(
        await cesium.cesium3dtileset.fromurl("/tileset/photogrammetry/tileset.json")
     );
    
  2. 上传到cesiumion自己的资源中,会生成一个id,然后用前面的方法

学习视频

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com