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

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,然后用前面的方法

学习视频
参考文章

### 回答1: Cesium是一个用于构建和展示地球上三维场景的开源平台。它支持加载和显示不同级别的3D模型,使用户能够以不同的细节级别观察地球上的物体。 加载分级3D模型的过程大致可分为以下几个步骤: 1. 准备3D模型:首先,需要将3D模型准备好。通常,3D模型需要以COLLADA (.dae)、glTF (.gltf) 或3D Tiles (.3dtiles)等格式存在。 2. 配置Cesium:在代码中配置Cesium以使用3D模型。这包括引入Cesium库、创建Cesium的Viewer对象,并设置它的一些属性,比如视图容器和底图。 3. 加载3D模型:使用Cesium提供的加载函数,将3D模型引入Cesium的场景中。这可以通过调用Cesium的load函数来实现。在load函数中,需要指定3D模型的URL、加载完成后的回调函数等参数。 4. 调整模型的显示级别:Cesium允许用户根据需要调整模型的显示级别。通过设置3D模型加载选项,可以控制模型的显示范围、LOD(层次细节)以及其他参数。这样,用户可以根据场景的远近和观察需求,动态地控制模型的显示细节。 5. 实时交互与更新:一旦3D模型加载完成并显示在Cesium的场景中,用户可以与模型进行交互,例如平移、缩放和旋转。同时,用户还可以实时更新模型的状态,比如改变颜色、位置等属性。 通过上述步骤,我们可以很方便地使用Cesium加载分级3D模型,并根据需要对模型进行进一步的定制和交互。Cesium加载和展示3D模型方面具有强大的功能和灵活性,可满足各种场景下的需求。 ### 回答2: Cesium是一种用于构建地球和空间场景的开源JavaScript库,它可以实现加载和展示分级3D模型。分级3D模型是一种将地球表面上的物体(如建筑物、植被等)分成多个层次,从而实现详细的展示和交互的技术。下面将介绍cesium如何加载和展示分级3D模型。 首先,在使用cesium加载分级3D模型之前,需要准备好模型数据。分级3D模型一般采用LOD(Level of Detail)技术,即将模型的细节层次化,根据距离观察者的远近显示相应层次的细节。因此,需要准备不同层次的模型数据,通常以瓦片(Tile)的形式组织。 接下来,将模型数据与Cesium集成。Cesium提供了一系列API和类,用于加载、显示和控制3D模型。通过以下步骤,将分级3D模型加载cesium中: 1. 使用CesiumTileset类加载分级3D模型的根瓦片。根瓦片是整个模型的入口点,包含了其他瓦片的引用。 2. 根据观察者的位置和视野范围,动态加载相应的瓦片。CesiumTileset类会根据观察者的位置和视野范围决定哪些瓦片需要加载和显示。 3. Cesium会根据瓦片的层次关系,自动管理瓦片的加载和卸载。在观察者接近某个瓦片时,Cesium会自动加载该瓦片和其子瓦片;在观察者远离某个瓦片时,Cesium会自动卸载该瓦片和其子瓦片,以节省内存。 最后,根据需要,可以通过Cesium的API实现对分级3D模型的交互和控制。例如,可以调整视角和距离观察者的远近,以查看模型的不同层次细节;也可以通过鼠标操作在模型上进行选取、旋转等操作。 综上所述,通过Cesium可以方便地加载和展示分级3D模型,实现了地球表面物体的详细展示和交互体验。 ### 回答3: Cesium是一个开源的JavaScript库,用于在Web浏览器上创建高性能的3D地理可视化效果。它支持加载和展示各种形式的地理数据,包括分级3D模型。 要加载分级3D模型,我们首先需要将模型数据准备好。通常,这需要从3D建模软件中导出成支持的文件格式,例如glTF或OBJ。这些文件将包含模型的几何数据、纹理贴图和材质信息。 一旦我们准备好模型文件,就可以在Cesium中使用"Model"类来加载模型加载模型的步骤如下: 1. 创建一个Cesium的Viewer对象,用于渲染3D场景。 2. 使用CesiumCesium.Model类创建一个模型对象。 3. 通过设置模型对象的url属性,指定模型文件的URL地址。 4. 使用Cesium的Viewer.scene.primitives.add方法将模型添加到场景中。 在加载过程中,Cesium会自动解析模型文件,并在场景中根据模型的几何数据和材质信息绘制出模型。默认情况下,模型会放置在地球上的特定位置,但我们也可以通过设置模型对象的position属性来调整模型的位置。 另外,我们还可以通过设置模型对象的scale属性来调整模型的大小,以适应不同的场景需求。 需要注意的是,加载3D模型可能需要一定的时间,特别是对于较大的模型文件或者网络较慢的情况。因此,在加载模型时,我们可以使用Cesium的事件处理机制来显示加载进度或者提供加载动画,以提高用户体验。 总之,Cesium提供了强大的功能来加载和展示分级3D模型,为我们创建令人印象深刻的地理可视化效果提供了便利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值