Cesium开发教程

项目初始化

创建Vue3项目,并导入Cesium

Vue3 项目创建

  1. Node.js的版本在16.0及以上。
  2. 打开命令窗口,运行创建项目命令
npm init vue@latest
  1. 按照自己需求进行配置选择
  2. 之后提示命令窗口提示运行
cd "项目名称"
npm install
npm run format
npm run dev

配置Cesium环境

  1. 下载Cesium库
## cesium安装指定版本,最新版本的cesium可能文档没有更新
npm install cesium@1.100 vite-plugin-cesium
  1. 在vite.config.js中引入cesium
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cesium from 'vite-plugin-cesium'

// https://vitejs.dev/config/
export default defineConfig({
		plugins: [vue(), cesium()],
 		resolve: {
   		alias: { '@': fileURLToPath(new URL('./src', import.meta.url))}
	   }
})
  1. 导入cesium基础地球
<script setup lang="ts">
import { onMounted } from 'vue'
import * as Cesium from 'cesium'

let token = 'your token'

onMounted(() => {
  //设置token
  Cesium.Ion.defaultAccessToken = token
  //加载基础地球
  new Cesium.Viewer('contain')
})
</script>

<template>
  <div id="contain"></div>
</template>

<style scoped>
body {
  margin: 0;
  padding: 0;
}
#contain {
  width: 50vw;
  height: 50vh;
}
</style>

初始化Cesium

onMounted(async () => {
  Cesium.Ion.defaultAccessToken = token

  //初始化Cesium
  const viewer = new Cesium.Viewer('contain')
})

控制组件的显示与隐藏

  1. 通过JS
  var viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false, // 动画小组件
    baseLayerPicker: false, // 底图组件,选择三维数字地球的底图(imagery and terrain)。
    fullscreenButton: false, // 全屏组件
    vrButton: false, // VR模式
    geocoder: false, // 地理编码(搜索)组件
    homeButton: false, // 首页,点击之后将视图跳转到默认视角
    infoBox: false, // 信息框
    sceneModePicker: false, // 场景模式,切换2D、3D 和 Columbus View (CV) 模式。
    selectionIndicator: false, //是否显示选取指示器组件
    timeline: false, // 时间轴
    navigationHelpButton: false, // 帮助提示,如何操作数字地球。
    // 如果最初应该看到导航说明,则为true;如果直到用户明确单击该按钮,则该提示不显示,否则为false。
    navigationInstructionsInitiallyVisible: false
  })

  // 隐藏logo
  viewer._cesiumWidget._creditContainer.style.display = 'none'
  1. 通过CSS
  .cesium-viewer-toolbar,             /* 右上角按钮组 */
  .cesium-viewer-animationContainer,  /* 左下角动画控件 */
  .cesium-viewer-timelineContainer,   /* 时间线 */
  .cesium-viewer-bottom               /* logo信息 */ {
    display: none !important;
  }

  .cesium-widget-credits  /* 隐藏logo图片 */ {
    display: none !important;
  }

  .cesium-viewer-fullscreenContainer  /* 全屏按钮 */ {
    display: none !important;
    position: absolute;
    top: 0;
  }

添加3D Tiles数据

  // 添加3D Tiles数据
  const buildingTileset = await Cesium.createOsmBuildings()
  viewer.scene.primitives.add(buildingTileset)

加载地形

默认地图是平面的,没有地形图层。可通过如下打开地形图层和水面特效。Cesium 支持多种使用 terrain providers请求 terrain 的方法。

  1. CesiumTerrainProvider:支持量化网格地形瓦片,针对地形流进行了优化。与铯离子提供的地形或 [3D 平铺管道] 的输出兼容])(/3d-tiling-pipeline/terrain/)。
  2. GoogleEarthEnterpriseTerrainProvider:支持由 Google Earth Enterprise 服务器生成的高度贴图地形。
  3. VRTheWorldTerrainProvider:支持向 VT MAK VR-TheWorld Server 请求的高度贴图地形瓦片。
  4. EllipsoidTerrainProvider:以程序方式创建椭球体的表面。这缺乏地形的真实外观,但不会从服务器请求数据。
onMounted(async () => {
  Cesium.Ion.defaultAccessToken = token

  //初始化Cesium
  const viewer = new Cesium.Viewer('contain', {
    // 加载Cesium自带的地形数据,地形特效
    terrainProvider: Cesium.createWorldTerrain({
      requestWaterMask: true //水面特效
    })
  })
})

创建坐标点

  1. 2D笛卡尔坐标点
  let point = new Cesium.Cartesian2 ( x , y )
  1. 3D笛卡尔坐标点
  let point = new Cesium.Cartesian3 ( x , y , z )
  1. 4D笛卡尔坐标点
  let point = new Cesium.Cartesian4 ( x , y , z , w )

Cesium坐标系统及坐标转换

常用的坐标系统主要有3个:屏幕坐标系统(Cartesian2);笛卡尔空间直角坐标系(Cartesian3);WGS-84地理坐标系。

  1. 角度与弧度的转换
  // 角度转弧度
  let radians = Cesium.Math.toRadians(degress)
  
  // 弧度转角度
  let degress = Cesium.Math.toDegrees(radians)
  1. 经纬度坐标转换为笛卡尔空间直角坐标

(1) 直接通过经纬度转换。Cesium默认WGS84经纬度坐标。

  // height为大地高
  let c3 = Cesium.Cartesian3.fromDegrees(longitude, latitude, height)

  // cooridnates 格式为不带高度的数组,例如:[-115.0, 37.0, -107.0, 33.0]
  let c3 = Cesium.Cartesian3.fromDegreesArray(coordinates)

  // cooridnates 格式为带高度的数组,例如:[-115.0, 37.0, 1000, -107.0, 33.0, 1500]
  let c3 = Cesium.Cartesian3.fromDegreesArrayHeights(coordinates)

(2) 通过椭球体进行转换。以WGS-84为例,将WGS-84经纬度坐标转换为笛卡尔空间直角坐标

  const ellipsoid84 = Cesium.Ellipsoid.WGS84
  // Cartographic是一个由经度、纬度和高度定义的位置
  const position = Cesium.Cartographic.fromDegrees(longitude, latitude, height, ellipsoid84)
  
  // 单个点转换
  let c3 = ellipsoid84.cartesianToCartographic(position)
  
  // 多个点转换
  let c3s = ellipsoid84.cartesianArrayToCartographicArray([position1, position2, position3])
  1. 笛卡尔空间直角坐标转经纬度坐标

(1) 直接转换:默认情况转为WGS-84的经纬度坐标。

  // 转换后得到的是WGS-84坐标系下的弧度形式的经纬度,高度为大地高
  let positionWGS84 = Cesium.Cartographic.fromCartesian(cartesian3)

(2) 通过椭球体转换。

  // 以WGS-84坐标系为例
  
  // 一个坐标点
  let positionWGS84 = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3)
  
  // 多个坐标点
  let c3 = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray([car1, car2])
  1. 屏幕坐标和笛卡尔空间直角坐标的转

(1) 屏幕坐标转场景空间直角坐标。这里的场景坐标包括:地形、倾斜摄影测量模型等其他三维模型。(目前IE浏览器不支持深度拾取,所以用不了)

  let cartesian2 = new Cesium.Cartesian2(x, y)
  let cartesian3 = viewer.scene.pickPosition(cartesian2)

(2) 屏幕坐标转地表笛卡尔空间坐标。包括地形在内,但是倾斜摄影测量模型等其他三维模型的坐标。

  let cartesian2 = new Cesium.Cartesian2(x, y)
  // 返回值是一个射线(Ray)对象,包含了摄像机的位置(origin)和射线的方向(direction)
  let ray = viewer.camera.getPickRay(cartesian2)
  let cartesian3 = viewer.scene.globe.pick(ray, viewer.scene)

(3) 屏幕坐标转笛卡尔椭球面坐标。不包括地形、倾斜摄影测量模型等其他三维模型的坐标。该椭球是WGS-84椭球

  let cartesian2 = new Cesium.Cartesian2(x, y)
  let cartesian3 = viewer.scene.camera.pickEllipsoid(cartesian2)
  1. 笛卡尔空间直角坐标转屏幕坐标
  // 将 WGS84 坐标中的位置转换为窗口坐标
  let cartesian3 = new Cesium.Cartesian3 ( x , y , z )
  let cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3)

摄像机

摄像机控制

Cesium中摄像机的位置由6个参数决定:笛卡尔空间直角坐标系中的(X,Y,Z):destination;相机视线的方向:(heading(方位);pitch(俯视角度);roll:偏航角度。
在这里插入图片描述

相机控制有两种方式:viewer.flyTo()和viewer.zommTo()。
默认情况下,照相机朝北,并从45°角向下看。

flyTo():摄像机视野飞行至目标点

将摄像头聚焦到实体,可直接使用

  viewer.flyTo(entity)

利用空间位置设置如下:

  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), // 相机的空间位置
    // 相机视线方向
    orientation: {
      heading: Cesium.Math.toRadians(0.0), //方向
      pitch: Cesium.Math.toRadians(-90.0), // 俯视角度
      roll: 0.0 // 偏航角度
    },
    duration: 5.0, // 飞行时间,单位为秒
    complete: function () {
      console.log('fly complete') // 飞行完成后的回调函数
    },
    cancel: function () {
      console.log('fly canceled') // 飞行取消的回调函数
    },
    pitchAdjustHeight: 0.0, // 如果摄像机飞越该值,则调整俯视角度,并将地球保持在视域中
    maximumHeight: 5000, // 相机飞行的最大高度
    flyOverLongitude: 100, // 相机飞向目的地的过程中,强制经过东经100度
  })

zoomTo():直接定位到实体

  viewer.zoomTo(Entity)

setView():直接定位至目标点

viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), // 相机的空间位置
    // 相机视线方向
    orientation: {
      heading: Cesium.Math.toRadians(0.0), //方向
      pitch: Cesium.Math.toRadians(-90.0), // 俯视角度
      roll: 0.0 // 偏航角度
    },
  })

lookAT():直接定位至目标点

该方法会将摄像机的视野中心固定到目标点上,用户可以通过鼠标任意旋转视角方向、缩放地图,但不会改变摄像机视野中心点的位置。

 //heading: 方位; pitch: 俯视角; range: 与目标点的距离;
 viewer.canera.lookAt(cartesian3, new Cesium.HeadingPitchRange(heading,pitch,range))

lookAtTransform:使用变换矩阵设置相机位置和方向

该方法是直接定位至实体。
lookAtTransform(transform, offest)。transform:是全局参考系转到局部参考系的变换矩阵Matrix4;offest:以目标为中心的参考系中与目标的偏移。该方法无法设置摄像机视线的翻滚(roll)。

  // 1. 使用cartesian offset
  // 转换矩阵:笛卡尔空间坐标系转为目标点为中心,北为X轴,正南为Y轴,正上为Z轴的坐标系的转换矩阵
  const transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-98.0, 40.0));
  viewer.camera.lookAtTransform(transform, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0));

  // 2. 使用HeadingPitchRange
  // 转换矩阵:笛卡尔空间坐标系转为目标点为中心,北为X轴,正南为Y轴,正上为Z轴的坐标系的转换矩阵
  const transform = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-72.0, 40.0));
  const heading = Cesium.Math.toRadians(50.0); // 方位
  const pitch = Cesium.Math.toRadians(-20.0); // 俯视角
  const range = 5000.0; // 与中心目标点的距离
  viewer.camera.lookAtTransform(transform, new Cesium.HeadingPitchRange(heading, pitch, range));

摄像机围绕某点旋转

将摄像机围绕富士山旋转。可分为两步,1. 将摄像机锁定至富士山;2. 摄像机围绕富士山旋转。

  // 1. 将相机锁定到某个点
  // 经纬度(弧度)转为笛卡尔空间坐标系
  const centerPoint = Cesium.Cartesian3.fromRadians(
    2.4213211833389243,
    0.6171926869414084,
    3626.0426275055174
  )
  // 笛卡尔空间坐标系转为centerPoints点为中心,北为X轴,正南为Y轴,正上为Z轴的坐标系的转换矩阵
  const transform = Cesium.Transforms.eastNorthUpToFixedFrame(centerPoint)
  // 通过转换矩阵设置相机视角
  viewer.scene.camera.lookAtTransform(
    transform,
    new Cesium.HeadingPitchRange(0, -Math.PI / 4, 2900) //三个参数分别表示相机的方位角、俯仰角、目标点距离相机的距离
  )

  // 2. 环绕centerPoint点旋转
  /* viewer.clock.onTick.addEventListener(function (clock) { ... }):
  这个方法用于在Cesium的时钟每一帧更新时添加一个事件监听器。
  onTick事件在每一帧更新时触发,可以用于执行一些每帧都需要更新的操作。
  clock参数是当前的时钟对象,包含了当前的时间、时钟的运行状态等信息*/
  viewer.clock.onTick.addEventListener(function () {
    viewer.scene.camera.rotateRight(0.005) // 绕相机的右侧轴旋转0.005弧度
  })

飞行轨迹跟踪

参考网址:https://cesium.com/learn/cesiumjs-learn/cesiumjs-flight-tracker/
使用绿点代替飞机模型,模拟随时间变化的飞机飞行过程。

onMounted(async () => {
  Cesium.Ion.defaultAccessToken = token

  //初始化Cesium
  const viewer = new Cesium.Viewer('contain', {
    //地形特效
    terrainProvider: Cesium.createWorldTerrain({
      requestWaterMask: true //水面特效
    })
  })

  // 添加全局的3d建筑图层
  const buildingTileset = await Cesium.createOsmBuildings()
  viewer.scene.primitives.add(buildingTileset)

  //飞行路径中间位置数据。此处省略一部分,可参考:https://cesium.com/learn/cesiumjs-learn/cesiumjs-flight-tracker/
  const flightData = JSON.parse(
    '[{"longitude":-122.39053,"latitude":37.61779,"height":-27.32},{"longitude":-122.39035,"latitude":37.61803,"height":-27.32},{"longitude":-122.39019,"latitude":37.61826,"height":-27.32},{"longitude":-122.39006,"latitude":37.6185,"height":-27.32},...
  )

  const timeStepInSeconds = 30 //飞行轨迹采样间隔。假设为30m
  const totalSeconds = timeStepInSeconds * (flightData.length - 1)
  const start = Cesium.JulianDate.fromIso8601('2020-03-09T23:10:00Z') //起飞时间
  const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate())
  viewer.clock.startTime = start.clone() //时间轴的起始时间
  viewer.clock.stopTime = stop.clone() //时间轴的结束时间
  viewer.clock.currentTime = start.clone()
  viewer.timeline.zoomTo(start, stop)
  viewer.clock.multiplier = 50 //将播放速度加快50倍
  viewer.clock.shouldAnimate = true //开始播放场景

  //用于存储轨迹点的时间和位置
  const positionProperty = new Cesium.SampledPositionProperty()

  for (let i = 0; i < flightData.length; i++) {
    const dataPoint = flightData[i]
    const time = Cesium.JulianDate.addSeconds(start, i * timeStepInSeconds, new Cesium.JulianDate())
    const position = Cesium.Cartesian3.fromDegrees(
      dataPoint.longitude,
      dataPoint.latitude,
      dataPoint.height
    )
    positionProperty.addSample(time, position)

    //添加飞行路径轨迹点
    viewer.entities.add({
      //属性描述
      description: `Location: (${dataPoint.longitude}, ${dataPoint.latitude}, ${dataPoint.height})`,
      position: Cesium.Cartesian3.fromDegrees(
        dataPoint.longitude,
        dataPoint.latitude,
        dataPoint.height
      ),
      point: { pixelSize: 10, color: Cesium.Color.RED }
    })
  }

  //创建一个实体,用一条线将整个雷达样本序列可视化,并添加一个沿着样本移动的点
  const airplaneEntity = viewer.entities.add({
    //设置实体的有效时间段
    availability: new Cesium.TimeIntervalCollection([
      new Cesium.TimeInterval({ start: start, stop: stop })
    ]),
    position: positionProperty,
    point: { pixelSize: 30, color: Cesium.Color.GREEN },
    path: new Cesium.PathGraphics({ width: 3 }) //描述所定义实体随时间移动时形成的路径折线
  })

  //设置摄像头跟踪移动实体
  viewer.trackedEntity = airplaneEntity

加载自定义3D模型

参考网址:https://cesium.com/learn/cesiumjs-learn/cesiumjs-interactive-building/

  1. 初始化Cesuim,添加3D建筑物
  //初始化Cesium
  const viewer = new Cesium.Viewer('contain', {
    //地形特效
    terrainProvider: Cesium.createWorldTerrain({
      requestWaterMask: true //水面特效
    })
  })
  
  // 添加全局的3d建筑图层
  const buildingTileset = await Cesium.createOsmBuildings()
  viewer.scene.primitives.add(buildingTileset)
  1. 确定新建筑物区域
    新建建筑覆盖区域GeoJSON文件,将网页内容复制到新建的“.json”文件中。
	//从GeoJSON创建几何图形,并将其固定在地面上
	const geoJSON = await Cesium.GeoJsonDataSource.load('src/assets/New_Buliding.json', {
      clampToGround: true
    })
    const dataSource = await viewer.dataSources.add(geoJSON)

    //默认情况下,CesiumJS中的多边形会覆盖场景中的所有3D内容。
    //修改多边形,使这个悬垂效果只适用于地形,而不是3D建筑物。
    for (const entity of dataSource.entities.values) {
      if (entity.polygon)
        entity.polygon.classificationType = new Cesium.ConstantProperty(
          Cesium.ClassificationType.TERRAIN
        )
    }
  1. 隐藏新建筑的现有3D建筑物
    根据建筑物的”elementId“属性进行隐藏,点击基础地球中的对应建筑即可查看。
    在这里插入图片描述
  //隐藏新建建筑的现有3D建筑物
  buildingTileset.style = new Cesium.Cesium3DTileStyle({
    // Create a style rule to control each building's "show" property.
    show: {
      conditions: [
        //隐藏指定建筑物,根据elementId隐藏
        ['${elementId} === 532245203', false],
        ['${elementId} === 530288180', false],
        ['${elementId} === 235368665', false],
        ['${elementId} === 332469316', false],
        ['${elementId} === 332469317', false],
        // 其他的建筑显示在图层中
        [true, true]
      ]
    },
    //为这个特定的3D Tileset设置默认颜色样式
    //对于任何具有`cesium#color`属性的建筑物,使用原颜色,否则设置为白色。
    color:
      "Boolean(${feature['cesium#color']}) ? color(${feature['cesium#color']}) : color('#ffffff')"
  })
  1. 添加新建筑的3D模型
    下载3D建筑模型。导入到Cesium Icon中(需确保3D模型地理位置准确)。并获取模型的"asset_id"。
    在这里插入图片描述
  // 添加您从Cesium Icon帐户创建的3D瓦片集
  const newBuildingTileset = await Cesium.IonResource.fromAssetId("asset_id")
  const tileset = new Cesium.Cesium3DTileset({ url: newBuildingTileset })
  //保在继续执行后续代码之前,Cesium3DTileset 已经完全加载并准备好
  await tileset.readyPromise
  //将新建筑添加到场景中
  viewer.scene.primitives.add(tileset)

  viewer.flyTo(tileset)

筛选3D Tiles,并设计样式

根据筛选条件设计样式使用函数Cesium.Cesium3DTileStyle()。利用该函数前需要先加载3DTiles数据,如下:

  // 添加全局的3d建筑图层
  const buildingTileset = await Cesium.createOsmBuildings()
  viewer.scene.primitives.add(buildingTileset)
  1. 筛选3D Tiles数据的name属性为“Crown Entertainment Complex”,使其3D Tiles颜色为红色,其他颜色为白色
  buildingTileset.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        ["${name} === 'Crown Entertainment Complex'", "color('red')"],
        [true, "color('white')"]
      ]
    }
  })
  1. 显示“buliding”属性为“residential”或“apartments”的3D Tiles中
  bulidingTileset.style = new Cesium.Cesium3DTileStyle({
    show: "${feature['building']} === 'residential' || ${feature['building']} === 'apartments'"
  })
  1. 据每座建筑物与皇冠娱乐中心【vec2(144.96007, -37.82249)】,
    的距离为其分配不同的颜色
  buildingTileset.style = new Cesium.Cesium3DTileStyle({
    defines: {
      // 自定义变量,distance()计算两点之间的距离
      distanceFromComplex:
        "distance(vec2(${feature['cesium#longitude']}, ${feature['cesium#latitude']}), vec2(144.96007, -37.82249))"
    },
    color: {
      conditions: [
        ['${distanceFromComplex} > 0.010', "color('#d65c5c')"],
        ['${distanceFromComplex} > 0.006', "color('#f58971')"],
        ['${distanceFromComplex} > 0.002', "color('#f5af71')"],
        ['${distanceFromComplex} > 0.0001', "color('#f5ec71')"],
        ['true', "color('#ffffff')"]
      ]
    }
  })

创建实体

CesiumJS 具有丰富的空间数据 API,可分为两类:Primitive API面向图形开发人员的低级 API 和Entity API面向数据驱动可视化的高级 API。Entity API 实际上在后台使用了 Primitive API。
Entity API: 由于其高层次的抽象,Entity在处理大量复杂对象时可能会性能较低,尤其是在需要频繁更新和渲染的情况下。
Geometry API: 由于其低层次的抽象和直接的渲染控制,Geometry在处理大量几何体时性能更高,适合需要高性能的应用场景。

Entity API

  viewer.entities.add({
    // 设置name
    name: `Location: -114.0, 40.0, 300000.0`,
    // 设置点的位置
    position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
    // 设置点的样式
    point: { pixelSize: 10, color: Cesium.Color.RED }
  })

折线

  viewer.entities.add({
    name: '折线',
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArrayHeights([-75, 45, 500000, -125, 45, 500000]),
      width: 4,

      // 设置线的样式]
      // PolylineDashMaterialProperty:虚线样式
      // PolylineArrowMaterialProperty:箭头样式
      // PolylineGlowMaterialProperty:发光样式
      // PolylineOutlineMaterialProperty:轮廓样式
      // PolylineMaterialProperty:实线样式
      material: new Cesium.PolylineDashMaterialProperty({
        color: Cesium.Color.CYAN
      })
    }
  })

矩形

  viewer.entities.add({
    name: '矩形',
    rectangle: {
      // new Cesium.Rectangle ( west , south , east , north ) 指定为经度和纬度坐标的二维区域
      coordinates: Cesium.Rectangle.fromDegrees(-140.0, 30.0, -100.0, 40.0),
      material: Cesium.Color.GREEN.withAlpha(0.5),
      extrudedHeight: 600000.0, // 拉伸高度:矩形的高度,沿着远离地表方向拉伸
      height: 100000.0, // 高度
      outline: true,
      outlineColor: Cesium.Color.BLACK,
      rotation: Cesium.Math.toRadians(45), // 矩形从北逆时针旋转的数值,Cesium默认旋转为逆时针方向
      stRotation: Cesium.Math.toRadians(45) // 纹理从北逆时针旋转的数值
    }
  })

多边形

 viewer.entities.add({
    name: 'Polygon',
    polygon: {
      // 多边形的经纬度坐标,Cesium.Cartesian3.fromDegreesArrayHeights([经度,纬度,高度,经度,纬度,高度,...])
      hierarchy: {
        // 定义多边形或孔外边界的线性环
        positions: Cesium.Cartesian3.fromDegreesArray([
          -99.0, 30.0, -85.0, 30.0, -85.0, 40.0, -99.0, 40.0
        ]),

        // 定义多边形或孔外边界的线性环,可以嵌套,例如:holes:[{positions: [...],hole: [{positions: [...]}]
        holes: [
          {
            positions: Cesium.Cartesian3.fromDegreesArray([
              -97.0, 31.0, -97.0, 39.0, -87.0, 39.0, -87.0, 31.0
            ])
          }
        ]
      },

      height: 200000, // 多边形的恒定高度
      extrudedHeight: 100000, // 拉伸高度:多边形的高度,沿着地表方向拉伸
      //指定是否使用每个位置的高度。
      //如果为真,则形状将具有由每个 PolygonGraphics#hierarchy 位置的高度定义的非均匀高度。
      //如果为 false,则形状将具有由 PolygonGraphics#height 指定的恒定高度。
      perPositionHeight: true,
      closeTop: false, // 多边形的顶部是否闭合,若为flase,则不渲染顶部表面
      closeBottom: false, // 多边形的底部是否闭合,若为flase,则不渲染底部表面
      material: Cesium.Color.RED.withAlpha(0.5), // 多边形的材质:红色半透明,可利用图片添加纹理:Material:”图片地址”
      // 设置纹理坐标
      textureCoordinates: {
        positions: [
          new Cesium.Cartesian2(0, 1),
          new Cesium.Cartesian2(0, 0),
          new Cesium.Cartesian2(0.5, 0),
          new Cesium.Cartesian2(1, 0),
          new Cesium.Cartesian2(1, 1)
        ]
      },
      // 设置边框线颜色
      outline: true,
      outlineColor: Cesium.Color.BLACK,
      arcTy: Cesium.ArcType.RHUMB // 指定多边形边使用的线的类型:NONE(直线)、GEODESIC(遵循测地线路径)、RHUMB(遵循 rhumb 或 loxodrome 路径)
    }
  })

长方体

  const entity = viewer.entities.add({
    // 实体的name
    name: '长方体',
    // 长方体的中心位置
    position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
    box: {
      // 长方体的长宽高
      dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
      // 是否对长方体的表面进行填充,若为false,则不需要设置属性:material
      fill: false,
      // 长方体的样式设置
      material: Cesium.Color.BLUE.withAlpha(0.5)
      // 设置边框线颜色
      outline: true,
      outlineColor: Cesium.Color.BLACK
    }
  })

椭圆

  viewer.entities.add({
    name: '椭圆',
    // 椭圆从地球椭球体表面建立。position不在地球表面,会投影至地球表面
    position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
    ellipse: {
      // 南北方向的半长轴
      semiMinorAxis: 150000.0,
      // 东西方向的半短轴
      semiMajorAxis: 300000.0,
      // 椭圆拉伸高度:不设置时会变成高度为0的椭圆,从地球表面Z轴方向拉伸
      extrudedHeight: 200000.0,
      // 椭圆从北逆时针旋转的数值
      rotation: Cesium.Math.toRadians(45),
      material: Cesium.Color.BLUE.withAlpha(0.5),
      outline: true
    }
  })

走廊

  viewer.entities.add({
    name: '走廊',
    corridor: {
      positions: Cesium.Cartesian3.fromDegreesArray([-80.0, 40.0, -85.0, 40.0, -85.0, 35.0]),
      // 走廊高度:走廊上沿距离地面的高度,默认为0
      height: 300000.0,
      // 拉伸高度:走廊下沿距离地面的高度,默认为0
      extrudedHeight: 100000.0,
      // 走廊宽度
      width: 200000.0,
      // 设置指定角的样式:如下图,ROUNDED(角有光滑的边缘)、MITERED(角点是相邻边的交点)、BEVELED(角被剪裁)
      cornerType: Cesium.CornerType.BEVELED,
      material: Cesium.Color.BLUE.withAlpha(0.5),
      outline: true, // height 或 extrudedHeight 设置后才可使用
      outlineColor: Cesium.Color.WHITE
    }
  })

在这里插入图片描述

圆柱体和圆锥体

 viewer.entities.add({
    name: '圆柱体或圆锥体',
    // 圆柱体或圆锥体的中心
    position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0),
    cylinder: {
      // 圆柱体或圆锥体高度
      length: 200000.0,
      // 圆柱体顶部半径,为0时即为圆锥体
      topRadius: 200000.0,
      // 圆柱体顶部半径,为0时即为圆锥体
      bottomRadius: 200000.0,
      material: Cesium.Color.GREEN.withAlpha(0.5),
      outline: true,
      outlineColor: Cesium.Color.BLACK
    }
  })

折线体

折线体:为一条线带和沿它挤出的相应二维形状。生成的体积符合地球的曲率。

// 折线体积中positions的点的位置始终保持在折线体底部的中间位置
  viewer.entities.add({
    name: '折线体',
    polylineVolume: {
      positions: Cesium.Cartesian3.fromDegreesArrayHeights([
        -90.0, 32.0, 300000.0, -90.0, 36.0, 100000.0, -94.0, 36.0, 0.0
      ]),
      // 设置指定 Cartesian2 位置数组的属性,这些位置定义要挤出的形状。
      shape: [
        new Cesium.Cartesian2(-60000, -60000),
        new Cesium.Cartesian2(60000, -60000),
        new Cesium.Cartesian2(60000, 60000),
        new Cesium.Cartesian2(-60000, 60000)
      ],
      // 边角类型:ROUNDED(角有光滑的边缘)、MITERED(角点是相邻边的交点)、BEVELED(角被剪裁),参考上文中创建实体中的走廊
      cornerType: Cesium.CornerType.ROUNDED, 
      material: Cesium.Color.GREEN.withAlpha(0.5),
      outline: true,
      outlineColor: Cesium.Color.BLACK
    }
  })

在这里插入图片描述

球体和椭球体

  viewer.entities.add({
    name: '球体和椭圆体',
    // 球体或椭圆体的中心
    position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),
    ellipsoid: {
      // 球体或椭圆体的半径,包括x,y,z方向
      radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),
      fill: false,
      outline: true,
      outlineColor: Cesium.Color.YELLOW,
      slicePartitions: 24, // 径向切分数量
      stackPartitions: 36, // 高程方向切分数量
    }
  })

  viewer.entities.add({
    name: '墙',
    wall: {
      // 该属性指定定义墙顶部的 Cartesian3 位置数组。
      // Cesium.Cartesian3.fromDegreesArrayHeights([经度、纬度、高度、经度、纬度、高度、...]) 中的高度指顶部的高度。
      positions: Cesium.Cartesian3.fromDegreesArray([
        -115.0, 50.0, -112.5, 50.0, -110.0, 50.0, -107.5, 50.0, -105.0, 50.0, -102.5, 50.0, -100.0,
        50.0, -97.5, 50.0, -95.0, 50.0, -92.5, 50.0, -90.0, 50.0
      ]),
      // 设置指定要用于墙顶部的高度数组。数组的长度必须与 Wall#positions 相同
      maximumHeights: [
        100000, 200000, 100000, 200000, 100000, 200000, 100000, 200000, 100000, 200000, 100000
      ],
      // 设置指定要用于墙底部的高度数组。数组的长度必须与 Wall#positions 相同
      minimumHeights: [0, 100000, 0, 100000, 0, 100000, 0, 100000, 0, 100000, 0],
      material: Cesium.Color.BLUE.withAlpha(0.5),
      outline: true,
      outlineColor: Cesium.Color.BLACK
    }
  })

加载自定义的3D模型

  // 可使用orientation控制3D模型方向
  viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706),
    model: {
      uri: "../../../../Apps/SampleData/models/GroundVehicle/GroundVehicle.glb",
    },
  });

实体的样式设置

在创建实体时创建样式,设置material等,可见“创建实体”中的示例;
属性中的"outlineWith"仅适用于非 Windows 系统,例如 Android、iOS、Linux 和 OS X。在 Windows 系统上,轮廓的宽度始终为 1。这是由于 WebGL 在 Windows 上的实现方式受到限制

  1. 图像
  material : "/docs/tutorials/creating-entities/images/cats.jpg";
  1. 棋盘
  material : new Cesium.CheckerboardMaterialProperty({
    evenColor: Cesium.Color.WHITE, // 偶数格的颜色
    oddColor: Cesium.Color.BLACK, // 奇数格的颜色
    repeat: new Cesium.Cartesian2(4, 4), // 棋盘格的重复次数,, 奇数和偶数分别算一次
  });

在这里插入图片描述

  1. 条纹
  material: new Cesium.StripeMaterialProperty({
    evenColor: Cesium.Color.WHITE,
    oddColor: Cesium.Color.BLACK,
    repeat: 32 //重复次数, 奇数和偶数分别算一次
  })

在这里插入图片描述

  1. 网格
  material: new Cesium.GridMaterialProperty({
    color: Cesium.Color.YELLOW,
    cellAlpha: 0.2, // 单元格透明度
    lineCount: new Cesium.Cartesian2(8, 8), // Cartesian2 属性,指定沿每个轴的网格线数
    lineThickness: new Cesium.Cartesian2(2.0, 2.0), // Cartesian2 属性,指定沿每个轴的网格线的粗细
    lineOffest: new Cesium.Cartesian2(0.5, 0.5)  //Cartesian2 属性,指定网格线沿每个轴的起始偏移量,0.5表示偏移0.5个单元格大小
  });

在这里插入图片描述

Primitive API

使用Primitive API渲染集合实体可大致分为两部:(1)几何实体实例化;(2)渲染几何实体。

  // 几何实例化
  const geometry = new Cesium.GeometryInstance({
    // 要实例化的几何图形:此处为矩形
    geometry: new Cesium.RectangleGeometry({
      rectangle: Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0),
      // 顶点格式:定义了构成顶点的属性。可以将 VertexFormat 提供给 Geometry 以请求计算某些属性,例如仅位置、位置和法线等。
      vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
    }),
    // 将几何从模型转换为世界坐标的模型矩阵:局部坐标系转全局坐标系
    modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
      Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0)
    ),
    id: 'rectangle',
    // 定义实例的属性。
    // ColorGeometryInstanceAttribute:设置颜色和透明度.
    // ShowGeometryInstanceAttribute : 是否显示实例
    attributes: {
      color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE)
    }
  })

  // 渲染几何实例
  viewer.scene.primitives.add(
    new Cesium.Primitive({
      // 渲染的几何实体:多个实体用数组表示[geometry1,geometry,...]
      geometryInstances: geometry,
      // 设置颜色,PerInstanceColorAppearance:允许使用相同的 Primitive 绘制多个几何实例,每个实例具有不同的颜色
      appearance: new Cesium.PerInstanceColorAppearance()
    })
  )
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值