https://blog.csdn.net/UmGsoil/article/details/74912638

我们先直接来看一个例子

  1. var viewer = new Cesium.Viewer('cesiumContainer');
  2. var flag = viewer.entities.add({
  3.   rectangle : {
  4.     coordinates : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
  5.     material : new Cesium.StripeMaterialProperty({
  6.     evenColor: Cesium.Color.WHITE,
  7.     oddColor: Cesium.Color.BLUE,
  8.     repeat: 5
  9.     })
  10.    }
  11. });

这是我们之前的写法,直接创建一个实体对象

而在这一章,我们将会使用几何和外观来创建实体对象,这样更灵活更有效率

首先,还是先看一下,上面那段代码的改造

  1. var viewer = new Cesium.Viewer('cesiumContainer');
  2. var scene = viewer.scene;
  3. //创建几何图形
  4. var instance = new Cesium.GeometryInstance({
  5. geometry : new Cesium.RectangleGeometry({
  6.   rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
  7.   vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
  8.   })
  9. });
  10. scene.primitives.add(new Cesium.Primitive({
  11. geometryInstances : instance,
  12. //使用系统自带的条纹样式
  13. appearance : new Cesium.EllipsoidSurfaceAppearance({
  14.   material : Cesium.Material.fromType('Stripe')
  15.   })
  16. }));

这样的写法自然是有优点也有缺点的

优点:

性能 - 当绘制大量静态图元时,直接使用几何形状可以将它们组合成单个几何体,以减少CPU开销并更好地利用GPU。并且组合是在网络上完成的,可以保持UI的响应。
灵活性 - 基元组合几何和外观。通过解耦,我们可以独立地修改。我们可以添加与许多不同外观兼容的新几何体,反之亦然。
低级访问 - 外观提供了接近于渲染器的访问,可以直接使用渲染器的所有细节(Appearances provide close-to-the-metal access to rendering without having to worry about all the details of using the Renderer directly)。外观使其易于:
编写完整的GLSL顶点和片段着色器。
使用自定义渲染状态。
缺点:

代码量增大,并且需要使用者对这方面有更深入的理解。
组合几何可以使用静态数据,不一定是动态数据。
primitives 的抽象级别适合于映射应用程序;几何图形和外观的抽象层次接近传统的3D引擎(Primitives are at the level of abstraction appropriate for mapping apps; geometries and appearances have a level of abstraction closer to a traditional 3D engine)(感觉翻译的不太好的地方都给上了原文)
我们可以用一个primitives画出多个几何图形,这样可以明显能看出性能上的优势

  1. var viewer = new Cesium.Viewer('cesiumContainer');
  2. var scene = viewer.scene;
  3. var instance = new Cesium.GeometryInstance({
  4.   geometry : new Cesium.RectangleGeometry({
  5.     rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
  6.     vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
  7.    })
  8. });
  9. var anotherInstance = new Cesium.GeometryInstance({
  10.   geometry : new Cesium.RectangleGeometry({
  11.     rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0),
  12.     vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
  13.   })
  14. });
  15. scene.primitives.add(new Cesium.Primitive({
  16.     geometryInstances : [instance, anotherInstance],
  17.     appearance : new Cesium.EllipsoidSurfaceAppearance({
  18.     material : Cesium.Material.fromType('Stripe')
  19.   })
  20. }));

对于不同的图形,我们可以单独给它们设置属性,这里,我们使用PerInstanceColorAppearance不同颜色来遮蔽每个实例

  1. var viewer = new Cesium.Viewer('cesiumContainer');
  2. var scene = viewer.scene;
  3. var instance = new Cesium.GeometryInstance({
  4.   geometry : new Cesium.RectangleGeometry({
  5.   rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
  6.   vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  7.   }),
  8.   attributes : {
  9.   //(红,绿,蓝,透明度)
  10.   color : new Cesium.ColorGeometryInstanceAttribute(0.0, 0.0, 1.0, 0.8)
  11.   }
  12. });
  13. var anotherInstance = new Cesium.GeometryInstance({
  14.   geometry : new Cesium.RectangleGeometry({
  15.     rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0),
  16.     vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  17.   }),
  18.   attributes : {
  19.     color : new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 0.8) }
  20.   });
  21.   scene.primitives.add(new Cesium.Primitive({
  22.   geometryInstances : [instance, anotherInstance],
  23.   appearance : new Cesium.PerInstanceColorAppearance()
  24. }));

可能这样大家还感觉不出来性能上的优势,那我们可以这样

  1. var viewer = new Cesium.Viewer('cesiumContainer');
  2. var scene = viewer.scene;
  3. var instances = [];
  4. //循环创建随机颜色的矩形
  5. for (var lon = -180.0; lon < 180.0; lon += 5.0) {
  6.   for (var lat = -85.0; lat < 85.0; lat += 5.0) {
  7.     instances.push(new Cesium.GeometryInstance({
  8.     geometry : new Cesium.RectangleGeometry({
  9.       rectangle : Cesium.Rectangle.fromDegrees(lon, lat, lon + 5.0, lat + 5.0),
  10.       vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  11.     }),
  12.     attributes : {
  13.       color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 0.5}))
  14.     }
  15.     }));
  16.   }
  17. }
  18. scene.primitives.add(new Cesium.Primitive({
  19.   geometryInstances : instances,
  20.   appearance : new Cesium.PerInstanceColorAppearance()
  21. }));

这里画了2592个不同颜色的矩形,而且速度非常快,这就更明显的看出primitives在性能上的优势了

虽然我们是通过一个primitives来创建的,但是我们可以给每一个几何图形一个id,这样我们就可以单独访问他们了、

  1. var instance = new Cesium.GeometryInstance({
  2.   id : "blue rectangle",
  3.   geometry : new Cesium.RectangleGeometry({
  4.   rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
  5.   vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  6. }),
  7. attributes : {
  8.   color : new Cesium.ColorGeometryInstanceAttribute(0.0, 0.0, 1.0, 0.8)
  9.   }
  10. });
  11. var anotherInstance = new Cesium.GeometryInstance({
  12.   id : "red rectangle",
  13.   geometry : new Cesium.RectangleGeometry({
  14.     rectangle : Cesium.Rectangle.fromDegrees(-85.0, 20.0, -75.0, 30.0),
  15.     vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
  16.   }),
  17.   attributes : {
  18.   color : new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 0.8)
  19.   }
  20. });
  21. scene.primitives.add(new Cesium.Primitive({
  22.   geometryInstances : [instance, anotherInstance],
  23.   appearance : new Cesium.PerInstanceColorAppearance()
  24. }));
  25. //获取屏幕事件管理器
  26. var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
  27. //监听屏幕输入事件(这里是监听左键点击事件)
  28. handler.setInputAction(function (movement) {
  29.   var pick = scene.pick(movement.position);
  30.   if (Cesium.defined(pick) ) {
  31.     switch (pick.id)
  32.     {
  33.       case 'blue rectangle':
  34.         console.log('Mouse clicked blue rectangle.');
  35.       break;
  36.       case 'red rectangle':
  37.         console.log('Mouse clicked red rectangle.');
  38.        break;
  39.     }
  40.   }
  41. }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

然后我点击两个矩形,控制台就输出了相应的log

当只要改变属性,不需要改变几何形状时候还可以把几何图形的创建给提出来

  1. var viewer = new Cesium.Viewer('cesiumContainer');
  2. var scene = viewer.scene;
  3. //使用同一个几何图形
  4. var ellipsoidGeometry = new Cesium.EllipsoidGeometry({
  5.   vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
  6.   radii : new Cesium.Cartesian3(300000.0, 200000.0, 150000.0)
  7. });
  8. var cyanEllipsoidInstance = new Cesium.GeometryInstance({
  9.   geometry : ellipsoidGeometry,
  10.   //不同的模型矩阵改变了位置
  11.   modelMatrix : Cesium.Matrix4.multiplyByTranslation(
  12.     Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)),
  13.       new Cesium.Cartesian3(0.0, 0.0, 150000.0),
  14.       new Cesium.Matrix4()
  15.     ),
  16.   //改变了颜色
  17.   attributes : {
  18.     color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CYAN)
  19.   }
  20. });
  21. var orangeEllipsoidInstance = new Cesium.GeometryInstance({
  22.   geometry : ellipsoidGeometry,
  23.   modelMatrix : Cesium.Matrix4.multiplyByTranslation(
  24.     Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)),
  25.     new Cesium.Cartesian3(0.0, 0.0, 450000.0),
  26.     new Cesium.Matrix4()
  27.   ),
  28.   attributes : {
  29.     color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE)
  30.   }
  31. });
  32. scene.primitives.add(new Cesium.Primitive({
  33.    geometryInstances : [cyanEllipsoidInstance, orangeEllipsoidInstance],
  34.   appearance : new Cesium.PerInstanceColorAppearance({
  35.   //不透明
  36.   translucent : false,
  37.   closed : true
  38.   })
  39. }));

在创建完之后,我们依旧可以动态的修改模型的属性,当然,这需要给模型加上一个id

var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;

var ellipsoidGeometry = new Cesium.EllipsoidGeometry({
  vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
  radii : new Cesium.Cartesian3(300000.0, 200000.0, 150000.0)
});

var cyanEllipsoidInstance = new Cesium.GeometryInstance({
  id : 'cyan',
  geometry : ellipsoidGeometry,
  modelMatrix : Cesium.Matrix4.multiplyByTranslation(
    Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)),
    new Cesium.Cartesian3(0.0, 0.0, 150000.0),
    new Cesium.Matrix4()
  ),

  attributes : {
    color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.CYAN)
  }
});

var orangeEllipsoidInstance = new Cesium.GeometryInstance({
  id : 'orange',
  geometry : ellipsoidGeometry,
  modelMatrix : Cesium.Matrix4.multiplyByTranslation(
    Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-100.0, 40.0)),
    new Cesium.Cartesian3(0.0, 0.0, 450000.0),
    new Cesium.Matrix4()
  ),
  attributes : {
    color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE)
  }
});

var primitive = scene.primitives.add(new Cesium.Primitive({
  geometryInstances : [cyanEllipsoidInstance, orangeEllipsoidInstance],
  appearance : new Cesium.PerInstanceColorAppearance({
  //不透明
  translucent : false,
  closed : true
  })
}));

setInterval(function() {
  var attributes1 = primitive.getGeometryInstanceAttributes('cyan');
  attributes1.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0}));
  var attributes2 = primitive.getGeometryInstanceAttributes('orange');
  attributes2.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.fromRandom({alpha : 1.0}));
},1000);

下面列举下cesium中的几何图形和外观,要注意的是有些外观和几何是不兼容的

几何图形                        描述
BoxGeometry                盒子
BoxOutlineGeometry             只有外部线条的的盒子
CircleGeometry               圆圈或挤压圆
CircleOutlineGeometry            同上(只有线条的圆,后面我就省略了)
CorridorGeometry              垂直于表面的折线,宽度以米为单位,可选择挤压高度
CorridorOutlineGeometry
CylinderGeometry              圆柱体,圆锥体或截锥体
CylinderOutlineGeometry
EllipseGeometry               椭圆或挤出椭圆
EllipseOutlineGeometry
EllipsoidGeometry              椭圆形
EllipsoidOutlineGeometry
RectangleGeometry             矩形或挤压矩形
RectangleOutlineGeometry
PolygonGeometry              具有可选孔或挤出多边形的多边形
PolygonOutlineGeometry
PolylineGeometry              一组宽度为像素的线段
SimplePolylineGeometry
PolylineVolumeGeometry           沿着折线挤压的2D形状
PolylineVolumeOutlineGeometry
SphereGeometry               一个球体
SphereOutlineGeometry
WallGeometry                垂直于地球的墙壁
WallOutlineGeometry
外观                             描述
MaterialAppearance              外观与所有几何类型一起使用,并支持材料描述阴影。
EllipsoidSurfaceAppearance           几何像几何平行于地球表面的“Material Appearance”一样,就像一个多边形,并且使用这个假设来通过程序上计算许多顶点属性来节省内存。
PerInstanceColorAppearance         使用每个实例的颜色来遮蔽每个实例。
PolylineMaterialAppearance          支持材料遮蔽Polyline。
PolylineColorAppearance           使用每顶点或每段着色来遮蔽折线。

原文链接:https://blog.csdn.net/UmGsoil/article/details/74912638

Cesium学习笔记(六):几何和外观(Geometry and Appearances)【转】的更多相关文章

  1. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  2. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  3. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  4. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  5. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  6. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  7. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  8. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  9. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

随机推荐

  1. windows搭建测试环境

    1.安装python  安装地址: https://www.python.org/downloads/windows/ Download Windows x86-64 executable insta ...

  2. 【DATAGUARD】物理dg配置客户端无缝切换 (八.3)--客户端TAF 配置

    [DATAGUARD]物理dg配置客户端无缝切换 (八.3)--客户端TAF 配置 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读 各位技术爱好者,看完本文后,你 ...

  3. bug集锦------持续但不定期 更新

    对于个人而言:这个错误集锦是很有必要的. 为了避免误导他人,其中个人想法:用 紫色加粗 标注. 1.springboot端口冲突: Protocol handler start failed2.spr ...

  4. opencv图像阈值操作

    使用threshold方法和adaptivethreshold方法对图像进行阈值分割操作. 1.使用threshold方法,设置一个阈值,将大于阈值的值变换为最大值,小于阈值的值变换为0. #-*- ...

  5. C程序中的内存分布

    一个典型的C程序存储分区包含以下几类: Text段 已初始化数据段 未初始化数据段 栈 堆 进程运行时的典型内存布局 1. Text段 Text段通常也称为代码段,由可执行指令构成,是程序在目标文件或 ...

  6. sqlzoo易错题

    https://sqlzoo.net/wiki/SELECT_names 答案在:https://github.com/codyloyd/sqlzoo-solutions/blob/master/SQ ...

  7. 初试linux,cp、rm、mv、file、umask等命令粗略使用方法

    ls --color=never 不要依據檔案特性給予顏色顯示: --color=always 顯示顏色 --color=auto 讓系統自行依據設定來判斷是否給予顏色 --full-time 以完整 ...

  8. js 变量以及函数传参

    一.变量: 基本类型是变量对象重新创建一个新值给变量对象空间,虽然是同一个值但是互不影响. 引用类型是也是将一个值重新赋值给新的变量空间,但是这个值是堆中对象的一个指针,新的变量和旧的变量指向是同一个 ...

  9. 基于Chrome内核(WebKit内核)定制开发DoNet浏览器

    1.    源起 a)     定制.Net浏览器 本人是一名C#开发者,而作为C#开发者,做客户端应用中最头痛的一件事就是没有一个好的UI解决方案, WinFrom嘛,效率虽然还不错,但是做一些特殊 ...

  10. test201909027 老Z

    30+100+40=170.数据出锅*2,也是没谁了. 装饰 快要到 Mope 的生日了,Mope 希望举行一场盛大的生日派对. 派对的准备工作中当然有装饰房间啦.Mope 的房间里有按从左到右的顺序 ...