360免费建站教程,wordpress 邮件功能,wordpress时间排序,微信h5商城网站开发Cesium中通过 Primitive 高效添加 点、线、多边形、圆、椭圆、球、模型 等地理要素#xff0c;以下是各类地理要素的高效添加方式#xff1a;
一、公告板
1. 创建 BillboardCollection 并添加到场景
const billboards viewer.scene.primitives.add(new Ces…Cesium中通过 Primitive 高效添加 点、线、多边形、圆、椭圆、球、模型 等地理要素以下是各类地理要素的高效添加方式
一、公告板
1. 创建 BillboardCollection 并添加到场景
const billboards viewer.scene.primitives.add(new Cesium.BillboardCollection());
new Cesium.BillboardCollection() 创建一个新的 公告板集合BillboardCollection用于管理多个公告板Billboard。 viewer.scene.primitives.add(...) 将这个公告板集合添加到 Cesium 的 场景Scene 中使其能够被渲染。 作用 类似于创建一个“容器”用于高效管理多个公告板比如多个图标、标记点等而不是单独添加每个公告板单独添加会有更高的性能开销。 2. 向 BillboardCollection 添加一个公告板
billboards.add({position: Cesium.Cartesian3.fromDegrees(113.3244, 23.1049, 600),image: /Assets/nav.svg,width: 32,height: 32,scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 2e6, 0.2)
});
position: Cesium.Cartesian3.fromDegrees(113.3244, 23.1049, 600)
定义公告板的 3D 坐标位置
113.3244, 23.1049 是经纬度WGS84 坐标系。
600 是高度单位米表示公告板在地球表面上方 600 米处。
image: /Assets/nav.svg
公告板显示的 图片路径这里是 /Assets/nav.svg可以是一个 SVG 或 PNG 图标。
width: 32, height: 32
公告板的 尺寸宽度和高度均为 32 像素。
scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 2e6, 0.2)
视距缩放优化根据相机距离动态调整公告板大小
当相机距离 1000 米1e3 时公告板显示原始大小1.0 倍。
当相机距离 2000000 米2e6 时公告板缩小到 0.2 倍避免远处图标过大。 作用 在指定位置广州附近高度 600 米添加一个 导航图标nav.svg并优化其显示大小近大远小。 3、整体作用
这段代码的 核心功能 是
创建一个公告板集合BillboardCollection用于高效管理多个公告板。向集合中添加一个公告板指定其
位置经纬度 高度。显示的图片nav.svg。尺寸32x32 像素。视距缩放优化近大远小避免远处图标过大。
4、优化点
使用 BillboardCollection 而不是单独添加 Billboard
批量管理多个公告板时性能更高减少 GPU 调用次数。
scaleByDistance 优化
避免远处图标过大提升视觉效果。
支持 3D 位置含高度
不仅能在地表放置图标还能在 3D 空间如空中放置。
5、扩展用法
如果需要添加多个公告板可以循环调用 billboards.add()
const positions [{ lon: 113.3244, lat: 23.1049, height: 600 },{ lon: 113.3254, lat: 23.1059, height: 700 }
];
positions.forEach(pos {billboards.add({position: Cesium.Cartesian3.fromDegrees(pos.lon, pos.lat, pos.height),image: /Assets/nav.svg,width: 32,height: 32});
});
性能更好的方式
const billboards viewer.scene.primitives.add(new Cesium.BillboardCollection({scene: viewer.scene,debugShowBoundingVolume: false // 关闭调试框提升性能[4](ref)})
);const positions [{ lon: 116.40, lat: 39.91, image: icon1.png },{ lon: 121.47, lat: 31.23, image: icon2.png }
];const billboardList positions.map(pos {return {image: pos.image,position: Cesium.Cartesian3.fromDegrees(pos.lon, pos.lat),scale: 0.8,color: Cesium.Color.WHITE.withAlpha(0.9),horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM};
});// 批量添加减少渲染调用
billboards.add(billboardList);
6、动态更新策略
直接修改属性
const billboard billboards.get(0); // 获取第一个广告牌
billboard.scale 1.2; // 修改缩放比例
billboard.position Cesium.Cartesian3.fromDegrees(120.0, 30.0); // 更新位置
动态效果旋转/闪烁
// 通过 preRender 事件实现旋转动画[9](ref)
viewer.scene.preRender.addEventListener(() {const time Date.now() * 0.001;billboard.rotation time % (Math.PI * 2); // 持续旋转billboard.color.alpha 0.5 0.5 * Math.sin(time); // 透明度闪烁
});
按需更新
// 仅当广告牌可见时更新
if (billboard.show) {billboard.scale calculateScaleBasedOnDistance();
}
7、性能优化技巧
7.1 GPU 合并渲染 批量添加单次 billboards.add() 提交多个广告牌触发 GPU 实例化渲染。 纹理复用相同图片自动合并纹理减少 Draw Call。
7.2 距离动态控制
billboard.scaleByDistance new Cesium.NearFarScalar(1e3, 1.0, 1e5, 0.2);
billboard.translucencyByDistance new Cesium.NearFarScalar(1e4, 1.0, 2e5, 0.1); 近距离正常显示远距离缩小并渐隐降低渲染负载。 7.3 视锥体裁剪
viewer.scene.frustumCulling true; // 默认开启自动剔除视野外广告牌
8、内存管理机制
8.1 移除单个广告牌
billboards.remove(billboard); // 移除指定对象
8.2 批量清理
// 移除所有广告牌
billboards.removeAll();
// 或从场景中移除整个集合
viewer.scene.primitives.remove(billboards);
8.3 避免内存泄漏
// 销毁时释放资源
viewer.scene.primitives.destroyPrimitives true;
9、总结
代码部分作用new Cesium.BillboardCollection()创建公告板集合高效管理多个 Billboardviewer.scene.primitives.add(...)将集合添加到场景使其可渲染billboards.add({...})添加一个公告板指定位置、图片、尺寸和缩放优化
这段代码是 Cesium 中高效添加和管理 3D 图标/标记的标准方式适用于地图、仿真、游戏等场景。
二、文本
使用 Primitive API // 初始化Viewerconst viewer new Cesium.Viewer(cesiumContainer, {terrainProvider: Cesium.createWorldTerrain(),sceneMode: Cesium.SceneMode.SCENE3D});// 创建LabelCollection图元const labelCollection viewer.scene.primitives.add(new Cesium.LabelCollection({show: true,// 启用深度测试避免被地形遮挡需权衡性能depthTest: false}));// 批量添加文本标签const positions [{ lon: 116.404, lat: 39.915, text: 北京 },{ lon: 121.47, lat: 31.23, text: 上海 },// 更多位置数据...];positions.forEach(pos {labelCollection.add({position: Cesium.Cartesian3.fromDegrees(pos.lon, pos.lat),text: pos.text,font: 14px sans-serif, // 字体优化避免过大字号fillColor: Cesium.Color.WHITE,outlineColor: Cesium.Color.BLACK,outlineWidth: 2,// 垂直对齐文本位于坐标点下方verticalOrigin: Cesium.VerticalOrigin.BOTTOM,// 像素偏移微调位置pixelOffset: new Cesium.Cartesian2(0, -15)});});
三. 点Point
使用 Primitive API高性能适合大量点
const pointPrimitiveCollection viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection());
pointPrimitiveCollection.add({position: Cesium.Cartesian3.fromDegrees(113.3244, 23.1049, 0),color: Cesium.Color.RED,pixelSize: 10
});
四、线Polyline
使用 Primitive APIPrimitive 方式需手动构建 Geometry
const polylineCollection viewer.scene.primitives.add(new Cesium.PolylineCollection());
polylineCollection.add({positions: Cesium.Cartesian3.fromDegreesArray([113.3244, 23.1049,113.3254, 23.1059]),width: 2,material: new Cesium.ColorMaterialProperty(Cesium.Color.BLUE)
});
五、多边形Polygon
使用 Primitive APIPrimitive 方式需手动构建 Geometry
const polygonCollection viewer.scene.primitives.add(new Cesium.PolygonCollection());
polygonCollection.add({hierarchy: Cesium.Cartesian3.fromDegreesArray([113.3244, 23.1049,113.3254, 23.1059,113.3264, 23.1039]),material: new Cesium.ColorMaterialProperty(Cesium.Color.GREEN.withAlpha(0.5))
});六、圆Circle
使用 Primitive API需手动计算圆周点
// 初始化Cesium
const viewer new Cesium.Viewer(cesiumContainer, {terrainProvider: Cesium.createWorldTerrain(),baseLayerPicker: false, // 禁用底图选择器geocoder: false, // 禁用地理编码器homeButton: false, // 禁用主页按钮infoBox: false, // 禁用信息框sceneModePicker: false, // 禁用场景模式选择器selectionIndicator: false, // 禁用选择指示器navigationHelpButton: false, // 禁用导航帮助按钮animation: false, // 禁用动画控件timeline: false, // 禁用时间轴fullscreenButton: false // 禁用全屏按钮
});// 定义圆的中心点和半径
const centerLon 113.3244;
const centerLat 23.1049;
const radiusInMeters 1000;// 将圆心转换为 Cartesian3 坐标
const centerCartesian Cesium.Cartesian3.fromDegrees(centerLon, centerLat);// 计算圆的 Cartesian3 点集近似采样
const granularity Cesium.Math.RADIANS_PER_DEGREE; // 采样精度弧度/度
const positions [];
for (let angle 0; angle 360; angle granularity) {const radians Cesium.Math.toRadians(angle);// 计算圆周上的点基于球面坐标const x radiusInMeters * Math.cos(radians);const y radiusInMeters * Math.sin(radians);// 将局部坐标转换为全局 Cartesian3const point Cesium.Cartesian3.fromDegrees(centerLon x / 111320, // 经度偏移1度≈111320米centerLat y / (111320 * Math.cos(Cesium.Math.toRadians(centerLat))), // 纬度偏移考虑纬度缩放0 // 高度与圆心相同);positions.push(point);
}// 闭合圆首尾相连
positions.push(positions[0]);// 使用 Primitive API 添加圆
const primitiveCollection viewer.scene.primitives.add(new Cesium.PrimitiveCollection());
primitiveCollection.add(new Cesium.Primitive({geometryInstances: new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(positions),perPositionHeight: false // 固定高度}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(0.5) // 半透明蓝色)}}),appearance: new Cesium.PerInstanceColorAppearance({outline: true,outlineColor: Cesium.Color.RED,outlineWidth: 2})})
);// 定位相机到圆的位置
viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, 5000),orientation: {heading: Cesium.Math.toRadians(0),pitch: Cesium.Math.toRadians(-30)}
});
七、椭圆Ellipse
使用 Primitive API需手动计算椭圆点集
const viewer new Cesium.Viewer(cesiumContainer, {terrainProvider: Cesium.createWorldTerrain(),baseLayerPicker: false, // 禁用底图选择器geocoder: false, // 禁用地理编码器homeButton: false, // 禁用主页按钮infoBox: false, // 禁用信息框sceneModePicker: false, // 禁用场景模式选择器selectionIndicator: false, // 禁用选择指示器navigationHelpButton: false, // 禁用导航帮助按钮animation: false, // 禁用动画控件timeline: false, // 禁用时间轴fullscreenButton: false // 禁用全屏按钮
});// 定义椭圆的中心点、半长轴、半短轴和旋转角度const centerLon 113.3244;const centerLat 23.1049;const semiMajorAxis 2000; // 半长轴米const semiMinorAxis 1000; // 半短轴米const rotation Cesium.Math.toRadians(45); // 旋转角度弧度// 将椭圆中心转换为 Cartesian3 坐标const centerCartesian Cesium.Cartesian3.fromDegrees(centerLon, centerLat);// 计算椭圆的 Cartesian3 点集近似采样const granularity Cesium.Math.RADIANS_PER_DEGREE; // 采样精度弧度/度const positions [];for (let angle 0; angle 360; angle granularity) {const radians Cesium.Math.toRadians(angle);// 计算椭圆上的点基于参数方程const x semiMajorAxis * Math.cos(radians);const y semiMinorAxis * Math.sin(radians);// 旋转椭圆const rotatedX x * Math.cos(rotation) - y * Math.sin(rotation);const rotatedY x * Math.sin(rotation) y * Math.cos(rotation);// 将局部坐标转换为全局 Cartesian3const point Cesium.Cartesian3.fromDegrees(centerLon rotatedX / 111320, // 经度偏移1度≈111320米centerLat rotatedY / (111320 * Math.cos(Cesium.Math.toRadians(centerLat))), // 纬度偏移考虑纬度缩放0 // 高度与椭圆中心相同);positions.push(point);}// 闭合椭圆首尾相连positions.push(positions[0]);// 使用 Primitive API 添加椭圆const primitiveCollection viewer.scene.primitives.add(new Cesium.PrimitiveCollection());primitiveCollection.add(new Cesium.Primitive({geometryInstances: new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(positions),perPositionHeight: false // 固定高度}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(0.5) // 半透明蓝色)}}),appearance: new Cesium.PerInstanceColorAppearance({outline: true,outlineColor: Cesium.Color.RED,outlineWidth: 2})}));// 定位相机到椭圆位置viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, 5000),orientation: {heading: Cesium.Math.toRadians(0),pitch: Cesium.Math.toRadians(-30)}});
八、球Sphere
使用 Primitive APIPrimitive 方式需手动构建 Geometry
const sphereCollection viewer.scene.primitives.add(new Cesium.PrimitiveCollection());
sphereCollection.add(new Cesium.Primitive({geometryInstances: new Cesium.GeometryInstance({geometry: new Cesium.EllipsoidGeometry({vertexFormat: Cesium.VertexFormat.POSITION_AND_NORMAL,radii: new Cesium.Cartesian3(100, 100, 100)})}),appearance: new Cesium.PerInstanceColorAppearance()})
);
九、3D 模型Model
使用 Primitive APIPrimitive 方式需手动加载模型
性能优化建议
场景推荐方式原因少量要素Entity API代码简洁开发效率高大量要素1000Primitive API性能更高减少 CPU-GPU 通信开销动态更新如轨迹动画Entity API支持更简单的属性动画自定义渲染如特殊着色器Primitive API可深度定制渲染逻辑
总结
要素类型推荐 API示例代码点Entity 或 PointPrimitiveCollectionviewer.entities.add({ point: {...} })线Entity 或 PolylineCollectionviewer.entities.add({ polyline: {...} })多边形Entity 或 PolygonCollectionviewer.entities.add({ polygon: {...} })圆/椭圆Entity API更简单viewer.entities.add({ circle: {...} })球Entity API更简单viewer.entities.add({ ellipsoid: {...} })模型Entity API更简单viewer.entities.add({ model: {...} })