Cesium开发入门

Cesium

四大核心类

Viewer

查看器类 展示三维要素内容的主要窗口

    const viewer = new Cesium.Viewer("cesiumContainer", {
        scene3DOnly: true,
        selectionIndicator: true,
        baseLayerPicker: false,
        animation:false,
        timeline:false
    });

Scene

场景类 是所有3D对象的容器,是在 viewer 内部隐式创建的 scene 可以对整个场景环境进行修改,如地球的显示隐藏、光照强度、地球的图层样式、地形数据、绘制几何体点线面、场景的交互,如鼠标对场景的控制

    // 加载图层
    // viewer.imageryLayers.remove(viewer.imageryLayers.get(0))
    // viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({assetId:3954}))

    // 加载地形
    viewer.terrainProvider = Cesium.createWorldTerrain({
        requestWaterMask:true,
        requestVertexNormals:true
    })
    viewer.scene.globe.depthTestAgainstTerrain = true;

    // 激活太阳光照射
    // viewer.scene.globe.enableLighting = true

	// 设置相机视角
    // Create an initial camera view
    var initialPosition = new Cesium.Cartesian3.fromDegrees(-73.998114468289017509, 40.674512895646692812, 2631.082799425431);
    var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306);
    var homeCameraView = {
        destination : initialPosition,
        orientation : {
            heading : initialOrientation.heading,
            pitch : initialOrientation.pitch,
            roll : initialOrientation.roll
        }
    };
    // Set the initial view
    viewer.scene.camera.setView(homeCameraView);

Entity

实体类 用于构造复杂额、时间动态可视化的结构,与静态数据自然的结合在一起。在使用中主要用于加载实体模型,几何图形,对其进行样式设置,动态修改等

    // entity
    const entity = viewer.entities.add({
        position:Cesium.Cartesian3.fromDegrees(116.39,39.91,400),
        point:{
            pixelSize:100,
            color:new Cesium.Color(0,1,0,1)
        }
    })
    viewer.trackedEntity = entity

DataSourceCollection

数据源集合类,是 Cesium 中加载矢量数据的主要方式之一,支持加载矢量数据集和外部文件的调用
主要有三种调用方法:CzmlDataSource KmlDataSource GeoJsonDataSource

    var geocachePromise = Cesium.KmlDataSource.load('./SampleData/kml/bikeRide.kml', kmlOptions);
    // Add geocache billboard entities to scene and style them
    geocachePromise.then(function(dataSource) {
        // Add the new data as entities to the viewer
        viewer.dataSources.add(dataSource);
    });

Cesium坐标系

  1. WGS84 经纬度坐标系(没有实际的对象)

  2. WGS84 弧度坐标系(Cartographic)

    弧度 = π/180 × 经纬度角度

    经纬度角度 = 180/π × 弧度

    new Cesium.Cartographic(longitude,latitude,height)
    // 经纬度转弧度
    var radians = Cesium.CesiumMath.toRadians(degrees)
    // 弧度转经纬度
    var degrees = Cesium.CesiumMath.toDegrees(radians)
    // WGS84 经纬度坐标和WGS84 弧度坐标系(Cartographic)的转换
    // 1、构造函数法
    new Cesium.Cartographic(longitude弧度,latitude弧度,height米)
    // 2、静态函数法
    var cartographic = Cesium.Cartographic.fromDegrees(longitude经度latitude纬度,height:)
    var cartographic = Cesium.Cartographic.fromRadians(longitude弧度,latitude弧度,height米)
    
    // WGS84 坐标系和笛卡尔空间直角坐标系(Cartesian3)的转换
    // 1、WGS84 转为笛卡尔空间直角坐标系
    // 直接转换
    var cartesian3 = Cesium.Cartesian3.fromDegrees(longitude,latitude,height);
    var cartesian3 = Cesium.Cartesian3.fromDegreesArray(coordinates);
    coordinates格式为不带高度的数组。例如:[-278.0,66.0,-123.0,55.0]
    var cartesian3s = Cesium.Cartesian3.fromDegreesArrayHeights(coordinates);
    coordinates格式为带有高度的数组。例如:[-278.0,66.0,6000.0,-318,65.0,120000.0]
    // 间接转换
    var wgs84 = Cesium.Cartographic.fromDegrees(longitude经度,latitude纬度,height);
    var wgs84 = Cesium.Cartographic.fromRadians(longitude弧度,latitude弧度,height);
    var cartesian3 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(wgs84);
    var cartesian3s = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray([wgs84_1,wgs84_2,wgs84_3])
    // 2、笛卡尔空间直角坐标系转换为 WGS84
    // 直接转换
    var cartographic = Cesium.Cartographic.fromCartesian(cartesian3)
    var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3)
    var cartographics = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray([cartesian1,cartesian2,cartesian3])
    
  3. 笛卡尔空间直角坐标系(Cartesian3)

    new Cesium.Cartographic3(x,y,z)
    // 平面坐标系(Cartesian2)和笛卡尔空间直角坐标系(Cartesian3)的转换
    // 平面坐标系转笛卡尔空间直角坐标系
    // 1、屏幕坐标转场景 WGS84 坐标,包含了地形、倾斜、模型的坐标
    var cartesian3 = viewer.scene.pickPosition(Cartesian2)
    // 2、屏幕坐标转地表坐标
    var cartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(Cartesian2),viewer.scene);
    // 3、屏幕坐标转椭球面坐标,是参考椭球 WGS84 坐标,不包含地形、模型、倾斜摄影表面
    var cartesian3 = viewer.scene.camera.pickEllipsoid(Cartesian2)
    
  4. 平面坐标系(Cartesian2)

    new Cesium.Cartographic2(x,y)
    // 笛卡尔空间直角坐标系转平面坐标系
    var cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,cartesian3)
    
  5. 4D 笛卡尔坐标系(Cartesian4)

Cesium 的相机系统

在三维中需要确定视点位置和视线方向

// setView 方法,通过定义相机飞行目的地的三维坐标和视线方向,将视角直接切换到所设定的视域范围内
const position = Cesium.Cartesian3.fromDegrees(116.39,39.91,400)
viewer.camera.setView({
    destination:position,
    orientation:{
        heading:Cesium.Math.toRadians(0),//x 轴旋转
        pitch:Cesium.Math.toRadians(-90),//y 轴旋转
        roll:0//z 轴旋转
    }
})

// flyTo 方法,具有空中飞行逐步切换视域的效果,还可以设置飞行时间
const position = Cesium.Cartesian3.fromDegrees(116.39,39.91,400)
viewer.camera.flyTo({
    destination: position,
    orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: 0
    },
    duration:5
})

// lookAt 方法,将视角跳转到设置的目的地上,通过鼠标旋转视角方向是不会改变其位置的
const center = Cesium.Cartesian3.fromDegrees(116.39, 39.91)
// 设置一个水平旋转视口方向
const heading = Cesium.Math.toRadians(50)
// 设置一个垂直旋转视口的角度
const pitch = Cesium.Math.toRadians(-90)
// 设置相机距离目标点的高度
const range = 2500
// lookAt 一般用于锁定某个场景的视角
viewer.camera.lookAt(center,new Cesium.HeadingPitchRange(heading,pitch,range))

// viewBoundingSphere 视角切换效果与 setView 一样,没有飞行过渡效果,而是直接切换视口到指定目的地。当需要对一个物体进行多角度观测或者建筑物进行定点漫游时使用此方法
const position = Cesium.Cartesian3.fromDegrees(116.39,39.91,400)
const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, new Cesium.HeadingPitchRoll(-90, 0, 0))
    const entity = viewer.entities.add({
        position: position,
        orientation: orientation,
        model: {
            uri: "./SampleData/models/CesiumAir/Cesium_Air.glb",
            minimumPixelSize: 100,
            maximumScale: 10000,
            show: true
        }
    })
viewer.camera.viewBoundingSphere(new Cesium.BoundingSphere(position,20),new Cesium.HeadingPitchRange(0,0,0))

加载地图、地形

// 加载地图
const esri = new Cesium.ArcGisMapServerImageryProvider({
    url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
})
const viewer = new Cesium.Viewer('cesiumContainer', {
    baseLayerPicker: false,
    imageryProvider: esri,
    animation: false,
    timeline: false,
    // 加载地形
    terrainProvider:new Cesium.CesiumTerrainProvider({
        url:Cesium.IonResource.fromAssetId(1),
        // 增加法线提高光照效果
        requestVertexNormals:true,
        // 增加水面特效
        requestWaterMask:true
    })
})
// 加载图层
const layer = viewer.imageryLayers.addImageryProvider(
   new Cesium.IonImageryProvider({assetId: 3812})
);

加载建筑物模型

// 加载建筑物信息
// primitives 属性用于获取大量的基元集合
// const tileset = viewer.scene.primitives.add(
//     new Cesium.Cesium3DTileset({
//         url: Cesium.IonResource.fromAssetId(96188),
//     })
// );

// 加载包含高度数据的建筑物
const tileset = viewer.scene.primitives.add(
    new Cesium.Cesium3DTileset({
        url: Cesium.IonResource.fromAssetId(75343),
    })
);

// 添加相机信息
viewer.camera.setView({
    // destination: Cesium.Cartesian3.fromDegrees(121.49, 31.23, 3000),
    // orientation: {
    //     heading: 0,
    //     pitch: -90,
    //     poll: 0
    // }
    destination: new Cesium.Cartesian3(1333597.291762958, -4667718.246269587, 4147626.344790953),
    orientation: {
        heading: 0.8384333942956657,
        pitch: -1.299766516859664,
        ro11: 0.0
    }
})
// 设置模型样式
tileset.style = new Cesium.Cesium3DTileStyle({
    // color: "color('blue',0.5)",
    // show: true
    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)']
        ]
    },
    show: '${Height} >= 0'
})

空间数据加载

// 空间数据加载
const position = new Cesium.Cartesian3.fromDegrees(116.39, 39.91, 0)
// 加载原点
const pointEntity = viewer.entities.add({
    position: position,
    point: {
        pixelSize: 100,
        color: new Cesium.Color(1, 0, 0, 1)
    }
})
// 加载线条
const lineEntity = viewer.entities.add({
    polyline: {
        show: true,
        positions: new Cesium.Cartesian3.fromDegreesArray([116.39, 39.91, 116.40, 39.91]),
        width: 5,
        material: new Cesium.Color(0, 0, 1, 1)
    }
})
// 加载面
const planeEntity = viewer.entities.add({
    position: position,
    plane: {
        // 设置轴向沿着 z 轴平铺
        plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0.0),
        // 设置面的长度和宽度
        dimensions: new Cesium.Cartesian2(400, 300),
        // 面的颜色,也可以设置url加载图片等
        material: Cesium.Color.RED.withAlpha(0.5),
        // 显示边框
        outline: true,
        outlineColor: Cesium.Color.BLUE
    }
})
// 标签加载
const labelEntity = viewer.entities.add({
    position: position,
    label: {
        text: "hqzqaq",
        font: "50px Helvetica",
        fillColor: Cesium.Color.SKYBLUE
    }
})

空间数据管理

// 空间数据管理
const polygonEntity = viewer.entities.add({
    id:'polygonEntity',
    polygon:{
        hierarchy:Cesium.Cartesian3.fromDegreesArray([116.39,39.91,116.39,39.915,116.395,39.91]),
        material:Cesium.Color.GREEN,
        // 垂直方向拉伸
        extrudedHeight:200
    }
})
// 移除实体
// viewer.entities.remove(polygonEntity)
// 根据 id 获取实体,修改实体属性
viewer.entities.getById('polygonEntity').polygon.material = Cesium.Color.YELLOW
// 移除所有实体
viewer.entities.removeAll()

Cesium 鼠标交互

// cesium 鼠标交互
// 加载面
const position = new Cesium.Cartesian3.fromDegrees(116.39, 39.91, 0)
const planeEntity = viewer.entities.add({
    id: 'planeEntity',
    position: position,
    plane: {
        // 设置轴向沿着 z 轴平铺
        plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0.0),
        // 设置面的长度和宽度
        dimensions: new Cesium.Cartesian2(400, 300),
        // 面的颜色,也可以设置url加载图片等
        // material: Cesium.Color.RED.withAlpha(0.5),
        material: './SampleData/cesium_stripes.png',
        // 显示边框
        outline: true,
        outlineColor: Cesium.Color.BLUE
    },
    // 用于设置选定对象的显示信息
    description:'<div><img src="./SampleData/cesium_stripes.png" width="100%" height="300px"><h3>hqzqaq</h3></div>'
})
// 获取 scene 下所有 canvas 创建的元素
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
// 监听事件,第一个参数是回调函数,第二个参数表示监听鼠标的哪个事件
handler.setInputAction((movement) => {
    // 获取到点击对象的位置信息
    const pick = viewer.scene.pick(movement.position)
    if (Cesium.defined(pick) && (pick.id.id === 'planeEntity')) {
        alert('你已点击该区域')
    }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
// scene.pick 返回包含给定窗口位置基元的对象
// scene.drillpick 返回的是给定窗口位置所有对象的列表
// global.pick 返回的是给定光线和地形的交点
// Cesium.ScreenSpaceEventType.MIDDLE_CLICK Cesium.ScreenSpaceEventType.MOUSE_MOVE Cesium.ScreenSpaceEventType.RIGHT_CLICK

三维数据格式 3DTiles

是一种三维模型瓦片数据结构,将海量三维数据用分块、分层的形式组织起来。

特点:

  1. 开放性,可以根据实际需求设定三维模型的大小和范围
  2. 异质性,可以将不同类型的三维模型数据
  3. 专为三维可视化设计
  4. 可交互性,支持对加载模型的拾取和样式的修改

3D Tiles 格式文件代码详解

{
  "asset": {
    // 定义版本
    "version": "1.0",
    // 定义特定应用中的版本号
    "tilesetVersion": "1.2.3"
  },
  // 定义了一个非误差单位,低于这个误差值,瓦片集不会被渲染,单位为米
  "geometricError": 70,
  // 定义根瓦片
  "root": {
	// 在加载大量模型或建筑物的情况下,单个模型的点云瓦片集能在它自己的坐标系中定义,其内的数据是一个4x4仿射变换矩阵,以列主序存储,用来实现从瓦片局部坐标系到父瓦片或根瓦片坐标系的变换
    "transform": [
      -0.05105018459701556,
      0.9986960892346634,
      0,
      0,
      -0.7230889943688711,
      -0.036962021820761914,
      0.6897652609152887,
      0,
      0.6888658685660259,
      0.03521264389833409,
      0.7240330688818458,
      0,
      4401696.395347578,
      225000.79448064446,
      4595435.890447363,
      1
    ]// 当前瓦片集不被渲染的误差
    "geometricError": 0,
    // 定义 LOD 细化的方法,也就是瓦片如何切换
    "refine": "REPLACE",
    // 引入包含瓦片内容的文件
    "content": {
      "uri": "content.geom"
    }
    // 其子 tiles 文件
    "children": [
      {
        "boundingVolume": {
          "region": [
            -1.3197209591796106,
            0.6988424218,
            -1.31968,
            0.698874,
            0,
            20
          ]
        },
        "geometricError": 0,
        "content": {
          "uri": "ll.b3dm"
        }
      }]

加载 3D tiles 数据

// 三维数据格式 3DTiles
const tileset = viewer.scene.primitives.add(
    new Cesium.Cesium3DTileset({
        url:"./SampleData/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/tileset.json",
        // 最大的屏幕空间误差,数字越低,视觉效果越好
        maximumScreenSpaceError:2,
        // 最大加载瓦片个数
        maximumNumberOfLoadedTiles:1000
    })
)

动态数据格式 czml

是一种 json 数据格式,不仅方便交互,而且具有时间属性,即可以用于绘制各种几何图形,给定颜色、材质、透明度等,也可以根据实际的场景需求,放入动态的模型数据,还可以让 czml 中的属性跟随时间变化。

czml 数据结构

const czml = [
    // 声明为 czml 格式
    {
        id: "document",
        name: "box",
        version: "1.0",
    },
    // 几何模型数据
    {
        id: "shape1",
        name: "Blue box",
        // 模型位置信息
        position: {
            cartographicDegrees: [-114.0, 40.0, 300000.0],
        },
        // 几何体形状
        box: {
            // 尺寸信息
            dimensions: {
                cartesian: [400000.0, 300000.0, 500000.0],
            },
            // 设置几何体的材质颜色
            material: {
                solidColor: {
                    color: {
                        rgba: [0, 0, 255, 255],
                    },
                },
            },
        },
    }
];

caml 轨迹数据处理

[
  {
    "id": "document",
    "version": "1.0",
    // 用于设定时间相关的数据,是构建动态轨迹场景必不可少的元素
    "clock": {
      // 设置运行的起止时间 ISO 8601 规范表示,用这个方法不需要进行时差计算,也不需要换算去协调世界时
      "interval": "2018-07-19T15:18:00Z/2018-07-19T15:18:30Z",
      // 设置当前时间节点
      "currentTime": "2018-07-19T15:18:00Z",
      // 设置时间速率
      "multiplier": 5,
      "range": "LOOP_STOP",
      "step": "SYSTEM_CLOCK_MULTIPLIER"
    }
  },
  // 汽车模型数据
  {
    "id": "CesiumMilkTruck",
	// 加载模型数据
    "model": {
      "gltf": "models/CesiumMilkTruck/CesiumMilkTruck.glb"
    },
    // 模型位置信息,将自动与 clock 中设置的时间信息关联起来,使时刻与坐标点相对应,从而实现动态轨迹效果
    "position": {
      // 设置的是插值算法
      "interpolationAlgorithm": "LINEAR",
      // 防止出现设定数值超出样本数据范围的情况
      "forwardExtrapolationType": "HOLD",
      // 时间、经纬度、高度
      "cartesian": [
        "2018-07-19T15:18:00Z",
        1216348.1632364073,
        -4736348.958775471,
        4081284.5528982095,
        "2018-07-19T15:18:30Z",
        1216369.1229444197,
        -4736377.467107148,
        4081240.888485707
      ]
    },
    // 模型方向信息,可替换为 "velocityReference":"#posiion",cesium 会根据位置信息进行四元数方向转换,从而达到模型在运动时方向转换的效果
    "orientation": {
      "unitQuaternion": [
        0.3084011337938999,
        0.3210181022701266,
        -0.45850421987074924,
        0.7686388857813198
      ]
    }
  },
  // 行驶轨迹线
  {
    "id": "Polyline",
    "polyline": {
      "positions": {
        "cartesian": [
          1216348.1632364073,
          -4736348.958775471,
          4081284.5528982095,
          1216369.1229444197,
          -4736377.467107148,
          4081240.888485707
        ]
      },
      "material": {
        "polylineOutline": {
          "color": {
              "rgba": [255, 255, 0, 255]
          },
          "outlineColor": {
              "rgba": [0, 0, 0, 255]
          },
          "outlineWidth": 2
        }
      },
      "width": 10,
      // 紧贴地面
      "clampToGround": true
    }
  }
]

引入数据

// czml 动态数据
viewer.dataSources.add(Cesium.CzmlDataSource.load('./SampleData/ClampToGround.czml'))
    .then((dataSource) => {
    viewer.trackedEntity = dataSource.entities.getById('CesiumMilkTruck')
})
// 如果需要设置动画循环播放,需要在 viewer 初始化时增加属性 shouldAnimate: true

Cesium 的时间系统

// cesium 的时间系统
// 设置初始化页面自动循环播放
viewer.clock.shouldAnimate = true
// 设置播放速率
viewer.clock.multiplier = 10
// 设置时间线
let start = Cesium.JulianDate.fromIso8601('2022-07-15')
let end = Cesium.JulianDate.fromIso8601('2022-07-20')
viewer.timeline.zoomTo(start, end)

Cesium 的粒子系统

是一种模拟复杂物理效应的图形技术,是由很多的小图像组成的集合,形成一个模糊的对象,从而产生特效。例如烟花燃放的特效、天气效果的展示、汽车的尾气等。

// cesium 的时间系统
// 设置初始化页面自动循环播放
viewer.clock.shouldAnimate = true
// 设置播放速率
viewer.clock.multiplier = 10
// 设置时间线
let start = Cesium.JulianDate.fromIso8601('2022-07-15')
let end = Cesium.JulianDate.fromIso8601('2022-07-20')
viewer.timeline.zoomTo(start, end)

const position = Cesium.Cartesian3.fromDegrees(116.39, 39.91, 1500)
const planeEntity = viewer.entities.add({
    position: position,
    orientation: Cesium.Transforms.headingPitchRollQuaternion(position, new Cesium.HeadingPitchRoll(-90, 0, 0)),
    model: {
        uri: './SampleData/models/CesiumAir/Cesium_Air.glb',
        minimumPixelSize: 100,
        maximumScale: 10000,
        show: true
    }
})
viewer.camera.viewBoundingSphere(new Cesium.BoundingSphere(position, 20), new Cesium.HeadingPitchRange(0, 0, 0))

// cesium 的粒子系统
// 火焰粒子特效
// 先设置粒子样式,再通过粒子发射器发射粒子,控制粒子在一定时间内存在,然后消亡,并且可以使得粒子可以随着时间的推移,改变外观和行为
viewer.scene.primitives.add(new Cesium.ParticleSystem({
    image: './SampleData/fire.png',
    imageSize: new Cesium.Cartesian2(20, 20),
    // 粒子大小变化
    startScale: 1.0,
    endScale: 4.0,
    // 粒子存在时间
    particleLife: 3.0,
    speed: 5.0,
    // 发射器 0.5 设置的是圆的半径,粒子将会在圆的范围内随机向上发射粒子,还有 BoxEmitter 等
    emitter: new Cesium.CircleEmitter(0.5),
    // 每秒钟发射粒子的数量
    emissionRate: 5.0,
    // 设置粒子系统的位置,将粒子系统从模型转换为世界坐标的 4x4 转换矩阵
    // computeModelMatrix 在指定时间计算实体变换的模型矩阵
    modelMatrix: planeEntity.computeModelMatrix(viewer.clock.startTime, new Cesium.Matrix4()),
    lifetime: 16.0
}))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值