之前零零碎碎学过、用过cesium,但也没做记录,现在重新整理一下,方便学习回顾。
在Cesium中绘制几何图形,有两种不同类型的API:
1.Entity API
特点:较为高级的,不需要使用者对计算机图形学有很深的理解,可以直接拿来使用的API。
2.Primitive API
向图形开发人员的,更为复杂的API。
Entity API本质上是对Primitive API的二次封装,目的是让使用者不必对计算机图
形学有多么高深的理解,就能轻松绘制出各式各样的几何图形。
本文主要介绍如何用Entity API绘制基本图形
1.entity绘制基本图形
entity实体,一般都要用viewer.entities.add({})来添加。
(1)点 point
//绘制点
var Point = viewer.entities.add({
id: "point",
name: "点",
show: true,
position: Cesium.Cartesian3.fromDegrees(118, 32, 0.0),
//设置点的具体参数
point: {
//点的颜色
color: Cesium.Color.BLUE,
//点的像素大小
pixelSize: 30,
//点的轮廓颜色
outlineColor: Cesium.Color.WHITE,
//点的轮廓宽度
outlineWidth: 5,
},
});
//相机飞到点
viewer.flyTo(Point);
(2)线 polyline
polyline,意思是折线
var Line = viewer.entities.add({
id: "line",
name: "线",
show: true,
//线的具体参数
polyline: {
//线的坐标
positions: Cesium.Cartesian3.fromDegreesArray([
118, 30, 119, 32, 116, 35,
]),
//线的颜色
color: Cesium.Color.RED,
//线的宽度
width: 8,
//线的材质
material: Cesium.Color.RED.withAlpha(0.5),
//线贴在地表
clampToGround: true,
},
});
viewer.flyTo(Line);
在polyline对象中,positions是一个数组,代表着坐标点,点可以有多个,前两个坐标点位置定义了一条线段,之后的每一个坐标点位置都根据前一个坐标点位置定义一条线段,
(3)面 polygon
polygon,意思是多边形。
//面
var Polygon = {
id: "polygon",
name: "面",
show: true,
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
118, 30, 119, 32, 116, 32, 116, 30,
]),
//面的材质
material: Cesium.Color.RED.withAlpha(0.4),
},
};
在Polygon中有一个名为hierarchy的属性,其值是一个Cartesian3类型的对象。这个对象使用经度(longitude)和纬度(latitude)的数组来表示一个一系列的坐标点。
具体来说,Cesium.Cartesian3.fromDegreesArray()方法接受一个包含经度和纬度值的数组,并将其转换为一组Cartesian3对象。每两个连续的数组元素表示一个坐标点的经度和纬度。
在这个例子中,通过传递[118, 30, 119, 32, 116, 32, 116, 30]作为参数给fromDegreesArray()方法,将会生成一组包含四个坐标点的Cartesian3对象。
这四个坐标点的经纬度分别是:
1. 经度 118,纬度 30
2. 经度 119,纬度 32
3. 经度 116,纬度 32
4. 经度 116,纬度 30
这个hierarchy属性通常用于定义一个闭合的或非闭合的多边形的形状,或者是一个路径的路线。这些坐标点将在Cesium的渲染过程中被使用,用于绘制多边形或路径。
(4)矩形 Rectangle
创建一个对象Rectangle,在其中加入相应的配置项:
//矩形
var addRectangle =viewer.entities.add({
id: "rectangle",
name: "矩形",
show: true,
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(
80.0,
30.0,
100.0,
35.0
),
material: Cesium.Color.BLUE.withAlpha(0.5),
},
});
rectangle 是包含矩形属性的对象。
coordinates 用于定义矩形的坐标范围。通过Cesium.Rectangle.fromDegrees()方法创建一个矩形,传入四个参数,分别代表矩形的最小经度、最小纬度、最大经度、最大纬度,这里设置为(80.0, 30.0, 100.0, 35.0),表示一个经度范围为80.0至100.0,纬度范围为30.0至35.0的矩形。
因为使用经纬度来约束的矩形边界,当矩形范围较大时,可以看到矩形有一些【弯曲】
当然,我们也可以加入更多的配置项,来个性化设置,例如设置厚度、高度、边框
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(
80.0,
30.0,
100.0,
35.0
),
material: Cesium.Color.BLUE.withAlpha(0.5),
// 设置矩形的厚度,单位为米
extrudedHeight: 20000,
// 设置矩形的高度,单位为米
height: 100000,
//设置外边框的颜色、宽度
outline: true,
outlineWidth: 10,
outlineColor: Cesium.Color.YELLOW,
},
想加入多个矩形时,可以用数组承接,然后循环绘制:
//矩形
var RectangleArr = [
{
id: "rectangle",
name: "矩形",
show: true,
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(
80.0,
30.0,
100.0,
35.0
),
material: Cesium.Color.BLUE.withAlpha(0.5),
// 设置矩形的厚度,单位为米
extrudedHeight: 20000,
// 设置矩形的高度,单位为米
height: 100000,
//设置外边框的颜色、宽度
outline: true,
outlineWidth: 10,
outlineColor: Cesium.Color.YELLOW,
},
},
{
id: "rectangle1",
name: "矩形",
show: true,
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(
80.0,
35.0,
100.0,
40.0
),
material: Cesium.Color.YELLOW.withAlpha(0.9),
// 设置矩形的高度,单位为米
height: 100000,
},
},
];
RectangleArr.forEach(item => {
viewer.entities.add(item);
});
(5)椭圆 Ellipse
在 ellipse对象中,需要配置好椭圆的semiMinorAxis 短半轴 和 semiMajorAxis长半轴,如果长短半轴一样,那绘制出来的就是一个圆形。
//椭圆
var ellipse = viewer.entities.add({
id: "ellipse",
name: "Ellipse",
show: true,
position: Cesium.Cartesian3.fromDegrees(116.39, 39.91),
ellipse: {
semiMinorAxis: 250000.0, //短半轴
semiMajorAxis: 400000.0, //长半轴
material: Cesium.Color.RED.withAlpha(0.5),
},
});
viewer.flyTo(ellipse);
(6)Cylinder 圆柱体
//圆柱体
var addCylinder = viewer.entities.add({
id: "cylinder",
name: "圆柱体",
show: true,
//位置
position: Cesium.Cartesian3.fromDegrees(100.0, 40.0, 200000.0),
cylinder: {
length: 400000.0, //圆柱长度
topRadius: 200000.0, //顶面半径
bottomRadius: 200000.0, //底面半径
material: Cesium.Color.GREEN.withAlpha(0.6),
outline: false,
outlineColor: Cesium.Color.DARK_GREEN,
},
});
viewer.flyTo(addCylinder);
position,
用于指定圆柱体柱心所在的位置,此处通过Cesium.Cartesian3.fromDegrees(100.0,40.0,
200000.0)将经纬度坐标转换为笛卡儿空间直角坐标,柱心高度为200000.0。
cylinder,用于描述圆柱体,并为cylinder对象添加
属性length,值为“400000.0”,用于指定圆柱体高度,这样柱心的高度刚好为200000.0,能够
保证圆柱体刚好贴地;
topRadius,值为“200000.0”,用于指定圆柱体顶面半径;
bottomRadius,值为“200000.0”,用于指定圆柱体底面半径;
当底面半径或者顶面半 径为0时,绘制出来的实体为圆锥体。
(7)Corridor 走廊
//走廊
var addCorridor = viewer.entities.add({
id: "corridor",
name: "走廊",
show: true,
corridor: {
//起点,中间点,终点
positions: Cesium.Cartesian3.fromDegreesArray([
100.0, 40.0, 105.0, 40.0, 105.0, 35.0, 108, 36,
]),
//宽度
width: 30000.0,
material: Cesium.Color.YELLOW.withAlpha(0.5),
},
});
我们还可以加入更多参数,例如拐角样式(ROUNDED是圆角,MITERED是直角,BEVELED是剪切角),还有实体高度等。
//走廊
var addCorridor = viewer.entities.add({
id: "corridor",
name: "走廊",
show: true,
corridor: {
//起点,中间点,终点
positions: Cesium.Cartesian3.fromDegreesArray([
100.0, 40.0, 105.0, 40.0, 105.0, 35.0, 108, 36,
]),
//宽度
width: 30000.0,
material: Cesium.Color.YELLOW.withAlpha(0.5),
//设置矩形的厚度,单位为米
extrudedHeight: 200000,
//定义拐角样式,ROUNDED圆角,MITERED直角,BEVELED剪切角
cornerType: Cesium.CornerType.MITERED,
},
});
(8)墙 Wall
wall是专门用来实现墙的效果的,注意,positions中传入的坐标,是需要带高度的,Cesium.Cartesian3.fromDegreesArrayHeights()用来将多个带高度的经纬度坐标转为Cartesian3坐标。
var addWall = {
id: "wall",
name: "墙",
show: true,
wall: {
positions: Cesium.Cartesian3.fromDegreesArrayHeights([
107.0, 43.0, 200000.0, 97.0, 43.0, 100000.0, 97.0, 40.0,
100000.0, 107.0, 40.0, 100000.0, 107.0, 43.0, 100000.0,
]),
material: Cesium.Color.GREEN,
},
};
(9)盒子 Box
position指定方盒的中心点位置,dimensions指定长、宽、高。
//方盒
var addBox = viewer.entities.add({
id: "box",
name: "方盒",
show: true,
position: Cesium.Cartesian3.fromDegrees(110, 35, 200000.0),
box: {
dimensions: new Cesium.Cartesian3(
400000.0,
300000.0,
400000.0
), //指定框的长度,宽度和高度
material: Cesium.Color.BLUE,
},
});
viewer.flyTo(addBox);
(10)椭球体 Ellipsoid
position指定椭球体中心的位置,radii 定义了椭球体的X轴半径,Y轴半径,Z轴半径。
//球体
var addEllipsoid = viewer.entities.add({
id: "ellipsoid",
name: "椭球体",
show: true,
position: Cesium.Cartesian3.fromDegrees(107.0, 40.0, 300000.0),
ellipsoid: {
radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0), //椭球的半径
material: Cesium.Color.BLUE.withAlpha(0.5),
//外轮廓线
outline: true,
outlineColor: Cesium.Color.WHITE,
},
});
viewer.flyTo(addEllipsoid);
(11)模型加载
首先,定义变量heading、pitch及roll,分别代表模型航向(围绕负Z
轴)、俯仰角(围绕负Y轴)及翻滚角(围绕正X轴)。
然后创建变量hpr,用new Cesium.HeadingPitchRoll(heading, pitch, roll);创建对象,这个对象是用来表示物体在三维空间中的方向和姿态的。
因为Cesium中都是以弧度的形式来进行计算的,所以我们需要将模型航向 Cesium.Math.toRadians(0)转换为弧度后进行使用。
// 定义参数,用于模型的摆位
var heading = Cesium.Math.toRadians(0); //航向
var pitch = 0; //俯仰角
var roll = 0; //翻滚角
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var addModel = {
id: "model", //id唯一
name: "小车模型", // 名称
show: true, //显示
position: Cesium.Cartesian3.fromDegrees(118, 30, 5000), // 小车位置
orientation: Cesium.Transforms.headingPitchRollQuaternion(
Cesium.Cartesian3.fromDegrees(118, 30, 5000),
hpr
),
model: {
uri: "./3D格式数据/glTF/CesiumMilkTruck.gltf",
minimumPixelSize: 300, //模型最小
maximumScale: 50000, //模型最大
scale: 30000, //当前比例
},
};
var modd = viewer.entities.add(addModel);
viewer.flyTo(modd);
orientation,用于指定实体的方向,值是四元数 (Quaternion)类型的一组四维坐标。
Cesium.Transforms.headingPitchRollQuaternion()可以计算得出四元数。该方法需要传入两个参数:
第一个参数为本地参考系的中心点,此处取模型的位置作为中心点;
第二个参数为HeadingPitchRoll类型,用于描述模型航 向、俯仰角及翻滚角,此处取前面计算得来的hpr。
我们可以试着只修改一下heading, pitch, roll,来看看效果:
- 航向角 (Heading) :航向角表示物体相对于北方的旋转角度,通常被定义为在水平面上的旋转角度。在航空和导航领域,航向角也被称为方位角。它通常从北方开始顺时针测量,0度表示正北,90度表示正东,180度表示正南,270度表示正西,依此类推。在代码中,
heading是一个角度值,通过Cesium.Math.toRadians函数将其转换为弧度,以便与Cesium中的其他角度值一致。 - 俯仰角 (Pitch) :俯仰角描述物体的上下旋转角度,通常在垂直平面内测量。正的俯仰角表示物体朝向地面,负的俯仰角表示物体朝向天空。在飞行和摄影术中,俯仰角用于确定物体视野的倾斜程度。在代码中,
pitch是一个角度值,表示物体上下方向的倾斜。 - 翻滚角 (Roll) :翻滚角描述物体绕其自身前后轴旋转的角度,通常在物体的轴线方向上测量。正的翻滚角表示物体向右翻滚,负的翻滚角表示物体向左翻滚。在航空和船舶领域,翻滚角也被称为滚转角。在代码中,
roll是一个角度值,表示物体绕自身轴线旋转的角度。
(12)广告牌 Billboard
广告牌里面可以做的事情有很多,可以支持自定义,这里就先简单加载一个图片。
//广告牌
var addBillboard = viewer.entities.add({
id: "billboard",
name: "广告牌",
show: true,
position: Cesium.Cartesian3.fromDegrees(108, 30, 50),
billboard: {
image: "./智慧大楼.png",
scale: 0.3, //比例
},
});
viewer.flyTo(addBillboard);
2.entity 贴地
在实际需求中,经常会遇到这种情况,绘制出的实体(一般是平面的)需要紧贴在山坡、山脉等地形上,或者是贴在倾斜摄影模型的表面上,cesium也有相应的API来实现。
通常是使用heightReference或者classificationType 来实现贴地
(1)点 贴地
var addPoint = {
id: "point",
name: "点",
show: true, //显示.
position: Cesium.Cartesian3.fromDegrees(118, 32),
point: {
color: Cesium.Color.BLUE, //颜色
pixelSize: 50, //点大小
disableDepthTestDistance: Number.POSITIVE_INFINITY,
//贴地
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
};
(2)线 贴地
线的贴地比较特殊,需要设置clampToGround: true, 没有用到上面说的classificationType和heightReference。
// 线
var addLine = {
id: "line",
name: "线",
show: true, //显示
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
118, 30, 119, 32, 116, 35,
]),
width: 2, //线条粗细
material: Cesium.Color.RED, //线条材质
clampToGround: true, //贴地
},
};
(3)面贴地
//面
var addPolygon = {
id: "polygon",
name: "面",
show: true,
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
118, 30, 119, 32, 116, 32, 116, 30,
]),
material: Cesium.Color.RED.withAlpha(0.4),
classificationType: Cesium.ClassificationType.BOTH,
},
};
3.entity材质
材质,简单来说就是表面的样式,cesium默认的材质样式都很简单,难以满足个性化的需求,因此cesium提供了MaterialProperty类,以方便我们自定义材质。
MaterialProperty类是一个抽象类,不能直接实例化,只能实例化它的子类。
在cesium文档中搜索一下MaterialProperty,可以看到
(1)虚线 PolylineDashMaterialProperty
创建一个直线后,如果想实现虚线的效果,可以实例化PolylineDashMaterialProperty,用在material属性中,来实现虚线
var addLine = viewer.entities.add({
id: "line",
name: "线",
show: true, //显示
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
111, 40, 116, 45,
]),
width: 6, //线条粗细
followSurface: false, //取消弯曲
//简单的红色材质
// material: Cesium.Color.RED,
//虚线
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.BLUE,
}),
},
});
(2)箭头 PolylineArrowMaterialProperty
//箭头
material: new Cesium.PolylineArrowMaterialProperty(
Cesium.Color.CYAN,
5.0 //箭头的宽度(相对于线宽)
),
(3)条纹 StripeMaterialProperty
首先创建一个普通的多边形
//面
var addPolygon = viewer.entities.add({
id: "polygon",
name: "面",
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
108, 30, 108, 36, 100, 36, 100, 30,
]),
height: 0,
outline: false,
material: Cesium.Color.RED.withAlpha(0.6),
},
});
//条纹纹理
material: new Cesium.StripeMaterialProperty({
evenColor: Cesium.Color.WHITE, //偶数行,白的
oddColor: Cesium.Color.BLACK, //奇数行,黑的
repeat: 8, //一共8行
}),
(4)棋盘 CheckerboardMaterialProperty
//棋盘纹理
material: new Cesium.CheckerboardMaterialProperty({
evenColor: Cesium.Color.RED,
oddColor: Cesium.Color.YELLOW,
//4X4
repeat: new Cesium.Cartesian2(4, 4),
}),
(5)网格 GridMaterialProperty
// 网格纹理
material: new Cesium.GridMaterialProperty({
//网格快的颜色和透明度
color: Cesium.Color.YELLOW,
cellAlpha: 0.2,
//4行4列
lineCount: new Cesium.Cartesian2(4, 4),
网格线,水平和垂直都是4的宽度
lineThickness: new Cesium.Cartesian2(4.0, 4.0),
}),
(6)贴图 image
//贴图纹理
material: new Cesium.ImageMaterialProperty({
image: "./自己练习/智慧大楼.png",
repeat: new Cesium.Cartesian2(2, 2),
}),
(8)删除实体等方法
viewer.entities.remove(addEllipsoid); //直接移除实体
viewer.entities.removeById("ellipsoid");//根据ID移除实体
viewer.entities.removeAll();//移除集合中全部实体