当前位置: 首页 > news >正文

Entity API vs Primitive API 详细对比

Entity API vs Primitive API 详细对比


1. 核心概念

Entity API(高层抽象)

  • 面向对象:每个 Entity 代表一个独立的地理对象
  • 数据驱动:基于时间动态的属性系统
  • 易用性优先:API 设计简洁,上手快

Primitive API(底层图形)

  • 面向图形:直接操作 WebGL 渲染层
  • 性能优先:批量渲染,减少 draw call
  • 灵活性高:可以精细控制渲染细节

2. 代码对比

添加一个多边形

// ========== Entity API ==========
const entity = viewer.entities.add({name: '区域A',polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray([120, 30,121, 30,121, 31,120, 31]),material: Cesium.Color.RED.withAlpha(0.5),outline: true,outlineColor: Cesium.Color.BLACK,height: 0,extrudedHeight: 100000},properties: {population: 1000000,area: 500}
});// 后续可以动态修改
entity.polygon.material = Cesium.Color.BLUE;
entity.show = false;// ========== Primitive API ==========
const instance = new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([120, 30,121, 30,121, 31,120, 31])),height: 0,extrudedHeight: 100000}),id: 'area-a',attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.5))}
});const primitive = viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: instance,appearance: new Cesium.PerInstanceColorAppearance({closed: true,translucent: true})
}));// Primitive 创建后难以修改单个属性
// 需要通过 getGeometryInstanceAttributes 修改
const attributes = primitive.getGeometryInstanceAttributes('area-a');
attributes.color = [0, 0, 255, 128]; // RGBA,需要手动计算

3. 主要区别对比表

特性Entity APIPrimitive API
学习曲线简单,10分钟上手复杂,需要理解图形学概念
性能较差(每个Entity独立渲染)优秀(批量渲染)
渲染效率1000个Entity会卡顿可处理10万+实例
动态修改容易,直接修改属性困难,需要重建或特殊API
时间动态原生支持时间轴动画不支持,需手动实现
拾取交互自动支持,返回Entity对象需要手动配置ID
数据绑定支持properties自定义属性只能存储ID
聚合支持Clustering不支持
内存占用较高较低

4. 渲染原理差异

Entity API 渲染流程

Entity对象 → EntityCollection → 
内部转换为Primitive → 每个Entity独立渲染 → 
多次WebGL Draw Call

问题

  • 1000个多边形 = 1000次 Draw Call = 卡顿

Primitive API 渲染流程

多个GeometryInstance → 合并为一个Primitive → 
一次WebGL Draw Call → 高效渲染

优势

  • 1000个多边形实例 = 1次 Draw Call = 流畅

5. 详细功能对比

5.1 创建多个对象

// ========== Entity API ==========
// 缺点:每个对象独立渲染
for (let i = 0; i < 1000; i++) {viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(120 + i * 0.01, 30),point: {pixelSize: 10,color: Cesium.Color.RED}});
}
// 结果:1000次Draw Call,严重卡顿// ========== Primitive API ==========
// 优点:批量渲染
const pointCollection = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection()
);for (let i = 0; i < 1000; i++) {pointCollection.add({position: Cesium.Cartesian3.fromDegrees(120 + i * 0.01, 30),pixelSize: 10,color: Cesium.Color.RED});
}
// 结果:1次Draw Call,流畅

5.2 动态修改

// ========== Entity API ==========
const entity = viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(120, 30),point: {pixelSize: 10,color: Cesium.Color.RED}
});// 轻松修改
entity.point.color = Cesium.Color.BLUE;
entity.position = Cesium.Cartesian3.fromDegrees(121, 31);
entity.show = false;// ========== Primitive API ==========
const pointCollection = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection()
);const point = pointCollection.add({position: Cesium.Cartesian3.fromDegrees(120, 30),pixelSize: 10,color: Cesium.Color.RED,id: 'point-1'
});// 可以直接修改(Collection类型支持)
point.color = Cesium.Color.BLUE;
point.position = Cesium.Cartesian3.fromDegrees(121, 31);
point.show = false;// 但对于Primitive,修改颜色需要特殊API
const primitive = viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: instance,appearance: new Cesium.PerInstanceColorAppearance()
}));// 修改颜色
const attributes = primitive.getGeometryInstanceAttributes('id');
attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.BLUE
);

5.3 时间动态属性

// ========== Entity API ==========
// 原生支持时间线动画
const entity = viewer.entities.add({position: new Cesium.SampledPositionProperty(),point: {pixelSize: 10,color: new Cesium.SampledProperty(Cesium.Color)}
});// 添加时间采样点
const start = Cesium.JulianDate.now();
for (let i = 0; i < 100; i++) {const time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());// 位置随时间变化entity.position.addSample(time,Cesium.Cartesian3.fromDegrees(120 + i * 0.01, 30));// 颜色随时间变化entity.point.color.addSample(time,Cesium.Color.fromHsl(i / 100, 1, 0.5));
}viewer.clock.shouldAnimate = true; // 自动播放// ========== Primitive API ==========
// 不支持时间动态,需手动实现
const pointCollection = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection()
);const point = pointCollection.add({position: Cesium.Cartesian3.fromDegrees(120, 30),pixelSize: 10,color: Cesium.Color.RED
});// 手动监听时钟更新
viewer.clock.onTick.addEventListener((clock) => {const currentTime = clock.currentTime;// 手动计算当前时间的位置和颜色point.position = calculatePositionAtTime(currentTime);point.color = calculateColorAtTime(currentTime);
});

5.4 交互拾取

// ========== Entity API ==========
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction((click) => {const pickedObject = viewer.scene.pick(click.position);if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {const entity = pickedObject.id; // 直接获取Entity对象console.log('点击了:', entity.name);console.log('属性:', entity.properties);// 高亮显示entity.polygon.material = Cesium.Color.YELLOW;}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);// ========== Primitive API ==========
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction((click) => {const pickedObject = viewer.scene.pick(click.position);if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.primitive)) {const primitive = pickedObject.primitive;const id = pickedObject.id; // GeometryInstance的ID(字符串)console.log('点击了ID:', id);// 需要自己维护ID到数据的映射const data = myDataMap.get(id);// 修改颜色(复杂)const attributes = primitive.getGeometryInstanceAttributes(id);if (attributes) {attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.YELLOW);}}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

6. 性能测试对比

测试场景:渲染10000个多边形

// ========== Entity API ==========
console.time('Entity加载');
for (let i = 0; i < 10000; i++) {viewer.entities.add({polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray([120 + i * 0.001, 30,120 + i * 0.001 + 0.001, 30,120 + i * 0.001 + 0.001, 30.001,120 + i * 0.001, 30.001]),material: Cesium.Color.RED.withAlpha(0.5)}});
}
console.timeEnd('Entity加载');
// 结果:约 15000ms,FPS < 10,严重卡顿// ========== Primitive API ==========
console.time('Primitive加载');
const instances = [];
for (let i = 0; i < 10000; i++) {instances.push(new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([120 + i * 0.001, 30,120 + i * 0.001 + 0.001, 30,120 + i * 0.001 + 0.001, 30.001,120 + i * 0.001, 30.001]))}),id: `polygon-${i}`,attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.5))}}));
}viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: instances,appearance: new Cesium.PerInstanceColorAppearance({translucent: true})
}));
console.timeEnd('Primitive加载');
// 结果:约 2000ms,FPS 50-60,流畅

性能提升:7.5倍


7. Primitive API 的特殊类型

Primitive API 有多种优化的集合类型:

// 点集合
const pointCollection = new Cesium.PointPrimitiveCollection();
viewer.scene.primitives.add(pointCollection);// 广告牌集合
const billboardCollection = new Cesium.BillboardCollection();
viewer.scene.primitives.add(billboardCollection);// 标签集合
const labelCollection = new Cesium.LabelCollection();
viewer.scene.primitives.add(labelCollection);// 折线集合
const polylineCollection = new Cesium.PolylineCollection();
viewer.scene.primitives.add(polylineCollection);// 通用Primitive(多边形等)
const primitive = new Cesium.Primitive({geometryInstances: [...],appearance: new Cesium.PerInstanceColorAppearance()
});
viewer.scene.primitives.add(primitive);

8. 选择建议

使用 Entity API 的场景:

✅ 数据量小(< 1000个对象)
✅ 需要频繁修改属性
✅ 需要时间动态效果
✅ 快速原型开发
✅ 需要数据绑定和属性管理
✅ 使用DataSource加载GeoJSON/KML

使用 Primitive API 的场景:

✅ 大数据量(> 1000个对象)
✅ 性能要求高
✅ 静态展示为主
✅ 需要自定义Shader
✅ 批量渲染相似对象
✅ 生产环境的优化需求


9. 混合使用策略

class HybridRenderer {constructor(viewer) {this.viewer = viewer;// 少量重要对象用Entity(可交互)this.entities = viewer.entities;// 大量背景数据用Primitive(高性能)this.primitives = viewer.scene.primitives;}// 添加可交互的重点对象addInteractiveObject(data) {return this.entities.add({name: data.name,polygon: {hierarchy: data.positions,material: Cesium.Color.RED},properties: data.properties});}// 批量添加背景对象addBackgroundObjects(dataArray) {const instances = dataArray.map(data => new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(data.positions)}),id: data.id,attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.GRAY.withAlpha(0.3))}}));this.primitives.add(new Cesium.Primitive({geometryInstances: instances,appearance: new 
http://www.dtcms.com/a/607015.html

相关文章:

  • 织梦cms 网站计数广东个人网站备案
  • 做公司年报网站登录密码是什么创立外包网站
  • 线程本地(ThreadLocal)的缓存容器
  • 可以做项目的网站网站开发工作 岗位怎么称呼
  • 【OpenCV + VS】调用摄像头与视频文件处理
  • 云手机的网络架构
  • 品牌网站建设四川微信开发公众号
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段-二阶段(18):文法和单词-第四课
  • wordpress是mvc架构吗google seo网站 被k
  • 【数据分享】2000-2022年我国省市县三级的逐年牛、山羊、绵羊和马的牲畜数量数据(Shp/Excel格式)
  • 利用模板建网站工信部信息备案网站
  • 阿里云建设网站步骤网络公司网站首页图片
  • 徐州做网站企业WordPress右下角提醒
  • 凡科建站做的网站收录慢吗娱乐视频直播网站建设
  • 【目标检测】热力图可视化脚本
  • 怎样用dede搭建网站网页传奇怎么删除
  • 做网站直播平台制作一个论坛网站多少钱
  • 电力设备机械结构声发射特征提取与深度学习驱动的裂纹损伤预测
  • 力扣面试150题打卡第五天
  • 做a货包好的网站专门做办公的网站
  • Common Go Mistakes(Ⅲ 控制结构)
  • vs建设网站营销的方法和技巧
  • 用vs2010做网站并连数据库2021ppt模板免费下载 素材
  • 【2025 最新】 Maven 下载安装与配置教程(超详细带图文Windows 版):从入门到实战
  • 做瞹视频网站哪里看志鸿优化设计官网
  • 南宁网站建设怎么样封开网站建设
  • 易语言exe反编译器 | 高效破解和安全分析工具
  • 智能决策系统落地后如何进行数据集成与安全保障?
  • 企业备案网站可以做论坛吗西安有哪些网站
  • 网站程序超市做网站怎样才能接单