欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

在 vue 中使用铯 - 铯加载模型

最编程 2024-04-26 11:12:21
...

一 前言

上一节我们完成了vue中使用Cesium的第一步,本节将继续介绍Cesium关于模型加载的一些尝试。在本节分别做了三种尝试(加载cesium官网仓库的纽约模型,加载本地的gltf模型,加载采集的3DTiles数据)

二 加载New York City 3D Buildings

想要加载官网仓库的New York City 3D Buildings模型,你需要先去注册账号,并在项目中填写你的token同时将New York City 3D Buildings 加入到你自己的仓库中,然后通过id进行模型调用,具体操作上节已经说过,此处我们直接使用。

image.png 在仓库中我们可以看到New York City 3D Buildings id 为 75343,接下来定义加载方法,直接使用。

loadBuliding(){
  //此处不想使用默认的谷歌地图影像,所以使用此url指定ArcGIS的在线影像地图
  let url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer";
  let geogle = new Cesium.ArcGisMapServerImageryProvider({url:url});
  //此处填写你在cesium注册的token
  Cesium.Ion.defaultAccessToken='你的token';
  this.viewer= new Cesium.Viewer('cesiumContainer',{
    baseLayerPicker: false,         //是否显示图层选择控件
    selectionIndicator: false,
    // geocoder: false,                //是否显示地名查找控件
    // sceneModePicker: false,         //是否显示投影方式控件
    // navigationHelpButton: false,    //是否显示帮助信息控件
    // homeButton: false,              //是否显示Home按钮
    // fullscreenButton: false,        //是否显示全屏按钮
    // timeline:false,                 //时间轴控件
    // animation:false,                //动画控件
    imageryProvider:geogle,
    // terrainProvider:new Cesium.createWorldTerrain({
    //   requestVertexNormals:true,
    //   requestWaterMask:true
    // }),
  });
  //用来设置相机的观看方向
  let initialPosition = Cesium.Cartesian3.fromDegrees(
    -74.01881302800248,
    40.69114333714821,
    -20
  );
  //设置相机镜头对准的方法
  let initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(
    21.27879878293835,
    -21.34390550872461,
    0.0716951918898415
  );
  this.viewer.camera.setView({
    destination: initialPosition,
    orientation: initialOrientation,
    endTransform: Cesium.Matrix4.IDENTITY,
  });
  //通过id进行加载 此处New York City 3D Buildings 为 75343
  let city= new Cesium.Cesium3DTileset({url:Cesium.IonResource.fromAssetId(75343)});
  this.viewer.scene.primitives.add(city);
  //使不同高度展现不同颜色
  let heightStyle = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        ["${Height} >= 300", "rgba(45, 0, 75, 0.5)"],
        ["${Height} >= 200", "rgb(102, 71, 151)"],
        ["${Height} >= 100", "rgb(170, 162, 204)"],
        ["${Height} >= 50", "rgb(224, 226, 238)"],
        ["${Height} >= 25", "rgb(252, 230, 200)"],
        ["${Height} >= 10", "rgb(248, 176, 87)"],
        ["${Height} >= 5", "rgb(198, 106, 11)"],
        ["true", "rgb(127, 59, 8)"],
      ],
    },
  });
  city.style = heightStyle;
},

效果如下:

image.png

image.png

三 加载gltf模型

loadGlTF(){
  this.viewer = new Cesium.Viewer("cesiumContainer", {
    animation: false, //是否创建动画小器件,左下角仪表
    baseLayerPicker: false, //是否显示图层选择器
    fullscreenButton: false, //是否显示全屏按钮
    geocoder: false, //是否显示geocoder小器件,右上角查询按钮
    homeButton: false, //是否显示Home按钮
    infoBox: false, //是否显示信息框
    sceneModePicker: true, //是否显示3D/2D选择器,与scene3DOnly不能同时为true
    selectionIndicator: false, //是否显示选取指示器组件
    timeline: false, //是否显示时间轴
    navigationHelpButton: false, //是否显示右上角的帮助按钮
    scene3DOnly: false, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
    terrainProvider:new Cesium.createWorldTerrain({
      requestVertexNormals:true,
      requestWaterMask:true
    }),
  });
  let scene = this.viewer.scene;
  //关键代码
  let modelMatrix = new Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(113.40, 34.32, 6.0));//gltf数据加载位置(自定义)
  let model = scene.primitives.add(new Cesium.Model.fromGltf({
    url: './scene.gltf', //gltf文件的URL
    modelMatrix: modelMatrix,
    scale: 1400.0     //放大倍数
  }));
  this.viewer.camera.setView({
    destination: new Cesium.Cartesian3.fromDegrees(113.40, 34.32, 2500.0),   //相机飞入点
    orientation:{
      heading: Cesium.Math.toRadians(90.0),  //左右摆头
      pitch: Cesium.Math.toRadians(-40),  //上下抬头
      roll:0.0
    }
  });
  // 限制相机的高度最小值
  // this.viewer.scene.screenSpaceCameraController.minimumZoomDistance = 2500;
  // 设置相机缩小时的速率
  //this.viewer.scene.screenSpaceCameraController._minimumZoomRate = 30000; // 设置相机缩小时的速率
},

效果如下:

image.png

四 加载采集的3DTiles数据

首页你需要有一组3DTiles数据,并且将数据整体放到服务上以至于可以通过url进行访问(以json文件为入口,进行读取加载)

init3DTilesJson(){
  let url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer";
  let geogle = new Cesium.ArcGisMapServerImageryProvider({url:url});
  Cesium.Ion.defaultAccessToken='你的token
  this.viewer = new Cesium.Viewer('cesiumContainer',{
    imageryProvider:geogle,
    baseLayerPicker: false,         //是否显示图层选择控件
    selectionIndicator: false,
    geocoder: false,                //是否显示地名查找控件
    sceneModePicker: false,         //是否显示投影方式控件
    navigationHelpButton: false,    //是否显示帮助信息控件
    homeButton: false,              //是否显示Home按钮
    fullscreenButton: false,        //是否显示全屏按钮
    timeline:false,                 //时间轴控件
    animation:false,                //动画控件
    terrainProvider:new Cesium.createWorldTerrain({
      requestVertexNormals:true,
      requestWaterMask:true
    }),
  });
  //开启地下可视化调整高度
  // this.viewer.scene.screenSpaceCameraController.enableCollisionDetection = false;
  // this.viewer.scene.globe.translucency.enabled=true;
  // this.viewer.scene.globe.depthTestAgainstTerrain = true;
  //相机最低高度
  // this.viewer.scene.screenSpaceCameraController.minimumZoomDistance = 200;
  //相机最高高度
  // this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 800;
  // 设置相机缩小时的速率
  //this.viewer.scene.screenSpaceCameraController._minimumZoomRate = 30000; // 设置相机缩小时的速率
  //隐藏地球
   this.viewer.scene.globe.show = false;
  //隐藏logo
  this.viewer.cesiumWidget.creditContainer.style.display = "none";
  //监听渲染,调整模型位置大小
  let palaceTileset= new Cesium.Cesium3DTileset({url:'你的3DTiles文件'})
  palaceTileset.readyPromise.then(palaceTileset=>{
    //添加到场景
    this.viewer.scene.primitives.add(palaceTileset);
    let longitude = 121.502325; //模型需要改变的经度(自定义,任意值)
    let latitude = 31.238165; //模型需要改变的纬度(自定义,任意值)
    let heightOffset = 10; //模型需要改变的高度(根据3DTiles调整,此次调整为10)
    //获取3Dtlies的bounds范围
    let boundingSphere = palaceTileset.boundingSphere;
    //获取3Dtlies的范围中心点的弧度
    let cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
    //定义3Dtlies改变之后中心点的弧度
    let offsetvalue = Cesium.Cartographic.fromDegrees(longitude, latitude, heightOffset);
    //模型本身的位置
    let surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
    //模型改变的位置
    let offset = Cesium.Cartesian3.fromRadians(offsetvalue.longitude, offsetvalue.latitude, heightOffset);
    //定义模型的改变状态
    let translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
    //修改模型的位置
    palaceTileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    //异步设置摄像机以查看提供的一个或多个实体或数据源。
    this.viewer.zoomTo(palaceTileset, new Cesium.HeadingPitchRange(0.5, -0.2, palaceTileset.boundingSphere.radius * 1.0));
  })
},

效果如下:

image.png 此处需要注意的是:

  1. 背景为星空黑色是因为我把地球隐藏了。
  2. 当地球未被隐藏的时候你可能在地球表面找不到你的模型,大概率是因为高度没有设置对,模型在地下。这时候你需要开启地下可视化来调整模型高度(heightOffset)
  3. 一个完整的3DTiles文件格式如下

image.png

使用时的url应该是如下格式:http://xxxxxxxx:xx/xxx.json 以json文件为入口

推荐阅读