欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Cesium3d tiles模型单体化思路

程序员文章站 2022-03-26 08:49:37
...

首先,当我们把倾斜摄影模型或者建筑模型等osgb、kml等格式的数据转化成b3dm格式之后我们才可以考虑在cesium中做单体化。

cesium中的模型单体化也就是针对于批量的数据的(b3dm)这样的格式。

在查看代码的时候可以多看看注释,有的地方详细解析了为什么要这么做

我们来剖析一下官网提供的思路:

1.建立场景

//创建初始的container并且提供地形
var viewer = new Cesium.Viewer("cesiumContainer", {
    terrainProvider: Cesium.createWorldTerrain(),
  });
  //开启深度检测
  viewer.scene.globe.depthTestAgainstTerrain = true;
  
  // 设置相机的观察位置和角度
  var initialPosition = Cesium.Cartesian3.fromDegrees(
    -74.01881302800248,
    40.69114333714821,
    753
  );
  var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(
    21.27879878293835,
    -21.34390550872461,
    0.0716951918898415
  );
  viewer.scene.camera.setView({
    destination: initialPosition,
    orientation: initialOrientation,
    endTransform: Cesium.Matrix4.IDENTITY,
  });

2.加载数据

 // 加载3d tiles数据
  var tileset = new Cesium.Cesium3DTileset({
    url: Cesium.IonResource.fromAssetId(75343),
  });
  viewer.scene.primitives.add(tileset);

3.设置鼠标移动事件和鼠标点击事件,当鼠标滑过,或者点击的时候做一些事情

 var clickHandler = viewer.screenSpaceEventHandler.getInputAction(
    Cesium.ScreenSpaceEventType.LEFT_CLICK
  );

 

4.通过isSilhouetteSupported来判断是否支持轮廓化要素,对要素的轮廓线进行设置

 //当要素支持轮廓的时候,设置成鼠标滑过轮廓显示蓝色,单击时显示绿色
  //如果要素不支持轮廓,鼠标滑过时要素显示黄色
  if (
    Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene)
  ) {
    // 支持轮廓的时候,设置样式
    var silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
    silhouetteBlue.uniforms.color = Cesium.Color.BLUE;
    silhouetteBlue.uniforms.length = 0.01;
    silhouetteBlue.selected = [];
  
    var silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
    silhouetteGreen.uniforms.color = Cesium.Color.LIME;
    silhouetteGreen.uniforms.length = 0.01;
    silhouetteGreen.selected = [];
  
    viewer.scene.postProcessStages.add(
      Cesium.PostProcessStageLibrary.createSilhouetteStage([
        silhouetteBlue,
        silhouetteGreen,
      ])
    );
  
    // 当鼠标滑过时设置蓝色
    viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) {
      // 如果一个要素此时正处于高亮状态,则取消
      silhouetteBlue.selected = [];

5.通过关键的scene.pick()方法获取要素以及属性

  // 选择一个新的feature通过场景的pick方法获取
      var pickedFeature = viewer.scene.pick(movement.endPosition);
      //如果没有要素,则不显示弹框
      if (!Cesium.defined(pickedFeature)) {
        nameOverlay.style.display = "none";
        return;
      }
// 如果被选中了,就展示弹框,获取要素的BIN属性展示在弹框内
      nameOverlay.style.display = "block";
      nameOverlay.style.bottom =
        viewer.canvas.clientHeight - movement.endPosition.y + "px";
      nameOverlay.style.left = movement.endPosition.x + "px";
      var name = pickedFeature.getProperty("BIN");
      nameOverlay.textContent = name;
      var featureName = pickedFeature.getProperty("name");
      selectedEntity.name = featureName;
      selectedEntity.description =
        'Loading <div class="cesium-infoBox-loading"></div>';
      viewer.selectedEntity = selectedEntity;
      selectedEntity.description =
        '<table class="cesium-infoBox-defaultTable"><tbody>' +
        "<tr><th>BIN</th><td>" +
        pickedFeature.getProperty("BIN") +
        "</td></tr>" +
        "<tr><th>DOITT ID</th><td>" +
        pickedFeature.getProperty("DOITT_ID") +
        "</td></tr>" +
        "<tr><th>SOURCE ID</th><td>" +
        pickedFeature.getProperty("SOURCE_ID") +
        "</td></tr>" +
        "</tbody></table>";

scene.pick()方法是用来选择场景中的要素的。通常会返回一个具有“primitive”属性的对象。

但是官方对于scene.pick()方法有这样一句关键的话:

When a feature of a 3D Tiles tileset is picked, pick returns a Cesium3DTileFeature object.、

意思是说如果被选中的要素是一个3d tiles的要素,将会返回3d tiles feature对象

实际上,3d tiles feature就是一个特殊的feature,它有着自己独特的属性和方法。

6.3d tilesetfeature的关键方法——getProperty获取要素属性

通过查阅API发现,3d tilesetfeature有一个很关键的方法叫做getProperty()它用来获取要素的属性信息,参数是属性名。

7.要注意3d tiles概念当中提到的每一个模型都是一个feature。

之前讲解3dtiles的时候有一个很重要的概念就是在3d tiles中每一个模型都是一个要素(feature),在这里正是应用了这一点。scene.pick()方法正好能够选择其中的单个要素,这是单体化的关键所在。

8.HTML功底,弹窗跟随鼠标

关键步骤清楚了以后,剩余的就是各位的html和js功底了,想要什么样的弹框,什么样的样式展示属性就是各位来定义了。