学习《Building Applications with FME Objects》 之八 空间索引

处理空间查询涵盖执行复杂和繁重的几何操作,例如:从1万个要素中查找某点附近的一个要素。暴力的解决办法是在整个范围内进行一系列的搜索,需要巨量的磁盘访问和巨量的几何条件测试。给一组要素创建空间索引可以大大提升搜索的执行效率,空间数据索引参考到空间索引,当使用空间索引时,一组要素将被索引。

 

FMEOReader对象使用setConstraints方法提供一些空间索引功能(详查Reading Features From a Dataset的Using Constraints章节),FME空间索引对象FMEOSpatialIndex提供精确、易用的基于R+树数据结构的空间索引,FMEOSpatialIndex的属性和方法如下图所示:

image

如果你的应用程序读取从提供本地(native)空间索引(可以通过FMEOReader的getProperties方法判断)的格式读取时,可以很简单的使用FMEOReader的setConstraints方法访问本地索引,尽管如此,你的应用程序仍然可以从FME空间索引对象获益,例如 ,如果有高程网格,本地(local)空间索引可以提高性能,而且FME空间索引对象对于巨量源数据集中创建一小部分要素的空间索引很有用。

 

本章可以学到如下内容:

  • 创建并打开空间索引
  • 索引一部分要素
  • 在索引后的要素执行空间查询
  • 关闭空间索引

 

创建并打开空间索引

必须使用FMEOSession对象的createSpatialIndex方法创建控件索引,一旦创建,就可以使用open方法打开,如下:

Dim fmeDirectives As FMEOStringArray
Dim sFileName As String

sFileName = sSpatialDir & "\SpatialIndex.ffs"
Set fmeDirectives = m_fmeSession.createStringArray
fmeDirectives.append ("PASSPHRASE")
fmeDirectives.append ("test")
fmeDirectives.append ("BYTE_ORDER")
fmeDirectives.append ("BIG_ENDIAN")
Set m_fmeSpatialIndex = m_fmeSession.createSpatialIndex( _
                      sFileName, "WRITE", fmeDirectives)
m_fmeSpatialIndex.open

 

createSpatialIndex方法第一个参数是存储索引要素的文件名和路径,习惯使用.ffs(FME feature store)作为要素数据文件扩展名,另一个文件与它同名,但扩展名为.fsi(FME spatial index),用来存储FME空间索引。

 

第二个参数是字符串值,用于指定访问模式,可以为WRITE或READ,用WRITE则可以创建一个新的索引,用READ则可以访问已存在的索引,当空间索引被创建并读取时,数据文件和关联的索引文件必须存在,否则会引发异常。在READ模式,视图给索引添加一个要素会导致异常。当空间索引创建并写入时,数据文件不需要存在,如果文件已存在,将被覆盖,在WRITE模式,尝试查询索引则不返回要素,当空间索引打开时,不能改变访问模式,些换WRITE和READ模式需要关闭空间索引后重新打开。

 

第三个参数是一个字符串数组,包含一些参数控制空间索引的创建。参数以键值对的形式提供,可以支持以下参数:

image

 

索引要素

FMEOSpatialIndex对象的store方法用来在打开的WRITE模式下一次添加一个要素到空间索引,例如:

Dim lEntries As Integer
Dim i As Integer
lEntries = m_fmeFeatureVector.entries
For i = 0 To lEntries - 1
Call m_fmeSpatialIndex.store(m_fmeFeatureVector.element(i))
Next i

m_fmeFeatureVector中的要素将被索引,因为store方法在.ffs文件中为每一个要素创建了深度拷贝,在m_fmeFeatureVector中改变要素不影响空间索引。

 

执行空间查询

 

FMEOSpatialIndex对象提供一套query方法用于执行空间查询,查询方法需要FMEOFeature对象作为参数。

image

查询代码与下面代码类似:

Dim fmeQueryFeature As FMEOFeature
Set fmeQueryFeature = m_fmeSession.createFeature
Call fmeQueryFeature.addCoordinate(0, 0, 0)
Call fmeQueryFeature.addCoordinate(1, 1, 0)
Call m_fmeSpatialIndex.queryEnvelope(fmeQueryFeature)

FMEOSpatialIndex通过空间查询维护一组被选择的要素,下面代码用fetch方法反复提取结果集。

Dim fmeDataFeature As FMEOFeature
Dim bEnd As Boolean
Set fmeDataFeature = m_fmeSession.createFeature
bEnd = False
Do While bEnd = False
    bEnd = m_fmeSpatialIndex.fetch(fmeDataFeature)
Loop

当结果集到结尾时,再次调用fetch将再次返回第一个要素(假定结果集不为空)。

 

关闭空间索引

可以使用close方法关闭空间索引。

Call m_fmeSpatialIndex.Close(True)

 

 

参考资料:

《Building Applications with FME Objects》February 2005

转载请注明文章来源 http://www.cnblogs.com/booolee

posted @ 2009-08-21 13:41  电电儿  阅读(552)  评论(1编辑  收藏  举报