我正在尝试实现一个显示服务器发送的栅格数据的图层。服务器协议发送的数据在广泛使用的浏览器中没有内置支持(这是一个jpeg2000数据)。因此,我正在自己解码数据并让它给 Cesium 显示。
是什么让它有点复杂:
服务器是有状态的,因此客户端和服务器都应该维护一个通道。该通道与单个感兴趣区域相关联。区域可能会随着时间而改变,但在每个时间点,只有一个区域供服务器在通道上发送数据。我可以在会话中使用一些频道,但是服务器在频道数量非常少的情况下表现不佳。
感兴趣的区域具有统一的分辨率(因此对于 3D 来说是有问题的)。
服务器支持逐步发送数据逐渐提高质量(jpeg2000 中的“质量层”),由于可用的网络资源非常少,我想使用这个属性。
就 CPU 时间而言,解码很繁重。
作为第一阶段,我实现了一个 ImageryProvider,它只是为渲染引擎请求的每个图块创建一个通道。它工作但创建了太多的连接,我不喜欢渐进式渲染。此外,性能很差,这个问题几乎可以通过实施优先机制来解决,该机制首先在 Cesium 查看器的视图区域中解码图块。
接下来我实现了一个自渲染光栅“层”,它根据视图区域改变通道的感兴趣区域。然后多通道问题得到解决,我享受渐进式渲染。但是我遇到了以下问题:
一个。我用来显示解码像素的方法是实现一个图像提供程序,它显示带有解码像素的单个 Canvas。每次更新图像(重新定位或逐步解码)时,我都必须删除旧的图像提供程序并用新的图像提供程序替换它。我想这不是做这些事情的正确方法,它可能会导致一些不良行为,例如在用新的提供者替换旧提供者时出现错误的 z 顺序等。其中一些问题可以通过使用带有图像材料的原语来解决,但是我必须使用图像的数据 URL 形式。这样做会降低性能,因为它会导致大量从画布到数据 URL 的转换。
湾。我必须编写特殊代码来理解视图区域,以便将其发送到服务器(使用 pickEllipsoid 和类似功能)。我猜这段代码是在 Cesium 引擎中完成的东西的重复。此外,我在一些讨论中看到 2D 不支持 pickEllipsoid。一般来说,我很高兴有一个为我计算视图区域的函数,而不是自己实现该代码。
C。我实现它的方式引发了一个 API 问题:与添加和删除图像提供程序(addImageryProvider() 方法和 removeLayer() )的 Cesium 的漂亮 API 不同,在我的实现中,用户只需要使用我向他公开的方法(例如,接受 Viewer 作为参数的方法 add())。
d。在 3D 模式下,当分辨率不均匀时,图像在近距离区域不清晰。我知道这是一个固有的问题,因为我的服务器的工作方式,只是指出来。
我认为我在这里真正缺少的是一种实现插件的方法,它比 ImageryProvider 的接口更强大:实现一个自渲染光栅层,它从渲染引擎接收视图区域更改事件,并可以决定何时以及如何刷新它的瓷砖。另一种选择(这对我来说甚至更好,但我猜其他人不太可重用)是将视图区域中的图块列表公开给 ImageryProvider 实现。
应对这种情况的正确方法是什么?