介绍一下 primitive 元素的使用
我们可以在地图上绘制矩形等 图形
有两种方法
在CesiumJS(一个用于创建3D地球和2D地图的JavaScript库)中,创建矩形通常不直接通过Entity
API来定义矩形的几何形状,而是使用更具体的图形对象,如Primitive
(尽管CesiumJS更多使用的是PrimitiveCollection
和更高级别的图形API,如RectanglePrimitive
,后者在Cesium的某些版本中可能不是直接可用的,但概念类似)。不过,通过Entity
和Primitive
(或相关API)创建矩形的方式确实存在显著区别。
1.使用Entity创建矩形
在Cesium中,Entity
是一个高级的API,用于表示地图上的单个对象,如点、线、多边形等。虽然Cesium的Entity
API不直接支持“矩形”作为一个单独的图形类型,但你可以通过定义一个Polygon
图形并设置其顶点来创建一个矩形。Polygon
是Entity
的一个属性,允许你定义一系列顶点来形成多边形。
// 创建一个矩形 | |
var rectangle = viewer.entities.add({ | |
name: 'Rectangle', | |
polygon: { | |
hierarchy: Cesium.Cartesian3.fromDegreesArray([ | |
-115.0, 37.0, | |
-115.0, 32.0, | |
-107.0, 32.0, | |
-107.0, 37.0 | |
]), | |
material: Cesium.Color.RED.withAlpha(0.5), | |
outline: true, | |
outlineColor: Cesium.Color.BLACK | |
} | |
}); |
在这个例子中,我们创建了一个红色的半透明矩形,其边界由黑色线条勾勒。
2.使用Primitive创建矩形
Primitive
API提供了更低层次的访问,允许你直接控制WebGL的渲染过程。虽然Cesium没有直接提供一个名为RectanglePrimitive
的类,但你可以通过创建一个包含矩形顶点的GeometryInstance
,然后使用Primitive
来渲染它。这通常涉及更多的设置和可能的性能优化,但提供了更高的灵活性。
// 创建一个矩形的顶点 | |
var rectangleGeometry = new Cesium.RectangleGeometry({ | |
rectangle: Cesium.Rectangle.fromDegrees(-115.0, 32.0, -107.0, 37.0) | |
}); | |
var geometry = Cesium.RectangleGeometry.createGeometry(rectangleGeometry); | |
// 创建一个Primitive来渲染这个矩形 | |
var primitive = new Cesium.Primitive({ | |
geometryInstances: new Cesium.GeometryInstance({ | |
geometry: geometry, | |
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame( | |
Cesium.Cartesian3.fromDegrees(-111.0, 34.5, 0.0), | |
Cesium.Ellipsoid.WGS84, | |
new Cesium.HeadingPitchRoll(0.0, 0.0, 0.0) | |
), | |
attributes: { | |
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.5)) | |
} | |
}), | |
appearance: new Cesium.PerInstanceColorAppearance({ | |
flat: true, | |
translucent: true | |
}) | |
}); | |
// 将Primitive添加到viewer的primitives集合中 | |
viewer.scene.primitives.add(primitive); |
注意,这个示例中的RectangleGeometry
和GeometryInstance
的用法可能需要根据Cesium的具体版本进行调整,因为Cesium的API在不同版本间可能会发生变化。
总结
Entity
API提供了更高级别的抽象,使创建和管理地图上的对象变得简单。Primitive
API提供了更多的控制和灵活性,但通常需要更多的设置和可能的性能考虑。- 在Cesium中,虽然
Entity
API没有直接的“矩形”类型,但你可以通过定义Polygon
的顶点来创建矩形。 - 使用
Primitive
API创建矩形通常需要更复杂的设置,包括创建几何体和指定渲染属性。
看一下代码效果
<template>
<div id="cesiumContainer" ref="cesiumContainer"></div>
</template>
<script setup>
// yarn add cesium
// 将cesium目录下的Build/Cesium4个目录拷贝到public,然后将widgets目录拷贝一份到src下
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
import { onMounted } from "vue";
// 设置cesium token
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";
// 设置cesium静态资源路径
window.CESIUM_BASE_URL = "/";
// 设置cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
// 西边的经度
89.5,
// 南边维度
20.4,
// 东边经度
110.4,
// 北边维度
61.2
);
onMounted(() => {
var viewer = new Cesium.Viewer("cesiumContainer", {
// 是否显示信息窗口
infoBox: false,
terrainProvider: Cesium.createWorldTerrain(),
});
// 隐藏logo
viewer.cesiumWidget.creditContainer.style.display = "none";
// 添加3D建筑
const osmBuildings = viewer.scene.primitives.add(
new Cesium.createOsmBuildings()
);
// 使用entity创建矩形
var rectangle = viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(
// 西边的经度
90,
// 南边维度
20,
// 东边经度
110,
// 北边维度
30
),
material: Cesium.Color.RED.withAlpha(0.5),
},
});
// primivite创建矩形
// 01-创建几何体
let rectGeometry = new Cesium.RectangleGeometry({
rectangle: Cesium.Rectangle.fromDegrees(
// 西边的经度
115,
// 南边维度
20,
// 东边经度
135,
// 北边维度
30
),
// 距离表面高度
height: 0,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
});
// 02-创建几何体实例
let instance = new Cesium.GeometryInstance({
geometry: rectGeometry,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
Cesium.Color.RED.withAlpha(0.5)
),
},
});
// 03-设置外观
let appearance = new Cesium.PerInstanceColorAppearance({
flat: true,
});
// 04-图元
let primitive = new Cesium.Primitive({
geometryInstances: instance,
appearance: appearance,
});
// 05-添加到viewer
viewer.scene.primitives.add(primitive);
viewer.camera.setView(viewer.entities);
});
</script>
<style>
* {
margin: 0;
padding: 0;
}
#cesiumContainer {
width: 100vw;
height: 100vh;
}
</style>