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

学习视频
参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值