# cesium

# cesium基础配置

 const viewer = new Cesium.Viewer("cesiumContainer",
    { 
      // 地图的影像提供者(Imagery Provider)
      imageryProvider: new Cesium.UrlTemplateImageryProvider({
        url: 'xxxx',  //地图
        fileExtension: 'png'
      }),
      selectionIndicator: false,
      baseLayerPicker: false,  // 影像切换
      animation: false,  //是否显示动画控件
      timeline: true, //是否显示时间线控件
      infoBox: false, //是否显示点击要素之后显示的信息
      geocoder: false, //是否显示地名查找控件
      navigationHelpButton: false, //是否显示帮助信息控件
      sceneModePicker: false,// 禁用场景模式选择器,用户将不能通过UI来切换不同的视图模式(如3D、2D等)。
      homeButton: false,//禁用主页按钮,这个按钮通常用于将视图重置到初始状态。
      shadows:true,//禁用阴影渲染,这意味着在地球视图上不会渲染地形、建筑物等的阴影。
      contextOptions: {//这部分配置了WebGL上下文选项。
      //alpha: true允许WebGL渲染器生成包含透明度的画布,这对于需要透明背景的地图视图特别有用。
        webgl: {
          alpha: true,
        }
      }
    });

还可以单独配置

viewer.scene.mode = Cesium.SceneMode.SCENE3D
// Cesium.SceneMode.SCENE2D
//Cesium.SceneMode.COLUMBUS_VIEW 2.5d
  // 设置开启深度检测

  // 这行代码禁用了地形深度测试。在Cesium中,深度测试用于确定一个对象是否应该被另一个对象遮挡。
  // 当depthTestAgainstTerrain设置为false时,意味着图层(如图像层或3D模型)将不会被地形遮挡,
  // 这可能会导致图像层显示在地形之上,即使它们应该被地形遮挡。
  // 这通常用于特定的视觉效果,比如确保某些图层总是可见的。
  viewer.scene.globe.depthTestAgainstTerrain = false
  // 是否支持图像渲染像素化处理
  if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
    viewer.resolutionScale = window.devicePixelRatio
  }
  // 开启抗锯齿
  viewer.scene.postProcessStages.fxaa.enabled = true;
viewer.terrainProvider = Cesium.createWorldTerrain();
viewer.scene.sun.show = false; //在Cesium1.6(不确定)之后的版本会显示太阳和月亮,不关闭会影响展示
viewer.scene.moon.show = false;
viewer.scene.skyBox.show = true;//关闭天空盒,否则会显示天空颜色
viewer.scene.skyAtmosphere.show = true;  // 显示大气层
viewer.scene.skyAtmosphere.hueShift = -0.8;  // 色调偏移,取值范围为-1到1,-1表示完全偏向蓝色,1表示完全偏向红色
viewer.scene.skyAtmosphere.saturationShift = -0.7;  // 饱和度偏移,取值范围为-1到1,-1表示完全饱和,1表示完全不饱和
viewer.scene.skyAtmosphere.brightnessShift = -1;  // 亮度偏移,取值范围为-1到1,-1表示完全黑暗,1表示完全亮度
viewer.scene.undergroundMode = true; //重要,开启地下模式,设置基色透明,这样就看不见黑色地球了
// viewer.scene.underGlobe.show = true;
// viewer.scene.underGlobe.baseColor = new Cesium.Color(0.0, 0.0, 0.0, 0.0);
viewer.scene.globe.show = false; //不显示地球,这条和地球透明度选一个就可以,设置为true会看见图片外的范围的内容,如果设置false只展示一小块地图
viewer.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 0.0);

viewer.scene.globe.show设置不同展示不同

# 基于cesium1.99版本的一些配置

在vue项目中,为了体验更好,可以配置插件,在vite.config.js中配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cesium from 'vite-plugin-cesium';
export default defineConfig({
  plugins: [vue(),cesium()]
});

如果需要隐藏空间可以额外配置参数

# cesium转换坐标

 // 转换为笛卡尔坐标
const cartesian1 =  Cesium.Cartesian3.fromDegrees(110,20,20)
const cartesian2 =  Cesium.Cartesian3.fromDegrees(110,20,30)
// 转为弧度制
let cartographic = Cesium.Cartographic.fromCartesian(cartesian1)
// 角度制
let lon =Cesium.Math.toDegrees(cartographic.longitude)
let lat = Cesium.Math.toDegrees(cartographic.latitude)

# cesium相机

# cesium添加实体

组合实体

# cesium绘制多边形且添加点击事件

多边形和线之间多了层hierarchy嵌套

// 假设已经有一个Cesium.Viewer实例叫做`viewer`
 
// 定义多边形的顶点(经纬度)  
var polygonHierarchy = Cesium.Cartesian3.fromDegreesArray([  
        -115.0, 37.0,  
        -107.0, 37.0,  
        -107.0, 40.0,  
        -115.0, 40.0  
    ]);  

  // 创建一个多边形实体  
  var polygon = viewer.entities.add({  
      polygon: {  
          hierarchy: polygonHierarchy,  
          material: Cesium.Color.BLUE.withAlpha(0.5),  
          outline: true,  
          outlineColor: Cesium.Color.BLACK  
      }  
  });  
  viewer.zoomTo(polygon);
  // 为多边形添加点击事件  
  viewer.screenSpaceEventHandler.setInputAction(function(click) {  
      // 使用viewer.pick来检查点击位置下的实体  
      var pickedObject = viewer.scene.pick(click.position);  
      if (Cesium.defined(pickedObject) && pickedObject.id === polygon) {  
          console.log('多边形被点击');  
          // 在这里可以添加更多的处理逻辑  
      }  
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);  

# cesium生成盒子

      // 定义盒子的位置和尺寸
      var position = Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 0.0); // 洛杉矶的经纬度
      var dimensions = new Cesium.Cartesian3(400000.0, 300000.0, 500000.0); // 盒子的尺寸,单位为米

      // 创建一个BoxGraphics实例,用于定义盒子的图形属性
      var box = {
        box: {
          dimensions: dimensions,
          material: Cesium.Color.RED.withAlpha(0.5), // 盒子的材料和透明度
        },
      };

      // 创建一个Entity实例,将位置和BoxGraphics结合
      var entity = viewer.entities.add({
        name: "A red box",
        position: position,
        box: box.box,
      });

# cesium设置椭圆

 // 设置椭圆的位置和大小  
     var position = Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 0.0); // 经纬度  
        var semiMajorAxis = 200000.0; // 半主轴长度,单位通常是米  
        var semiMinorAxis = 100000.0; // 半短轴长度,单位通常是米  
  
        // 创建一个椭圆实体并添加到viewer的entities中  
        var ellipse = viewer.entities.add({  
            name: 'A blue ellipse',  
            position: position,  
            ellipse: {  
                semiMajorAxis: semiMajorAxis,  
                semiMinorAxis: semiMinorAxis,  
                material: Cesium.Color.BLUE.withAlpha(0.5),  
                height: 0, // 相对于地球表面的高度  
                extrudedHeight: 0, // 如果需要立体效果,可以设置一个大于0的值  
                granularity: 0.01 // 控制椭圆的精细度,通常不需要调整得太低  
            }  
        });  
  
        // 可选:缩放视图以包含椭圆  
        viewer.zoomTo(ellipse);   

# cesium动态绘制范围

仅仅是举例,业务根据需求修改

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./Cesium/Cesium.js"></script>
    <style>
      @import url(./Cesium/Widgets/widgets.css);
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="cesiumContainer"></div>
    <script type="module">
            Cesium.Ion.defaultAccessToken =
              "xxxx";
            const viewer = new Cesium.Viewer("cesiumContainer");
        
          let point,line,polygon

          var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
          let arr = []
          let index = 0
          // 设置一个点击事件监听器
          handler.setInputAction(function(click) {
          // 使用 viewer.scene.pick 来获取点击位置下的对象
          // 但我们更关心的是点击位置的经纬度,所以不需要这个对象的详细信息
          // 直接使用 viewer.camera.pickEllipsoid 来获取椭球体上的点
          var pickedPosition = viewer.camera.pickEllipsoid(click.position, viewer.scene.globe.ellipsoid);

          if (Cesium.defined(pickedPosition)) {
              // 将 Cartesian3 坐标转换为 Cartographic 坐标(经纬度)
              var cartographic = Cesium.Cartographic.fromCartesian(pickedPosition);

              // 转换为度单位
              var longitude = Cesium.Math.toDegrees(cartographic.longitude);
              var latitude = Cesium.Math.toDegrees(cartographic.latitude);
              arr.push(longitude.toFixed(6),latitude.toFixed(6))
              // 在控制台输出经纬度
              console.log('Longitude: ' + longitude.toFixed(6) + ', Latitude: ' + latitude.toFixed(6));
              console.warn(index)
              index++
              if(index===1){
                   point = viewer.entities.add({
                      position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
                      point: {
                          pixelSize: 10,
                          color: Cesium.Color.RED,
                          outlineColor: Cesium.Color.RED,
                          outlineWidth: 2
                      }
                  });
              }else if(index===2){
                  line =viewer.entities.add({
                      polyline: {
                          positions: Cesium.Cartesian3.fromDegreesArray(arr),
                          width : 3,  
                          material : Cesium.Color.GREEN  
                      }
                  })
                  point&&viewer.entities.remove(point)
              }
              else if(index >=3){
                 polygon&&viewer.entities.remove(polygon)
                 polygon = viewer.entities.add({
                  polygon: {
                    hierarchy: Cesium.Cartesian3.fromDegreesArray(arr),
                    material: Cesium.Color.RED.withAlpha(0.5),
                    outline: true,
                    outlineColor: Cesium.Color.BLACK,
                  },
                });
                point&&viewer.entities.remove(point)
                line&&viewer.entities.remove(line)
              }

              // 如果需要,你可以在这里使用经纬度来创建实体或进行其他操作
          }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    </script>
  </body>
</html>

# cesium事件移除监听

移除点击事件的监听器

function onClick(click) {  
    // 你的点击事件处理逻辑  
}  
  
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);  
handler.setInputAction(onClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);  
  
// 稍后,当你想要移除这个监听器时  
handler.removeInputAction(onClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);

移除全部handler监听

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);  
handler.setInputAction(function(click) {  
    // 你的点击事件处理逻辑  
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);  
  
// 稍后,当你想要停止所有监听时  
handler.destroy(); // 这将移除所有通过此 handler 添加的事件监听器

# cesiumcallvack

# cesium数据接入

var tileset,tilesetObjArr=[],modelMatrixArr = window.parent.modelMatrixArr,
  titleArr = window.parent.tilesetUrl,guideArr=window.parent.guideArr
  loadModelFun()
  function loadModelFun(paramsArr){ //传入的是不重复的模型地址
    console.warn(paramsArr)
    let modelTagArr=[], modelCount = 0,titleArr = []
    if(paramsArr){  //如果有新模型则用新模型处理
      titleArr = paramsArr
    }
    
    //加载附模型
    titleArr.map(function(item,index){
      let tilesetOption = {
        url: item.modelUrl,
        // 调整高度
        // maximumScreenSpaceError: 16,
        // maximumMemoryUsage: 512,
        // cullWithChildrenBounds: true,
        // maximumNumberOfLoadedTiles: 10, // 控制同时加载的瓦片数量
        skipLevelOfDetail: true,
        baseScreenSpaceError: 1024,
        skipScreenSpaceErrorFactor: 16000,
        skipLevels: 1,
        immediatelyLoadDesiredLevelOfDetail: false,
        loadSiblings: false,
        cullWithChildrenBounds: true,
        maximumMemoryUsage: 1, // 根据实际情况调整
        progressiveResolutionHeightFraction: 0.5,
        dynamicScreenSpaceErrorDensity: 0.5,
        dynamicScreenSpaceErrorFactor: 1,
        dynamicScreenSpaceError: true
      }
      if(item.modelLocationArray){
        tilesetOption = Object.assign(tilesetOption,{modelMatrix: Cesium.Matrix4.fromArray(eval(item.modelLocationArray))})
      }

      tilesetObjArr.push(new Cesium.Cesium3DTileset(tilesetOption))

      tilesetObjArr[tilesetObjArr.length-1].readyPromise.then(function (tileset) {
        callVueFun('mainView',{})   //vueFlyAround飞入效果,mainView到主视图

        viewer.scene.primitives.add(tileset, 0)
        //效果
        // 更换模型颜色
        tileset.readyPromise.then(function (tileset) {
          callVueFun('initModel',{})
          if(item.modelColor){
            tileset.style = new Cesium.Cesium3DTileStyle({
              color: {
                conditions: [
                  // ["${Height} < 60", "color('#13293D')"],
                  ["true", "color('"+item.modelColor+"',1)"]
                ]
              }
            });
          }else{
            item.modelColor = 'rgb(57,103,255)'
          }
          var boundingSphere = tileset.boundingSphere;
          // 获取模型中心点的笛卡尔坐标
          var center = boundingSphere.center;
          // 将笛卡尔坐标转换为地理坐标
          var cartographic = Cesium.Cartographic.fromCartesian(center);
          // 获取经纬度
          var longitude = Cesium.Math.toDegrees(cartographic.longitude);
          var latitude = Cesium.Math.toDegrees(cartographic.latitude);
          modelTagArr.push({deviceTypes:'model',moduleLocation:[longitude,latitude,0],moduleId:'model-'+item.id,moduleDeviceName:item.modelName,...item})
          modelTagArr.map(function(item,index){
            if(!$('#model-'+item.id).length){
              loadPicPoint(item)
            }
          })
        })
      })
    })

  }

# CesiumVectorTile

Cesium VectorTileImageryProvider支持小数据量的geojson、shape文件 矢量 动态切片,实现贴地

npm install cesiumvectortile
最后更新: 1/30/2025, 7:30:14 PM