// 初始化cesium场景
const viewer = new Cesium.Viewer(cesiumContainer.value, {
  infoBox: false, // 解决默认的控制台报错
  baseLayerPicker: false, // 去掉底图选择器
  sceneModePicker: false, // 去掉场景模式选择器 (3D,2D)
  homeButton: false, // 去掉起始点按钮
  geocoder: false, // 去掉地理代码搜索
  navigationHelpButton: false, // 去掉导航帮助按钮
  animation: false, // 取消动画按钮
  timeline: false, // 去掉时间线
  fullscreenButton: false, // 去掉全屏按钮
  selectionIndicator: false, // 去掉选择指示器
});
(viewer.cesiumWidget.creditContainer as HTMLDivElement).style.display = 'none'; // 去掉cesium的左下角logo区域
// 打印创建的viewer在控制台中
console.log(viewer);

cesium常见的坐标系

  • Cesium中常见的坐标系:
    1. 笛卡尔空间直角坐标系(Cartesian3)
    2. 平面坐标系(Cartesian2)
    3. WGS84弧度坐标系(Cartographic)。
  1. 笛卡尔坐标系(Cartesian3) 笛卡尔空间直角坐标又称为世界坐标,Cesium中用Cartesian3变量表示,可通过**new Cesium.Cartesian3(x, y, z)**创建,主要是用来做空间位置的变化如平移、旋转和缩放等等,它的坐标原点在椭球的中心。

  2. 平面坐标系(Cartesian2) 平面坐标系也就是平面直角坐标系,也称为屏幕坐标,是一个二维笛卡尔坐标系,与Cartesian3相比少了一个z的分量,new Cesium.Cartesian2(x, y)。Cartesian2经常用来描述屏幕坐标系,比如鼠标在电脑屏幕上的点击位置,返回的就是Cartesian2,返回了鼠标点击位置的xy像素点分量。

  3. WGS84弧度坐标系(Cartographic) Cesium中的地理坐标单位默认是弧度制,用Cartographic变量表示,可通过**new Cesium.Cartographic(longitude, latitude, height)**创建,其中这里的参数是用弧度表示的经纬度,即经度和纬度。弧度即角度对应弧长是半径的倍数。 角度转弧度 π/180×角度弧度变角度 180/π×弧度

笛卡尔空间直角坐标系

  1. 屏幕坐标(像素) 即二维笛卡尔平面坐标,我们通过鼠标点击直接获取的坐标就是屏幕坐标了,单位是像素值,也可以通过new Cesium.Cartesian2(x, y)创建。

  2. 笛卡尔空间直角坐标 笛卡尔空间直角坐标又称为世界坐标,Cesium中用Cartesian3变量表示,可通过new Cesium.Cartesian3(x, y, z)创建,主要是用来做空间位置的变化如平移、旋转和缩放等等,它的坐标原点在椭球的中心,如下图所示: alt

  3. 地理坐标(弧度) Cesium中的地理坐标单位默认是弧度制,用Cartographic变量表示,可通过new Cesium.Cartographic(longitude, latitude, height)创建,其中这里的参数是用弧度表示的经纬度,即经度和纬度。弧度即角度对应弧长是半径的倍数。 角度转弧度 π/180×角度弧度变角度 180/π×弧度

  • 数学上是用弧度而非角度,因为360的容易整除对数学不重要,而数学使用弧度更方便。角度和弧度关系是:2π弧度=360°。从而1°≈0.0174533弧度,1弧度≈57.29578°。

    1. 角度转换为弧度公式:弧度=角度÷180×π。
    2. 弧度转换为角度公式: 角度=弧度×180÷π。
  1. 经纬度坐标 即测绘中的地理经纬度坐标,默认是WGS84坐标系,坐标原点在椭球的质心。

经度:参考椭球面上某点的大地子午面与本初子午面间的两面角,东正西负。 纬度 :参考椭球面上某点的法线与赤道平面的夹角,北正南负。 Cesuim中没有具体的经纬度对象,**要得到经纬度首先需要计算为弧度,**再进行转换。Cesium提供了如下对应的转换方法:

Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result)

  • 用于将给定经纬度高程坐标转换为笛卡尔坐标系下的向量的函数。
  1. 该函数接受五个参数longitude、latitude、height、ellipsoid和result
  2. longitude和latitude是以度为单位的浮点数,表示地球表面上几何点所对应的经度和纬度。
  3. height是这个几何点的高程值(以海平面作为参考)。
  4. ellipsoid是一个可选参数,表示使用的椭球体,如果未提供,则使用WGS84椭球体。
  5. result是一个可选的Cartesian3对象,表示转换后的笛卡尔坐标系下的向量。
    1. 如果未提供result参数,则新创建一个Cartesian3对象,其中计算后的向量储存在其中,然后返回该对象。
  6. 该函数首先将经度和纬度转换为弧度,并根据该椭球体的参数计算该几何点的地心向径。使用此信息可以计算笛卡尔坐标,同时可将高度添加到Z分量中。

Cesium.HeadingPitchRoll(heading, pitch, roll)

  • Cesium.HeadingPitchRoll是一个定义方位、俯仰和滚转角度的类,该类用于描述3D物体的旋转状态。
    • 该类的构造函数使用三个参数heading,pitch和roll来分别定义目标物体绕Y轴的旋转角度(方位)、绕X轴的旋转角度(俯仰)和绕Z轴的旋转角度(滚转),并把它们存储在类的实例中以供使用。
  • 所有参数都是以弧度为单位的浮点数,且值在 -π到π之间。
    1. heading参数定义了绕Y轴旋转的角度,以正北方向为0度。
    2. pitch参数定义了物体绕X轴旋转的角度,以水平位置为0度,向上旋转为正,向下旋转为负。
    3. roll参数定义了物体绕Z轴旋转的角度,以输入的旋转方向的垂直方向为0度。
// 经纬度转弧度 
Cesium.Math.toRadians(degrees) 
// 弧度转经纬度
Cesium.Math.toDegrees(radians) 

Cesium中常用的坐标变换

经纬度坐标转笛卡尔坐标系

// 方法1:直接转换 lng=116.39366974823713, lat=39.9060622299375, height=31805.253837354827
 var cartesian1 = Cesium.Cartesian3.fromDegrees(lng, lat, height); 
 //cartesian1.x=-2188808.843329037,cartesian1.y=4410550.298005498
 //cartesian1.z=4090394.086155276

// 方法2:借助ellipsoid对象,先转换成弧度再转换 
var cartographic = Cesium.Cartographic.fromDegrees(lng, lat, height); //单位:度,度,米 
var cartesian3 = ellipsoid.cartographicToCartesian(cartographic); 

笛卡尔坐标系转经纬度

var cartographic = Cesium.Cartographic.fromCartesian(cartesian3); 
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lng = Cesium.Math.toDegrees(cartographic.longitude); 
var height = cartographic.height; 


弧度和经纬度互转

// 经纬度转弧度:

Cesium.Math.toRadians(degrees)  
 
// 弧度转经纬度:

Cesium.Math.toDegrees(radians)  

屏幕坐标和世界坐标互转

// 屏幕转世界坐标:

// 2.二维屏幕坐标转为三维笛卡尔空间直角坐标(世界坐标) 
var cartesian3 = scene.globe.pick(viewer.camera.getPickRay(windowPostion), scene );   
 
// 世界坐标转屏幕坐标:

// 三维笛卡尔空间直角坐标(世界坐标)转为二维屏幕坐标 
// 结果是Cartesian2对象,取出X,Y即为屏幕坐标。  
windowPostion = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian3);   
 

  1. 经纬度坐标转世界坐标 Cesium提供了两种方式将经纬度坐标转成世界坐标。
// 方法1:直接转换 
// var cartesian3 = Cesium.Cartesian3.fromDegrees(lng, lat, height); 
// 方法2:借助ellipsoid对象,先转换成弧度再转换 
var cartographic = Cesium.Cartographic.fromDegrees(lng, lat, height); //单位:度,度,米 
var cartesian3 = ellipsoid.cartographicToCartesian(cartographic); 
  1. 世界坐标转经纬度

// 3.笛卡尔空间直角坐标系转为地理坐标(弧度制) 
  var cartographic = Cesium.Cartographic.fromCartesian(cartesian3); 
// 方法1 
  var cartographic = ellipsoid.cartesianToCartographic(cartesian3); 
// 方法2 
// 4.地理坐标(弧度制)转为经纬度坐标
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lng = Cesium.Math.toDegrees(cartographic.longitude); 
var height = cartographic.height; 
  1. 弧度和经纬度互转
// 经纬度转弧度:

Cesium.Math.toRadians(degrees) 
// 弧度转经纬度:

Cesium.Math.toDegrees(radians) 
  1. 屏幕坐标和世界坐标互转
// 屏幕转世界坐标:

// 2.二维屏幕坐标转为三维笛卡尔空间直角坐标(世界坐标) 
var cartesian3 = scene.globe.pick(    viewer.camera.getPickRay(windowPostion),    scene ); 
// 注意这里屏幕坐标一定要在球上,否则生成出的cartesian对象是undefined。

世界坐标转屏幕坐标:

// 三维笛卡尔空间直角坐标(世界坐标)转为二维屏幕坐标 
// 结果是Cartesian2对象,取出X,Y即为屏幕坐标。  
windowPostion = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian3); 

坐标变换工具

只有转换到笛卡尔坐标系后才能运用计算机图形学中的仿射变换知识进行空间位置变换如平移旋转缩放。Cesium为我们提供了如下几种很有用的变换工具类:

  • Cesium.Cartesian3(相当于Point3D)
  • Cesium.Matrix3(3x3矩阵,用于描述旋转变换)
  • Cesium.Matrix4(4x4矩阵,用于描述旋转加平移变换)
  • Cesium.Quaternion(四元数,用于描述围绕某个向量旋转一定角度的变换)
  • Cesium.Transforms(包含将位置转换为各种参考系的功能)
<template>
  <!-- 作为cesium的container元素 -->
  <div class="cesium-container" ref="cesiumContainer"></div>
</template>
<script>
import { onMounted, ref } from 'vue'
import * as Cesium from 'cesium'

export default {
  name: "App",
  setup() {

    // 笛卡尔 坐标  
    /*
    经纬度 转换 笛卡尔坐标
    x: -555172.2535708158,
    y: 3148538.3084323616,
    z: -5500485.794192676
    */
    const carts = Cesium.Cartesian3.fromDegrees(100, 300, 10);
    console.log(carts);
    // 笛卡尔 转 弧度坐标
    const catt = Cesium.Cartographic.fromCartesian({
      x: -555172.2535708158,
      y: 3148538.3084323616,
      z: -5500485.794192676
    })

    /**
     
height: 9.999999999485878
latitude: -1.0471975511965979
longitude:  1.7453292519943295

     */
    console.log(catt);

    // 弧度转坐标
    let hight = Cesium.Math.toDegrees(-1.0471975511965979);
    let hightv = Cesium.Math.toDegrees(1.7453292519943295);

    console.log(hight, hightv);

    const cesiumContainer = ref();
    onMounted(() => {
      if (cesiumContainer) {
        console.log(cesiumContainer.value);
        // 初始化cesium场景
        const esri = new Cesium.ArcGisMapServerImageryProvider({
          url:
            'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer',
          enablePickFeatures: false
        })
        const viewer = new Cesium.Viewer(cesiumContainer.value, {
          timeline: false, // 时间轴
          animation: false, // 动画控件

          imageryProvider: esri,
          terrainProvider: Cesium.createWorldTerrain()
        });
        // 打印创建的viewer在控制台中
        // console.log(viewer);
      }
    })
    return {
      cesiumContainer
    }
  }
}

</script>

<style   scoped>
/* 让cesium-container撑满整个屏幕 */
.cesium-container {
  width: 100%;
  height: 100%;
}
</style>


相机

设置视角
  • heading: 偏航角,默认方向为正北(0°),正角度为向东旋转,即左右摇头。
  • pitch: 俯仰角,默认角度为-90°,即朝向地面,0°为平视,正角度为仰视,负角度为俯视,即抬头低头。
  • roll: 翻转角,默认角度为0°,正角度向右旋转,负角度向左旋转,即左右歪头



 // Cesium.setView
const position = Cesium.Cartesian3.fromDegrees(114.21, 30.55, 600)
this.viewer.camera.setView({
    destination: position, // 相机位置
    orientation: {
        heading: Cesium.Math.toRadians(0), // 水平旋转  -正北方向
        pitch: Cesium.Math.toRadians(-90), // 上下旋转  --俯视朝向
        roll: 0 // 视口翻滚角度
    } 



// setView 通过定义相机目的地 (方向), 直接跳转到目的地
        viewer.camera.setView({
          destination: position
          ,orientation:{
            // 默认 (0, -90 ,0)
            heading:Cesium.Math.toRadians(0),
            pitch:Cesium.Math.toRadians(0),
            roll:Cesium.Math.toRadians(0)
          }
        })



        let position = Cesium.Cartesian3.fromDegrees(100, 20, 10000);
//  相机 切换视角,带飞行动画 可以设置 时间
        viewer.camera.flyTo({
          destination:position,
          orientation:{
            heading:Cesium.Math.toRadians(0),
            pitch:Cesium.Math.toRadians(0),
            roll:Cesium.Math.toRadians(0)
            
          },
          duration:3  // 过度时间  30 秒
        })




        // 将视角 固定在设定的点位上, 可以选择视角,但是 不能改变位置
        let position2 = Cesium.Cartesian3.fromDegrees(110, 20)
        viewer.camera.lookAt(
          position2,
          new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90), 20000)
        )
  • 获取当前视角参数
  • 获取当前屏幕中心的经纬度坐标、笛卡尔坐标、heading、pitch、roll参数。
function getCamera() {
        const camera = viewer.scene.camera
        const cartographic = Cesium.Cartographic.fromCartesian(camera.position)
        const x = Cesium.Math.toDegrees(cartographic.longitude)
        const y = Cesium.Math.toDegrees(cartographic.latitude)
        const z = cartographic.height
        let pt = Cesium.Cartographic.fromDegrees(x, y, z);
        let ellipsoid = viewer.scene.globe.ellipsoid;
        let cartesian3 = ellipsoid.cartographicToCartesian(pt);
        let objinfo = {
            "经度": x,
            "维度": y,
            "高度": z,
            "x": cartesian3.x,
            "y": cartesian3.y,
            "z": cartesian3.z,
            "heading": camera.heading,
            "pitch": camera.pitch,
            "roll": camera.roll
        }
        console.log(objinfo)
    }

点、线、面

  • 点的坐标,默认是地心坐标系,可使用我们更熟悉的经纬度来表示,转换方法是 new Cesium.Cartesian3.fromDegrees(经度,纬度,高程)
       /**
         * 点
         */
        let point = new Cesium.Entity({
          position:Cesium.Cartesian3.fromDegrees(100,200,10000),
          point: {
            pixelSize:20, // 图中的像素 px 
            color:Cesium.Color.BLUE
          }
        })
        viewer.entities.add(point)



        viewer.entities.add({
          position:Cesium.Cartesian3.fromDegrees(500,800),
          point:{
            pixelSize:30,
            color:Cesium.Color.RED
          }
        })

        
 

        // 随机的entity
        var entities = [];
        for (var lon = 114.0; lon < 114.1; lon += 0.01) {
          for (var lat = 30.0; lat < 30.1; lat += 0.01) {
            entities.push(viewer.entities.add({
              position: Cesium.Cartesian3.fromDegrees((lon + lon + 0.01) / 2, (lat + lat + 0.01) / 2, 10000),
              point: {
                pixelSize: 15,
                color: Cesium.Color.RED,
                outlineColor: Cesium.Color.WHITE,
                outlineWidth: 2,
                show: true
              }
            }));
          }
        }
       

标注 Billboard

  • 广告牌
  onMounted(() => {
      if (cesiumContainer) {

 

        // 添加标注  广告牌
        let billa = new Cesium.Entity({
          position: Cesium.Cartesian3.fromDegrees(100, 30, 10000),
          billboard: {
            image: '/src/assets/bz.png',
            scale: 0.1
          }
        });


        let zi = viewer.entities.add(billa);

        /**
         * 标题
         */
        let label = new Cesium.Entity({
          position: Cesium.Cartesian3.fromDegrees(100, 30, 1000),
          label: {
            text: '你好世界',
            fillColor: Cesium.Color.BLUE,
            showBackground: true
          }
        })
        let la = viewer.entities.add(label);

线

polyline 线的绘制参数

  • show 是否显示,true为显示,false为不显示,默认为显示

  • positions 线的坐标,为笛卡尔坐标系的地心坐标,可以有两种形式

一种是带高程值的,如Cesium.Cartesian3.fromDegreesArrayHeights([第1个点的经纬度高程, 第2个点的经纬度高程, ...])

另一种是不带高程的,只有经纬度,如Cesium.Cartesian3.fromDegreesArrayHeights([第1个点的经纬度, 第2个点的经纬度, ...]),此时的高程默认为0,可配合clampToGround参数让线贴地

  • arcType 线的地理类型,NONE表示纯直线,GEODESIC表示为测地线,RHUMB表示等角航线,默认为测地线
  • clampToGround 线是否贴地,默认为否。 clampToGround: true对于的效果,可见线都沿着地形绘制 测地线可理解为过球心的圆弧,表示球面上两点之间最短的距离,等角航线比较复杂,

多边形

polygon 多边形的绘制参数

  • hierarchy 多边形的坐标,为笛卡尔坐标系的地心坐标,可以有两种形式

一种是带高程值的,如Cesium.Cartesian3.fromDegreesArrayHeights([第1个点的经纬度高程, 第2个点的经纬度高程, ...]) ,如果想要高程值起作用,需设置perPositionHeight: true

另一种是不带高程的,只有经纬度,如Cesium.Cartesian3.fromDegreesArrayHeights([第1个点的经纬度, 第2个点的经纬度, ...]),此时的高程默认为0,可配合heightReference: Cesium.HeightReference.CLAMP_TO_GROUND参数让多边形贴地

  • height 多边形的高程,单位米,即便hierarchy设置了高程,只要perPositionHeight: false,多边形都会以height作为高程值,默认值为0,
  • heightReference 多边形的高程参考面,默认值为Cesium.HeightReference.NONE,表示使用绝对高程,如果想要多边形贴在地表,可设置为Cesium.HeightReference.CLAMP_TO_GROUND
  • extrudedHeight 多边形的外扩高程,默认值为0,当值不为0时,可形成多边形棱柱,即polygon可用来绘制几何体
/**
 * 线
 */
        let polyline = viewer.entities.add({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray([123, 20, 121, 20, 120, 20.5]),
            width: 10
          }
        })
let polyline = viewer.entities.add({
        name: "polyline",
        polyline: {
            show: true, //是否显示,默认显示
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                70, 40, 600000, 
                75, 30, 400000,
                120, 25, 200000
            ]),
            width: 2, //线的宽度(像素),默认为1
            granularity: Cesium.Math.RADIANS_PER_DEGREE,
            material: Cesium.Color.BLUE, //线的颜色,默认为白色
            // depthFailMaterial: Cesium.Color.RED, //线被遮挡部分的颜色,默认为空(不显示被遮挡的部分),设置后可显示被遮挡的部分
            arcType: Cesium.ArcType.NONE, //线的地理类型,NONE表示纯直线,GEODESIC表示为测地线,RHUMB表示等角航线,默认为测地线
            // arcType: Cesium.ArcType.GEODESIC,
            // arcType: Cesium.ArcType.RHUMB,
            clampToGround: false, //是否贴地,默认为否
            shadows: Cesium.ShadowMode.DISABLED, //是否显示光照阴影,默认为否
            // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(100.0, 2000000.0), //显示的视角距离条件,在该范围内显示,范围不显示,默认为空
            classificationType: Cesium.ClassificationType.BOTH,
            zIndex: 0, //显示深度,越大表示图层在上
        }
    }) 


        /**
         * 多边形
         */
        let dbx = viewer.entities.add({
          polygon: {
            height: 100000, // 地表高度
            extrudedHeight: 1000000, // 立体拉伸 高度
            hierarchy: {
              positions: Cesium.Cartesian3.fromDegreesArray([123, 20, 121, 20, 120, 20.5, 125, 40, 158, 40, 123, 20]),

            },
            outline: true, // 外包裹线   
            outlineColor: Cesium.Color.RED,
            fill: false // 是否填充

          }
        })


盒子 圆

        /**
         * 盒子 box
         */
        let box = viewer.entities.add({

          position: Cesium.Cartesian3.fromDegrees(118, 20, 10000),
          id: 'lusifer-uuid-box',
          box: {
            dimensions: new Cesium.Cartesian3(1000, 5000, 1000) // 长宽高
          }
        })
        // viewer.zoomTo(box)


        /**
         * 椭圆、 圆周率 Math。pi
         */

        let ellipse = viewer.entities.add({
          id: 'pi-001',
          position: Cesium.Cartesian3.fromDegrees(100, 20, 1000),
          ellipse: {
            semiMajorAxis: 5000,//	Property | number	<optional> 指定半长轴的数字属性。
            semiMinorAxis: 3000,
            height: 1000,
            rotation: Math.PI / 2 // 选择角度多边

          }
        })
        console.log(Math.PI);


        /**
         * 矩形
         */


        let rectangle = viewer.entities.add({
          rectangle: {
            coordinates: Cesium.Rectangle.fromDegrees(100, 20, 156, 50)
          }
        })

    
        viewer.zoomTo(rectangle);


      }

组合 坐标

 onMounted(() => {
      if (cesiumContainer) {
 
        viewer = new Cesium.Viewer(cesiumContainer.value, {
          timeline: false, // 时间轴
          animation: false, // 动画控件
          // imageryProvider: esri,
          terrainProvider: Cesium.createWorldTerrain({
            requestVertexNormals: true, //开启地形光照
          })
        });


        let bilbd = viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(120, 30, 100),
          billboard: {
            image: '/src/assets/bz.png',
            scale: 0.1,
            color: Cesium.Color.YELLOW
          }
        })
        //  114.21948 , 36.42566 0 

        let polyline = viewer.entities.add({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([120, 30, 0, 120, 30, 100])
          }
        })



        lab = viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(120, 30, 100),
          label: {
            text: '鼎峰.北城首府',
            font: '15px',
            fillColor: Cesium.Color.AQUA,
            pixelOffset: new Cesium.Cartesian2(0, -40)
          }
        })

        let ff = Cesium.Cartesian3.fromDegrees(114.21948, 36.42566, 1000);

        let ent = viewer.entities.add({
          position: ff,
          billboard: {
            image: '/src/assets/bz.png',
            scale: 0.1,
            color: Cesium.Color.YELLOW
          },
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([114.21948, 36.42566, 0, 114.21948, 36.42566, 1000])
          }, label: {
            text: '峰峰矿区',
            font: '15px',
            fillColor: Cesium.Color.AQUA,
            pixelOffset: new Cesium.Cartesian2(0, -40),
            showBackground: true
          }
        })

        // viewer.camera.flyTo({
        //   duration:5,
        //   destination:ff
        //   // ent
        // })
        viewer.zoomTo(ent);



      }
    })

动态效果CallbackProperty

函数介绍 Cesium提供了CallbackProperty函数来让我们构建动态变化的参数。该函数的官方文档说明如下,包含两个参数, callback是一个返回参数变量的函数,isConstant表示不同时刻的值是否一致,为布尔值,对于变化的情况为false。


        /**
         * Cesium.CallbackProperty  实现动态效果
         */
        let lon, lat, num = 0;
        let line = viewer.entities.add({
          polyline: {
            // positions: Cesium.Cartesian3.fromDegreesArray([120, 30, 121, 31]),
            positions: new Cesium.CallbackProperty(() => {
               num += 0.05;

              lon = num + 120;
              lat = num + 30;
              console.log(lon);
              

              /**
               * 停止
               * 给一个新的属性 对象值
               */
              if(lon < 121){

                return Cesium.Cartesian3.fromDegreesArray([120, 30, lon, lat]);
              }else{
                line.polyline.positions=Cesium.Cartesian3.fromDegreesArray([120, 30, 121, 31]);

              }
            }, false),
            width: 50,
            material: Cesium.Color.YELLOW
          }
        })


        viewer.zoomTo(line)



        
/**
 * callBackProperty 
 */
        let boxModel = viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(114.1, 116, 2000),
          box: {
            dimensions: new Cesium.CallbackProperty(() => {
              let height = Math.random() * 1000
              return new Cesium.Cartesian3(1000, 5000, height)
            }, false) // 长宽高
            , outline: true,
            outlineColor: new Cesium.CallbackProperty(() => {

              return Cesium.Color.BLUE;
            }, false)
          }
        })

        viewer.zoomTo(boxModel)


注册事件 ScreenSpaceEventHandler

var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function(movement) {
    var pick = scene.pick(movement.endPosition);
    if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
        // Output glTF node and mesh under the mouse.
        console.log('node: ' + pick.node.name + '. mesh: ' + pick.mesh.name);
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

scene.pickscene.pick之后需要判断的属性字段根据你的需求而定,这里我们关注的是model,所以判断model的属性是否存在。 scene.pick之后判断model的属性是否存在

 <html lang="en">
 
<body>
    <div id="cesiumContainer" style="position:fixed;left:0px;top:0px;width:100%;height:100%;"></div>
    <script>
     Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(100, -20, 120, 90);

    // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
    const viewer = new Cesium.Viewer('cesiumContainer', {
        geocoder:true,//控制右上角第一个位置的查找工具
        homeButton:true,//控制右上角第二个位置的home图标
        sceneModePicker:true,//控制右上角第三个位置的选择视角模式,2d,3d
        baseLayerPicker:true,//控制右上角第四个位置的图层选择器
        navigationHelpButton:true,//控制右上角第五个位置的导航帮助按钮
        animation:false,//控制左下角的动画器件
        timeline:false,//控制下方时间线
        fullscreenButton:false,//右下角全屏按钮
        vrButton:false,//右下角vr按钮
        shouldAnimate: true,//允许动画同步
        infoBox : true, //不显示点击要素之后显示的信息
        terrainProvider: Cesium.createWorldTerrain()
    });

    viewer._cesiumWidget._creditContainer.style.display="none";//取消版权信息
    
    // 定义第一个点,该点使用常规方法赋参数值
    let position1 = new Cesium.Cartesian3.fromDegrees(120, 25, 10000);
    let color1 = new Cesium.Color(1, 1, 0, 1); //黄色
    let point1 = viewer.entities.add({
        name: "point1",
        position: position1, // 点的经纬度坐标
        point: {
            show: true, //是否显示,默认显示
            pixelSize: 20, //点的大小(像素),默认为1
            color: color1, //颜色,默认为白色
        },
    })

    // 定义第二个点,该点使用回调函数赋参数值
    let position2 = new Cesium.Cartesian3.fromDegrees(120, 30, 100000);
    let color2 = new Cesium.Color(1, 0, 0, 1); //红色
    let point2 = viewer.entities.add({
        name: "point2",
        position: new Cesium.CallbackProperty(()=>{
            return position2;
        }, false), // 点的经纬度坐标
        point: {
            show: true, //是否显示,默认显示
            pixelSize: 20, //点的大小(像素),默认为1
            color: new Cesium.CallbackProperty(()=>{
                return color2;
            }, false), //颜色,默认为白色
        },
    })

    // let polygon1 = viewer.entities.add({
    //     name: "polygon1",
    //     polygon: {
    //         show: true,
    //         hierarchy: Cesium.Cartesian3.fromDegreesArray([
    //             120.0,
    //             40.0,
    //             124.0,
    //             40.0,
    //             122.0,
    //             42.0,
    //         ]),
    //         height: 50000,
    //         extrudedHeight: 100000,
    //         fill: true,
    //         material: Cesium.Color.RED,

    //         outline: true,
    //         outlineColor: Cesium.Color.BLACK,
    //         outlineWidth: 5.0,
    //     }
    // })

    let outline = true;
    let polygon2 = viewer.entities.add({
        name: "polygon2",
        polygon: {
            show: true,
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
                120.0,
                35.0,
                124.0,
                35.0,
                122.0,
                37.0,
            ]),
            height: 50000,
            extrudedHeight: 100000,
            fill: true,
            material: Cesium.Color.YELLOW,

            outline: new Cesium.CallbackProperty(()=>{
                return outline;
            }, false),
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 5.0,
        }
    })

    // 用于控制的变量
    let i = 0;
    let j = 1;

    // 每隔100毫秒修改一次参数
    setInterval(()=>{
        // 方法1:直接给entity的参数赋新值
        point1.position = new Cesium.Cartesian3.fromDegrees(120-1*i, 25, 100000);
        point1.point.color = new Cesium.Color(1, 1, 0, 0.1*i);
        // polygon1.polygon.outline = i%2 == 0? true:false;

        // 方法2: 修改参数对应的回调函数中的变量
        position2 = new Cesium.Cartesian3.fromDegrees(120-1*i, 30, 10000);
        color2 = new Cesium.Color(1, 0, 0, 0.1*i);
        outline = !outline;

        // 使变量间隔2秒重复
        if(i>=10){
            j = -1;
        }
        if(i<=0){
            j = 1;
        }

        i += j;
    }, 100) // point用100,polygon用1000

    </script>
</body>
</html>

贴地线

  • cesium在没有开启地形时,加载geojson线数据没有问题,不会出现拖动地图,线数据也发生变化的现象,
  • 但在开启地形以后再加载地形数据,由于地形不平整,所以部分线数据就可能会被地形覆盖遮挡,看起来就会断断续续;
  • 还有可能拖动地图,线数据也会跟着移动,

Entity方式贴地

    viewer.entities.add({
        polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray(line),//line要加载的线数据
            width: 10,//线宽
            clampToGround: true,//开启贴地
            material: Cesium.Color.RED//颜色
        }
    });
    //或者直接加载线数据地址,然后设置贴地即可
    var promise = Cesium.GeoJsonDataSource.load(urlLine, {
            clampToGround: true,//开启贴地
     });

primitive方式贴地

Primitive方式贴地, 需要使用GroundPolylinePrimitive和GroundPolylineGeometry来创建Primitive与Geometry对象,而不是使用Primitive和PolylineGeometry创建Primitive与Geometry对象,代码如下:

    viewer.scene.primitives.add(new Cesium.GroundPolylinePrimitive({
        geometryInstances: new Cesium.GeometryInstance({
            geometry: new Cesium.GroundPolylineGeometry({
                positions: Cesium.Cartesian3.fromDegreesArray(positions[i]),
                width: 15.0,//线宽
                vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT
            }),
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color.fromCssColorString("#0096ff")),
            }
        }),
        appearance: new Cesium.PolylineColorAppearance({
            translucent: false
        })
    }));