基于Cesium的实景三维模型动态更新-以3Dtiles为例(番外篇)

在进行实景三维模型动态更新的时候,经常会出现一些误差问题,这里将我遇到的问题以及解决方法统一写出来:

1.模型高度问题

在无人机采集数据倾斜建模后,可能会出现新旧模型高度不一致的情况,如下图:

可以通过clampToHeigthMostDetailed的办法去获取他的高度(如果你可以的话记得告诉我!),这里也给出代码

function getHeightByType(cartesians){
    return new Promise(async (resolve) => {
      try {
        let promise = viewer.scene.clampToHeightMostDetailed(cartesians);
          promise.then((updatedCartesians) => resolve(updatedCartesians));
      } catch (e) {
        resolve(false);
      }
    });
}

或者有比较吊诡的办法,直接获取某个点新旧模型的高度值,得到高度差,再用上模型的平移方法去纠正,代码如下:

1.1点选模型获取高度 

//鼠标点选获取模型上的点,可以准确的获取到某经纬度下模型的高度
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (evt) {
  var cartesian = viewer.scene.pickPosition(evt.position);
  var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  var lng = Cesium.Math.toDegrees(cartographic.longitude);
  var lat = Cesium.Math.toDegrees(cartographic.latitude);
  var height = cartographic.height; // 模型高度
  var mapPosition = {
    x: lng,
    y: lat,
    z: height,
  };
  console.log(mapPosition);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

这里的mapPosition就是你点选的那个点,只需要获得z(高度)就够了。

1.2调整模型高度

//根据tileset的边界球体中心点的笛卡尔坐标得到经纬度坐标,经纬度
    var cartographic = Cesium.Cartographic.fromCartesian(tilesset.boundingSphere.center);
    //根据经纬度和高度0,得到地面笛卡尔坐标
    var surface = Cesium.Cartesian3.fromRadians(
      cartographic.longitude,
      cartographic.latitude,
      cartographic.height,
    );
    console.log(cartographic.height)
    var height = cartographic.height + 5.40533759063451
    //根据经纬度和需要的高度,得到偏移后的笛卡尔坐标
    // var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 60);
    var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, height);
    //计算坐标变换,得到新的笛卡尔坐标
    var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
    //调整3dtiles位置
    tilesset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);

height后面那一段5.40533就是我们手动获取的新旧模型的高度差,之后通过位置移动就可以实现调整模型的高度一致了。 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 3dtiles模型动态压平可以通过合理设置Cesium的CameraOptions属性来实现,如设置camera.frustum.far,camera.frustum.near,camera.frustum.fov等属性。 ### 回答2: 在Cesium中,要实现3D Tiles模型动态压平,可以通过以下步骤实现: 1. 首先,加载3D Tiles模型文件。可以使用Cesium的`Cesium3DTileset`对象来加载3D Tiles模型文件,并将其添加到场景中。例如: ```javascript var tileset = new Cesium.Cesium3DTileset({ url: 'path/to/3dtiles/file' }); viewer.scene.primitives.add(tileset); ``` 2. 为了实现动态压平效果,需要使用相机的高度来改变3D Tiles模型的显示程度。可以通过监听相机的高度变化,动态调整模型的显示程度。例如: ```javascript viewer.scene.camera.moveEnd.addEventListener(function() { var cameraHeight = viewer.scene.camera.positionCartographic.height; tileset.maximumScreenSpaceError = cameraHeight / 1000; // 调整最大屏幕空间误差参数 }); ``` 将`maximumScreenSpaceError`参数值设置为相机高度的适当比例,可以根据实际需要调整。 3. 接下来,需要在3D Tiles模型加载完成后,使用`readyPromise`来确保模型已经完全加载进来。这样可以避免在模型加载过程中产生抖动或镜像效果。例如: ```javascript tileset.readyPromise.then(function(tileset) { tileset.maximumScreenSpaceError = viewer.scene.camera.positionCartographic.height / 1000; }); ``` 通过以上步骤,就可以实现Cesium3D Tiles模型动态压平效果。根据相机高度的变化,模型的显示程度将自动调整,从而实现动态压平的效果。 ### 回答3: 在Cesium中实现3dtiles模型动态压平,需要进行以下步骤: 1. 导入Cesium3dtiles模型:首先,你需要使用Cesium的加载器函数将3dtiles模型导入到Cesium中。加载器函数会加载3dtiles文件并将其在场景中呈现为3D模型。 2. 获取模型的高度信息:在Cesium中,可以使用模型的位置和高度信息来动态压平模型。你可以使用Cesium提供的函数来获取模型的高度信息,例如`model.position`和`model.height`。 3. 实现动态压平:一旦获得了模型的高度信息,你可以使用Cesium的几何操作函数来动态压平模型Cesium中的函数可以用于改变模型的顶点坐标,以实现压平效果。例如,你可以根据模型的高度信息修改顶点的Y坐标,并重新计算法线和纹理坐标。 4. 更新模型:完成对模型动态压平后,你需要使用Cesium提供的API来更新模型。可以使用Cesium更新函数来应用新的顶点坐标、法线和纹理坐标,以确保3D模型在场景中正确显示。 总结:实现Cesium中的动态压平需要导入3dtiles模型、获取模型的高度信息,使用几何操作函数进行动态压平,然后更新模型以显示在场景中。这些步骤将确保3D模型Cesium中进行动态压平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值