vtk用户指南 第九章 空间数据可视化

        地理空间可视化是一门结合了传统科学可视化技术和信息可视化技术的学科,目的是显示地理上有组织的数据。VTK的地理空间可视化工具目前正在开发中,虽然VTK 5.4提供了一些渲染高分辨率地图的工具,但其API可能会在VTK的下一个版本中发生变化,甚至可能会打破向后兼容性.

9.1地理视图和表述

        VTK提供的主要地理空间可视化功能是能够将极大的纹理图像渲染到地球的几何表示上。图像数据及其纹理所依据的几何图形都必须是分层表示,根据需要从磁盘或网络服务器加载,否则它们将消耗太多内存,并且加载时间太长。下面的Python代码片段展示了在VTK中显示地图的最简单方法,以及结果的图片。有关versionUtil内容的信息,它解决了VTK 5.4和更高版本之间的一些差异,请参见第163页的“信息可视化”。还要注意,指定“- D <path>”将允许脚本从VTK数据存储库中查找图像数据。

from vtk import *
import vtk.util.misc
import versionUtil
# Read in a small map image from VTKData.
rd = vtkJPEGReader()
datapath = vtk.util.misc.vtkGetDataRoot()
rd.SetFileName(datapath + '/Data/NE2_ps_bath_small.jpg')
rd.Update()
# Create a GeoView
gv = vtkGeoView()
rw = versionUtil.SetupView(gv)
# Add both image and geometry representations to the view
mi = gv.AddDefaultImageRepresentation(rd.GetOutput())
# Start threads that fetch data as required
gv.GetTerrain().GetSource().Initialize(1)
mi.GetSource().Initialize(1)
# Render and interact with the view.
gv.GetRenderer().SetBackground(1, 1, 1)
gv.GetRenderer().SetBackground2(.5, .5, .5)
gv.GetRenderer().GradientBackgroundOn()
versionUtil.ShowView(gv)

        Geovis工具包提供了vtkView的专门化,它可以创建和管理一组角色,以渲染带有您提供的地球表面图像纹理的虚拟球体。vtkGeoView类还包括一个指南针小部件,它允许您通过单击并拖动指南针玫瑰来围绕垂直于视窗的轴旋转地球仪。指南针小部件还允许您使用距离滑块放大和缩小,并使用相机倾斜滑块更改地球表面法线和相机视图矢量之间的角度。

        GeoView的adddefaulultimagerepresentation方法创建了两个表示:一个是vtkgeoalignedimagerepresentation,它接受一个高分辨率的输入地图图像并生成一个tile层次结构;以及一个定义良好的vtkgeoterraindata,它生成一个代表三维地球的几何层次结构。当然,您可以自由使用不同的表示方式。接下来的两段将展示如何手动创建和添加表示。

        vtkGeoView将接受一个几何表示和多个对齐的图像表示。例如,通过向上面的脚本添加以下代码行(在调用ShowView()之前),您可以在基本地图的顶部显示一个云层。

# Read in a cloud cover image from VTKData.
rd2 = vtkJPEGReader()
datapath = vtk.util.misc.vtkGetDataRoot()
rd2.SetFileName(datapath + '/Data/clouds.jpeg')
rd2.Update()
# Create the texture image hierarchy from the cloud image
mi = vtkGeoAlignedImageRepresentation()
ms = vtkGeoAlignedImageSource()
ms.SetImage(rd2.GetOutput())
ms.Initialize(1) # Start a thread to respond to requests
mi.SetSource(ms)
gv.AddRepresentation(mi) # A GeoView may have multiple textures

        要向可视化中添加地理位置信息,vtkGeoView将接受坐标指定为纬度和经度的图形表示。在VTK 5.4中,表示必须是vtkGeoGraphRepresentation实例,但在以后的版本中,任何vtkRenderedGraphRepresentation的布局策略导致经纬度坐标都是可以接受的。

# Create a graph with lat-long coordinates
gs = vtkGeoRandomGraphSource()
if versionUtil.VersionGreaterThan(5, 4):
 gr = vtkRenderedGraphRepresentation
gr.SetLayoutStrategyToAssignCoordinates
('latitude', 'longitude')
 gr.SetEdgeLayoutStrategyToGeo(0.1)
else:
 gr = vtkGeoGraphRepresentation()
gr.SetInputConnection( gs.GetOutputPort() )
gv.AddRepresentation( gr )

        虽然vtkGeoView中的3d虚拟地球仪很有趣,但在某些情况下,使用地图投影显示整个地图,地理可视化可以提供更多信息
地球在一个平面上。vtkView的vtkGeoView2D子类、vtkGeoTerrain2D二维地图几何表示和vtkgeorepresentation2d图形表示提供了一种使用制图投影生成地图的方法。
vtkGeoView2D接受与vtkGeoView相同的图像表示,如下面的代码片段所示。

gv = vtkGeoView2D()
# Create the terrain geometry
ps = vtkGeoProjectionSource()
ps.Initialize(1)
ps.SetProjection(138) # The "robin" projection
tr = vtkGeoTerrain2D()
tr.SetSource(ps)
gv.SetSurface(tr) # A GeoView can only have one terrain
# Create image representations and graph source
# the same way as previous 3D examples.
# Omitted for brevity ...
# Render and interact with the view.
versionUtil.Show( gv )

9.2生成层次结构

        您可能已经从上面的示例中注意到,vtkGeoAlignedImageSource将单个图像文件的名称作为输入。随着图像文件大小的增加,生成一组可以下载到显卡的磁贴的成本变得很高。类似地,为了生成多边形图块,采样地图投影(通常需要在每个点上计算超越函数)也可能是繁重的。为了避免在每次启动程序时执行此工作,

        •vtkGeoAlignedImageRepresentation和vtkGeoTerrain类提供了savedatase()方法来保存生成的瓷砖层次结构到目录中,并且

        •可以使用名为vtkFileImageSource和vtkFileTerrainSource的替代源从磁盘读取这些瓷砖,而不是从源图像或地图投影中动态生成它们。

        现在我们已经介绍了如何使用vtkGeoView和vtkGeoView2D以及它们的匹配表示,接下来的部分将讨论表示如何与提供底层数据的源一起工作。

9.3分层数据源——按需解析

        在上面的示例中,您可能已经注意到图像和地形表示各自管理一个源对象。这些源对象是分层图像或几何数据的实例,它们都继承自vtkGeoSource。vtkGeoSource类是一个抽象基类,它提供了一种一致的方式来执行允许交互式呈现的按需加载。因为从磁盘或网络加载几何图形和图像数据会在渲染中引入不希望出现的延迟,所以vtkGeoSource类使用线程异步加载请求的数据。每次渲染发生时,已经加载到vtkGeoSource子类实例中的内容将用于绘制。每当该内容在层次结构中不够深,无法产生足够精确的呈现时,就会向请求列表中添加新的层次结构节点。vtkGeoSource子类中的辅助线程负责加载请求的节点,并向主线程发出信号,表明新的图像或几何节点已准备好插入层次结构。

        vtkGeoSource的vtkGeoAlignedImageSource子类表示图像贴片的层次结构。每个tile在经纬度坐标空间(latlong -space)的矩形块上提供一个规则采样的图像。这些贴图被纹理化到从另一个层次获得的几何体(polydata)上。VTK提供了两个几何层次的来源:

•通过渲染管道(如OpenGL®)投影到屏幕空间的三维坐标,或

•通过传统地图投影投影到制图空间的二维坐标。三维屏幕空间多数据层次结构由名为vtkGeoGlobeSource的类表示;图9-4在VTK的二维地理空间视图上显示与图9-3相同的图形。

这些类生成或读取几何图形并呈现层次结构,但它们不确定应该使用层次结构中的哪些节点进行呈现。这个任务是为地形类保留的。

9.4地形

        每种情况都存在一个地形类,并引用vtkGeoSource的一个子类,从中获得地球几何形状的表示。地形类是负责从vtkGeoSource请求几何体并配置用于渲染已加载的层次结构切割的演员列表的表示。由地形类创建的角色被重用,因为不同的贴图是由vtkGeoSource提供的。除了将多数据从贴图分配给角色外,地形类还分配用于纹理几何的图像数据。在支持多纹理的硬件上,可以为每个贴图分配多个纵向对齐的图像。

        在三维情况下,使用vtkGeoTerrain类表示地球,该类提供近似球体的矩形块,并根据相机的位置和方向以不同的分辨率进行镶嵌。坐标以米为单位。

        在二维的情况下,地球是使用vtkGeoTerrain2D类来表示的,该类提供了矩形块,其坐标在一些地图空间中。地图空间坐标的单位根据所使用的地图投影而变化。因为vtkPoints类要求所有点有3个坐标,但只有2个是有效的,所以所有的z坐标值都是0。这些块是多边形数据,其中可能包含三角形和四边形。层次结构中用于呈现的补丁子集是基于它们与视口像素大小相比表示地图投影的误差来选择的。

9.5地图投影

        在二维情况下应用的地图投影是由vtkGeoProjection类提供的。为了转换到或从地图坐标,vtkGeoTransform类需要一个源和目标vtkGeoProjection实例,并使用VTK/Utilities中的libproj4库来转换点。因为vtkGeoTransform继承自vtkAbstractTransform类,所以vtkTransformFilter可以用来转换任何您想要的数据到地图空间或从地图空间。默认情况下,新的vtkGeoProjection实例被设置为名为“latlong”的自然制图转换。提供了180多个投影,其中一些如图9-5所示。请注意,许多预测并不打算用于整个地球,而是用于一个小区域。如果您试图在太大的域上使用这些投影,结果通常会令人困惑和不连贯。

        图9-5 libproj4提供的一些有趣的地图投影下面的例子说明了如何使用地图投影将矢量数据从latlong空间转换为地图空间。示例中的矢量数据是由vtkgeograticle类提供的,它生成一个网格,用恒定的纬度和经度线覆盖地球。栅极附近采样率较低,以避免杂波。

# The default is latlong
# (no projection at all)
ps = vtkGeoProjection()
# Interesting destination
# projections to try:
# wintri, rouss, robin, eck1
pd.SetName('wintri') # Use the Robinson projection
pd.SetCentralMeridian(0)
# The vtkGeoTransform class moves points from one projection to
# another by applying the inverse of the source projection and
# the forward projection of the destination to each point.
gt = vtkGeoTransform()
gt.SetSourceProjection(ps)
gt.SetDestinationProjection(pd)
# We will obtain points in lat-long coordinates from the
# vtkGeoGraticule. It creates a grid that covers the globe in
# lat-long coordinates.
gg = vtkGeoGraticule()
gg.SetLongitudeBounds(-180, 180)
gg.SetLatitudeBounds(-90, 90)
# How many grid points should there be along the latitude?
gg.SetLatitudeLevel(3)
# How many grid points should there be along the longitude?
gg.SetLongitudeLevel(3)
# The vtkTransformFilter is a vtkAlgorithm that uses a transform
# to map points from one coordinate system to another.
tr = vtkTransformFilter()
tr.SetTransform(gt)
tr.SetInputConnection(gg.GetOutputPort())
# Create a mapper, actor, renderer, to display the results.

本书为英文翻译而来,供学习vtk.js的人参考。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值