Cesium entity Entity + draw point line surface


Use the viewer.entities.add method to add Entity vector data, the properties are as follows:
insert image description here
insert image description here

<!--
 * @Author: HuKang
 * @Date: 2023-08-18 11:06:43
 * @LastEditTime: 2023-08-25 09:16:59
 * @LastEditors: HuKang
 * @Description: program-c
 * @FilePath: \global-data-display\src\views\program-c\index.vue
-->
<template>
  <div>
    <div id="cesiumContainer"></div>
  </div>
</template>

<script setup lang="ts">
import * as Cesium from "cesium";
import {
    
     Viewer } from "cesium";
import cesium from "vite-plugin-cesium";
import {
    
     getSatellitecloudApi, getGenerateGridApi } from "@/api/servies";

import {
    
     onMounted } from "vue";
import TOKEN from "@/utils/Tooken";

/**
 * Cesium
 */
// Token 设置
Cesium.Ion.defaultAccessToken = TOKEN;
}
// Viewer
const viewer = ref();
/**
 * 初始化函数
 */
const initViewer = () => {
    
    
  viewer.value = new Cesium.Viewer("cesiumContainer", {
    
    
    infoBox: false,
  });

  // 去除版权信息
  viewer.value.cesiumWidget.creditContainer.style.display = "none";

  // 增加太阳光效果
  // viewer.value.scene.globe.enableLighting = true;

  // 控制视角不转到底下
  viewer.value.scene.globe.depthTestAgainstTerrain = true;

  // 增加瓦片-海图数据
  const imageryProvider = new Cesium.UrlTemplateImageryProvider({
    
    
    url: "cesium-api/map/getMap/{x}/{y}/{z}.png",
    credit: "mapname",
    tilingScheme: new Cesium.GeographicTilingScheme({
    
    
      ellipsoid: Cesium.Ellipsoid.WGS84,
    }),
    maximumLevel: 18,
  });
  viewer.value.scene.imageryLayers.addImageryProvider(imageryProvider);

// 创建自己的数据集合
const datasource = new Cesium.CustomDataSource("")

};
onMounted(() => {
    
    
  initViewer();
});
</script>

<style scoped></style>

1. Draw points

insert image description here

1. The first type

var pointentity = viewer.value.entities.add({
    
    
  id: "point1",
  position: Cesium.Cartesian3.fromDegrees(109, 34),
  point: {
    
    
    pixelSize: 10,
    color: Cesium.Color.YELLOW, // 点的颜色
    outlineColor: Cesium.Color.RED, // 外边框颜色
    outlineWidth: 2,  // 外边框宽度
  },
});

2. The second type

const pointentity2 = new Cesium.Entity({
    
    
  id: "point2",
  position: Cesium.Cartesian3.fromDegrees(109, 34),
  point: {
    
    
    pixelSize: 10,
    color: Cesium.Color.YELLOW,
    outlineColor: Cesium.Color.RED,
    outlineWidth: 2,
  },
});
viewer.value.entites.add(pointentity2)

2. Drawing surface

insert image description here

viewer.value.entities.add({
    
    
   id: 'polygontest',
   name: 'mian',
   polygon: {
    
    
       hierarchy: Cesium.Cartesian3.fromDegreesArray([
           109.080842, 45.002073,
           105.91517, 45.002073,
           104.058488, 44.996596,
           104.053011, 43.002989,
           104.053011, 41.003906,
           105.728954, 40.998429,
           107.919731, 41.003906,
           109.04798, 40.998429,
           111.047063, 40.998429,
           111.047063, 42.000709,
           111.047063, 44.476286,
           111.05254, 45.002073,
           109.080842, 45.002073]),
       height: 100,
       material: Cesium.Color.RED.withAlpha(0.5),
       outline: true,
       outlineColor: Cesium.Color.BLUE,
       outlineWidth: 1,
       fill: true
       }
});

3. Draw the line

1. Do not set the material

insert image description here

viewer.value.entities.add({
    
    
   id: 'polygontest',
   name: 'line',
   polyline: {
    
    
       positions: Cesium.Cartesian3.fromDegreesArray([
           109.080842, 45.002073,
           105.91517, 45.002073,
           104.058488, 44.996596,
           104.053011, 43.002989,
           104.053011, 41.003906,
           105.728954, 40.998429,
           107.919731, 41.003906,
           109.04798, 40.998429,
           111.047063, 40.998429,
           111.047063, 42.000709,
           111.047063, 44.476286,
           111.05254, 45.002073,
           109.080842, 45.002073]),
       width: 2,
       material: Cesium.Color.YELLOW,
       }
});

2. Set the material

  • arrow
var entity = viewer.value.entities.add({
    
    
  id: "polyline",
  name: "borderLine",
  polyline: {
    
    
    positions: Cesium.Cartesian3.fromDegreesArray([28, 69, 98, 69]),
    width: 50,
    material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
  },
});
viewer.value.zoomTo(entity);//相机飞行到绘制地点

4. Remove Entity

//方法一,先查后删
var removeEntity = viewer.entities.getById('testLine');
console.log(removeEntity)
viewer.entities.remove(removeEntity) 
//方法二,直接删除
viewer.entities.removeById('uniqueId')
//方法三,删除所有
window.viewer.entities.removeAll()

5. Code Demonstration

  1. Solid creation conforming to the curvature of the earth

Two-dimensional:

(1) Create an ellipse
insert image description here

//绘制椭圆
  const ellipse =  new Cesium.Entity({
    
    
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 100),
    ellipse: {
    
    
      semiMinorAxis: 30000, //椭圆的短半轴
      semiMajorAxis: 40000, //椭圆的长半轴
      extrudedHeight: 4000.0, //拉伸高度
      material: Cesium.Color.WHITE.withAlpha(0.5), //椭圆颜色
      outline: true, //是否显示边框
      outlineColor: Cesium.Color.BLUE, //边框颜色
      rotation: Cesium.Math.toRadians(45), //旋转角度,从正北方向开始顺时针旋转
    },
  });

(2) Create a line
insert image description here

const polyline =  new Cesium.Entity({
    
    
    polyline: {
    
    
      positions: Cesium.Cartesian3.fromDegreesArray([112.3, 39.9, 114.4, 39.9]), //返回笛卡尔坐标数组
      width: 10,
      material: Cesium.Color.RED,
    },
  });

Because the coordinates of the line are composed of multiple coordinate pairs, we use the .FromDegreesArray method to convert the coordinates in batches;

Be sure to write the name of the api correctly. If the attribute name in cesium is wrong, no error will be reported;

(3) Create polygons
insert image description here

  var polygon = new Cesium.Entity({
    
    
    name: "多边形",
    polygon: {
    
    
      hierarchy: Cesium.Cartesian3.fromDegreesArray([
        114.3, 39.9, 114.3, 32.0, 107.0, 32.0, 107.0, 39.9, 114.3, 39.9,
      ]),
      material: Cesium.Color.RED.withAlpha(0.5),
      outline: true,
      outlineColor: Cesium.Color.BLACK,
    },
  });

Compared with the plane plane, we can see that the polygon is close to the ground;

(4) Create a rectangle
insert image description here

 var rectangle = new Cesium.Entity({
    
    
    name : '矩形',
    rectangle : {
    
    
        coordinates : Cesium.Rectangle.fromDegrees(114.3, 39.9, 0.4, 50),
        material : Cesium.Color.RED.withAlpha(0.5),
        outline : true,
        outlineColor : Cesium.Color.BLACK,
        height : 0,
        heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,
        extrudedHeight : 500000
    }
});

At first glance, a rectangle might seem like a box, but a rectangle is a two-dimensional area, specified by latitude and longitude coordinates, that can be extruded into a three-dimensional shape that bends with the curvature of the earth. A box, on the other hand, is a three-dimensional geometry that can be used to represent a cube or cuboid that does not bend with the curvature of the earth.

three dimensional

(1) Create a corridor Corridor
describes the corridor, the corridor is defined by the center line and the width of the line that conforms to the curvature of the earth. It can be placed on the ground or aloft and optionally extruded into a volume, which can be seen as a line compounding the curvature of the Earth.
insert image description here

  //绘制走廊
  const corridor = new Cesium.Entity({
    
    
    name: "走廊",
    corridor: {
    
    
      positions: Cesium.Cartesian3.fromDegreesArray([
        114.3, 39.9, -114.0, 40.0, -0.0, 40.0, 114.3, 39.9,
      ]), // 走廊的位置与形状
      height: 200.0, // 走廊的高度
      extrudedHeight: 100.0, //拉伸高度
      width: 2000.0, // 走廊的宽度
      cornerType: Cesium.CornerType.BEVELED, //走廊拐角类型 默认圆角,可选BEVELED或MITERED:
      material: Cesium.Color.BLUE.withAlpha(0.5), //走廊颜色
      outline: true, // 是否展示轮廓
      outlineColor: Cesium.Color.WHITE, //轮廓颜色
    },
  });

(2) Create Walls
Describes 2D walls defined as line bands and optional maximum and minimum heights. Walls conform to the curvature of the earth and can be placed along the ground or high up.
insert image description here

{
    
    
 name: "起伏之墙",
 wall: {
    
    
   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,
   ]),
   maximumHeights: [
     100000,200000,100000,200000,
     100000,200000,100000,200000,
     100000,200000,100000,
   ],
   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,
 },
}

(3) Create a polyline volume:
insert image description here

var polylineVolume = new Cesium.Entity({
    
    
    name: "折线体积",
    polylineVolume: {
    
    
      positions: Cesium.Cartesian3.fromDegreesArray([
        114.3, 39.9, 112.0, 36.0, 115.0, 38.0,
      ]),
      shape: [
        new Cesium.Cartesian2(-50000, -50000),
        new Cesium.Cartesian2(50000, -50000),
        new Cesium.Cartesian2(50000, 50000),
        new Cesium.Cartesian2(-50000, 50000),
      ],
      material: Cesium.Color.GREEN.withAlpha(0.5),
      outline: true,
      outlineColor: Cesium.Color.BLACK,
    },
  });
  1. Entity creation
    (1) that does not conform to the curvature of the earth creates a cube:
    insert image description here
//创建实体所在的坐标
const position = Cesium.Cartesian3.fromDegrees(113.3, 39.9, 5000)

const box = new Cesium.Entity({
    
    
    position: position, //位置
    box: {
    
    
      dimensions: new Cesium.Cartesian3(4000, 3000, 5000), //盒子的长宽高
      material: Cesium.Color.RED.withAlpha(0.5), //盒子颜色
      outline: true, //边框
      outlineColor: Cesium.Color.WHITE, //边框颜色
    },
  });
  
 //将立方体添加到场景中 
 viewer.entities.add(box);

Here, cesium does not use latitude and longitude coordinates, but a Cartesian three-dimensional space Cartesian coordinate system, so we need to convert our coordinates once; we can see that the box is the cube object we created, and the position here is the entity in the cesium space. Position; if this property is not set, the program will not report an error, but the entity will not be displayed;

(2) Create points:
insert image description here

  const point = new Cesium.Entity({
    
    
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),
    point: {
    
    
      pixelSize: 10,//点像素大小
      color: Cesium.Color.RED,//点颜色,不能用rgb等css方法,需要用Cesium.Color
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2,
    },
  });

(3) Create picture annotations:
insert image description here

//绘制图片
  const billboard = new Cesium.Entity({
    
    
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 10),
    billboard: {
    
    
      image: "/src/assets/position.png",
      width: 30,//图片宽度,单位px
      height: 30,//图片高度,单位px
      eyeOffset: new Cesium.Cartesian3(0, 0, -10),//与坐标位置的偏移距离
      color: Cesium.Color.RED,//颜色
      scale: 1,//缩放比例
    },
  });

(4) Create text annotation:
insert image description here

const label = new Cesium.Entity({
    
    
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 10),
    label: {
    
    
      text: "GISer Liu",
      font: "40px sans-serif",
      fillColor: Cesium.Color.red,
      showBackground: true,
      outlineColor: Cesium.Color.BLACK,
      outlineWidth: 2,
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      pixelOffset: new Cesium.Cartesian2(0, 20),
      eyeOffset: new Cesium.Cartesian3(0, 0, -10),
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      scale: 0.5,
      showBackground: true,
      backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),
      backgroundPadding: new Cesium.Cartesian2(10, 10),
    },
  });

(5) Create a cylinder:
insert image description here

var cylinder = new Cesium.Entity({
    
    
    name : '圆柱体',
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),
    cylinder : {
    
    
        length : 500000.0,
        topRadius : 200000.0,
        bottomRadius : 200000.0,
        material : Cesium.Color.RED.withAlpha(0.5),
        outline : true,
        outlineColor : Cesium.Color.BLACK,
        heightReference : Cesium.HeightReference.CLAMP_TO_GROUND
    }
});

(6) Create an ellipsoid:
insert image description here

var ellipsoid = new Cesium.Entity({
    
    
    name : '椭球体',
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),
    ellipsoid : {
    
    
        radii : new Cesium.Cartesian3(300000.0, 200000.0, 100000.0),//长半轴,短半轴,高度
        material : Cesium.Color.BLUE.withAlpha(0.5),
        outline : true,//开启轮廓
        outlineColor : Cesium.Color.BLACK,//轮廓颜色
        heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,//底部位置贴地
        fill : true //填充色启用
    }
});

When the semi-major axis, semi-minor axis, and height are all the same, we have created a sphere;

(7) Create a model:
insert image description here

  var model = new Cesium.Entity({
    
    
    name: "模型",
    position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 1000),//位置
    model: {
    
    
      uri: "/src/assets/Cesium_Air.glb",
      minimumPixelSize: 128, //模型最小像素
      maximumScale: 200, //模型最大放大倍数
    },
  });

glTF files come in two formats: .gltf and .glb.
.gltf is a JSON-based text format that stores model data in a human-readable form. It is often used in conjunction with other binary files, such as texture images, which contain additional data for the model.
.glb is a binary format that packs all model data (including texture images) into a single file. This format is more compact and better suited for transmission over the network.
Both formats can represent the same model data, they are just stored differently. Developers can choose an appropriate format according to their needs.

(8) Create track:
insert image description here

 //启用动画
  viewer.clock.shouldAnimate = true;
  // 定义路径的起始和结束时间
  var start = Cesium.JulianDate.fromDate(new Date());
  var stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());
  
  // 配置时钟以控制动画
  viewer.clock.startTime = start.clone();
  viewer.clock.stopTime = stop.clone();
  viewer.clock.currentTime = start.clone();
  viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
  viewer.clock.multiplier = 10;
  
  // 创建一个 SampledPositionProperty 来存储随时间变化的位置数据
  var position = new Cesium.SampledPositionProperty();

  //SampledPositionProperty 是 Cesium 中的一个类,它用于存储随时间变化的位置数据。它可以用来定义路径实体的形状,或者用来控制模型、点等其他实体随时间移动的轨迹。
  //开发者可以使用 addSample 方法向 SampledPositionProperty 中添加位置数据。每个位置数据都包含一个时间值和一个位置值

  for (var i = 0; i <= 360; i += 45) {
    
    
    // 计算每个时间点的位置
    var radians = Cesium.Math.toRadians(i);
    var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());
    var height = 10000 + 500 * Math.sin(radians); // 计算飞机的高度
    var positionValue = new Cesium.Cartesian3.fromDegrees(
      114.3 + 0.1 * Math.cos(radians),
      39.9 + 0.1 * Math.sin(radians),
      height
    );

    // 将位置数据添加到 SampledPositionProperty 中
    position.addSample(time, positionValue);
  }

  //设置插值算法,平滑路径
  position.setInterpolationOptions({
    
    
    interpolationDegree: 4, //插值程度
    interpolationAlgorithm: Cesium.HermitePolynomialApproximation, //插值算法
  });

  // 创建一个路径实体,并为其提供位置数据和样式
  var path = viewer.entities.add({
    
    
    name: "路径",
    position: position,
    orientation: new Cesium.VelocityOrientationProperty(position),
    path: {
    
    
      leadTime: 0,
      trailTime: 60, //路径持续时间
      width: 20, //路径宽度
      resolution: 10, //路径分辨率
      material: new Cesium.PolylineGlowMaterialProperty({
    
    
        glowPower: 1, //发光强度或者粗细程度
        color: Cesium.Color.BLUEVIOLET, //发光颜色
      }),
    },
    model: {
    
    
      uri: "/src/assets/Cesium_Air.glb",
      minimumPixelSize: 128, //模型最小像素
      maximumScale: 200, //模型最大放大倍数,
    },

  });
  //视角飞行至路径
  viewer.zoomTo(path);

There are many pitfalls in the path here. I have added the detailed use process of the path here. Generally speaking, we only need to set the path part. When using it, we must set the startup animation, otherwise it will have no effect and the path will not be displayed;
code I added the interpolation function to optimize the path trajectory. In practical applications, we can directly use the time series path data of CZML. Here I use the data created by myself; adding the model can better show the path; if you want a static
path , can be directly replaced by polyline;

(9) Create a plane:
insert image description here

var plane = new Cesium.Entity({
    
    
    name : '平面',
    position: Cesium.Cartesian3.fromDegrees(114.3, 40),
    plane : {
    
    
        plane : new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0),
        dimensions : new Cesium.Cartesian2(400000.0, 300000.0),
        material : Cesium.Color.RED.withAlpha(0.5),
        outline : true,
        outlineColor : Cesium.Color.BLACK
    }
});

3. Combined entity:
As far as our previous case code is concerned, we created a single entity, and we can also create a combined entity, that is, an entity element contains multiple elements; such as points and labels, the code is as follows:
insert image description here

  // 线的顶部位置
  var lineTopPosition = Cesium.Cartesian3.fromDegrees(114.3, 39.9, 1000);
  //创建组合实体
  var entity = new Cesium.Entity({
    
    
    position: lineTopPosition,
    // 线
    polyline: {
    
    
      positions: Cesium.Cartesian3.fromDegreesArrayHeights([
        114.3, 39.9, 0, 114.3, 39.9, 1000,
      ]),
      material: Cesium.Color.AQUA,//线的颜色
    },

    // 标签
    label: {
    
    
      text: "Hello World", // 标签显示的文本内容
      font: "14px sans-serif", // 标签文本的字体
      fillColor: Cesium.Color.RED, // 标签文本的填充颜色
      outlineColor: Cesium.Color.WHITE, // 标签文本的轮廓颜色
      outlineWidth: 2, // 标签文本的轮廓宽度
      style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 标签文本的样式,这里设置为填充和轮廓
      pixelOffset: new Cesium.Cartesian2(0, -10), // 标签相对于其原点的像素偏移量
      eyeOffset: new Cesium.Cartesian3(0, 0, -50), // 标签相对于相机位置的偏移量
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 标签的水平原点,这里设置为中心
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 标签的垂直原点,这里设置为底部
      scale: 1, // 标签的缩放比例
      showBackground: true, // 是否显示标签的背景
      backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), // 标签背景的颜色
      backgroundPadding: new Cesium.Cartesian2(10, 10), // 标签背景与文本之间的内边距
    },
  });

  //将立方体添加到场景中
  const Entity = viewer.entities.add(entity);
  
  //视角飞行至立方体
  viewer.camera.flyTo(
    {
    
    
      destination: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 4000), // 目的地的经纬度坐标
      duration: 4,
    } // 动画持续时间,默认为3秒
  );

Guess you like

Origin blog.csdn.net/qq_53810245/article/details/132488356