当前位置: 首页 > 工具软件 > s3viewer > 使用案例 >

Cesium笔记----关于viewer的配置及常用东西

邢寒
2023-12-01

关于viewer

一些基本配置

var viewer = new Cesium.Viewer('cesiumContainer', {
      animation: false, //左下角的动画仪表盘
      baseLayerPicker: false, //右上角的图层选择按钮
      geocoder: false, //搜索框
      homeButton: false, //home按钮
      sceneModePicker: false, //模式切换按钮
      timeline: false, //底部的时间轴
      navigationHelpButton: false, //右上角的帮助按钮,
      fullscreenButton: false, //右下角的全屏按钮
      infoBox: false,//小弹窗
      selectionIndicator: false,
      zoomIndicatorContainer: false,
      navigation: false,//指南针
      // shadows: true,//阴影
    })
    window.viewer = viewer

    var scene = viewer.scene
    //设置环境光(这是设置比较灰的)
    scene.lightSource.ambientLightColor = new Cesium.Color(0.4, 0.4, 0.4, 0.4);
    //开启颜色校正
    viewer.scene.colorCorrection.show = true;
    viewer.scene.colorCorrection.saturation = 1;
    viewer.scene.colorCorrection.brightness = 0.4;
    viewer.scene.colorCorrection.contrast = 1;
    viewer.scene.colorCorrection.hue = 0;
    //开启泛光和HDR
    viewer.scene.bloomEffect.show = true;
    viewer.scene.hdrEnabled = true;
    //隐藏底部logo
    viewer._cesiumWidget._creditContainer.style.display = 'none'
    //显示帧数
    // viewer.scene.debugShowFramesPerSecond = true;
    // viewer.extend(Cesium.viewerCesiumInspectorMixin)//调试工具
    //移除默认的双击事件
	viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    //fxaa
    // viewer.scene.postProcessStages.fxaa.enabled = true;
    //深度检测
    // viewer.scene.globe.depthTestAgainstTerrain = true;

关于layers

这个s3m图层的操作方式,可以设置选中效果,动态发光纹理,修改图层风格(颜色、透明度)

Cesium.when(promise, (layers) => {
	layers.forEach((res, i) => {
        // res.selectedColor = Cesium.Color.CYAN//选中颜色
        //动态自发光----HypsometricSetting
        res.selectedColor = ''//取消选中颜色
        var hyp = new Cesium.HypsometricSetting();
		setHypsometric(res);
		//设置自发光纹理
		function setHypsometric(layer) {
			hyp.emissionTextureUrl = "/static/img/speedline.jpg";
			hyp.emissionTexCoordUSpeed = 0.25;
			layer.hypsometricSetting = {
				hypsometricSetting: hyp,
			}
		};
		//获取图层风格-----style3D
        // var style = res.style3D;
        //设置图层风格
        var style3D = new Cesium.Style3D();
        var color = new Cesium.Color(1.0, 0.0, 0.0);
        style3D.fillForeColor = color;
        res.style3D = style3D;
        //设置后需刷新图层
        res.refresh();
})

关于事件

//鼠标单击事件
    var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas)
    handler.setInputAction(function (e) {
    ...
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

//注册鼠标点击事件----此方法获取要素集(须先查询data)
     viewer.pickEvent.addEventListener(function (feature) {
       console.log(feature)
     })
    
//监听相机改变事件
	viewer.scene.camera.changed.addEventListener(function () {
		var position = viewer.camera.position
        var cartographic = Cesium.Cartographic.fromCartesian(position)
	})

实体添加

添加实体方法就这样,只是不同对象里面的属性不同,具体可以看API文档就知道了。
new Cesium.CallbackProperty({})这个回调函数可以动态修改里面的属性,使用方法很多,也可也调用外部方法,只要返回值正确就行。

//entities
viewer.entities.add({
	  name: 'name',
      id: 'id',
      position: new Cesium.CallbackProperty(function () {
      //可用回调函数动态修改,实现动态效果
      ...
      return ...
      }, false),
      billboard: {
        image: 'URL',
        scale: 0.5,//缩放
        // width: 200,
        // height: 80,
        disableDepthTestDistance: Number.POSITIVE_INFINITY, //不被遮挡
        //可视距离范围
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(57, 210),
      },
    })
//primitives
//gltf
viewer.scene.primitives.add(Cesium.Model.fromGltf({
       id:'id',
       url:'XXX.glb',
       modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84,fixedFrameTransforms),
            }))
//其他
viewer.scene.primitives.add(new Cesium.Primitive({
       id:'id',
       geometryInstances:instance,
       appearance: new Cesium.MaterialAppearance({
         closed:false,
         material:material,
       }),
       show:true,
     }))
 

关于3dtileset

下面有附带纠偏的代码,泛光特效的代码(使用shader)
关于位置纠偏,之前尝试了很多办法,最近发现可以直接用矩阵实现,
Cesium.Cartesian3.fromDegrees()------ 将经纬度坐标转化成世界坐标
Cesium.Transforms.eastNorthUpToFixedFrame()--------- 计算一个从4x4变换矩阵到从以提供的原点为中心的东北向上轴的参考框架到提供的椭球的固定参考框架。
Cesium.Matrix4.multiplyByUniformScale()-------控制缩放
tileset._root.transform = mtx;
以上代码需放在tileset.readyPromise.then里面,不然会报错。

//3dtileset
//添加白模
    var tileset = viewer.scene.primitives.add(
      new Cesium.Cesium3DTileset({
        url: 'XXX.json',
      })
    )
    //位置纠偏
    tileset.readyPromise.then(function (tileset) {
      viewer.scene.primitives.add(tileset)
      var position = Cesium.Cartesian3.fromDegrees(...)
      var mtx = Cesium.Transforms.eastNorthUpToFixedFrame(position);
      Cesium.Matrix4.multiplyByUniformScale(mtx,1,mtx);//缩放
      tileset._root.transform = mtx;
      
      
//白膜渐变色,动态泛光线条
	tileset.style = new Cesium.Cesium3DTileStyle({
        color: {
          conditions: [
            ['true', 'rgba(0, 127.5, 255 ,0.8)']//'rgb(127, 59, 8)']
            // ['true', 'rgba(127,59,8 ,0.5)']
            
          ]
        }
      });
	tileset.tileVisible.addEventListener(function (tile) {
        var content = tile.content;
        var featuresLength = content.featuresLength;
        for (var i = 0; i < featuresLength; i += 2) {
          let feature = content.getFeature(i)
          let model = feature.content._model

          if (model && model._sourcePrograms && model._rendererResources) {
            Object.keys(model._sourcePrograms).forEach(key => {
              let program = model._sourcePrograms[key]
              let fragmentShader = model._rendererResources.sourceShaders[program.fragmentShader];
              let v_position = "";
              if (fragmentShader.indexOf(" v_positionEC;") != -1) {
                v_position = "v_positionEC";
              } else if (fragmentShader.indexOf(" v_pos;") != -1) {
                v_position = "v_pos";
              }
              const color = `vec4(${feature.color.toString()})`;

              model._rendererResources.sourceShaders[program.fragmentShader] =
                "varying vec3 " + v_position + ";\n" +
                "void main(void){\n" +
                "    vec4 position = czm_inverseModelView * vec4(" + v_position + ",1);\n" +
                "    float glowRange = 360.0;\n" +
                "    gl_FragColor = "+color+";\n"+
                // "    gl_FragColor = vec4(0.2,  0.5, 1.0, 1.0);\n" +
                "    gl_FragColor *= vec4(vec3(position.z / 100.0), 1.0);\n" +
                "    float time = fract(czm_frameNumber / 300.0);\n" +//线框浮动速度
                "    time = abs(time - 0.5) * 2.0;\n" +
                "    float diff = step(0.005, abs( clamp(position.z / glowRange, 0.0, 1.0) - time));\n" +
                "    gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - diff);\n" +
                "}\n"
            })
            model._shouldRegenerateShaders = true
          }
        }
      });

常用方法

viewer.camera.setView({
     destination: Cesium.Cartesian3.fromDegrees(),
     orientation: {
       heading: Cesium.Math.toRadians(50),
       pitch: Cesium.Math.toRadians(-5),
       roll: 0,
     },
   })

viewer.camera.flyTo({
          destination: new Cesium.Cartesian3.fromDegrees(),
          orientation: {
            heading: Cesium.Math.toRadians(0),
            pitch: Cesium.Math.toRadians(0),
            roll: 0.0,
          },
        })

关于弹窗

样式没贴了,自己写样式把。

var el = document.getElementById('pbubble');
el.style.display='block'
            viewer.scene.postRender.addEventListener(function () {
              // 每一帧都去计算气泡的正确位置
              if (position) {
                var canvasHeight = scene.canvas.height
                var windowPosition = new Cesium.Cartesian2()
                Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, position, windowPosition)
                el.style.bottom = canvasHeight - windowPosition.y + 45 + 'px'
                el.style.left = windowPosition.x - 70 + 'px'
                el.style.visibility = 'visible'
                el.innerHTML="总车位12<br>剩余10"
              }
            })
 类似资料: