学习《Building Applications with FME Objects》 之三 操作要素(Features)2

简单几何图形

简单的几何图形是独立的几何图形,不关联影响位置表现的FME属性的,就是说,简单几何图形要素包含以下属性:

fme_geometry,fme_type:{fme_line,fme_line},{fme_point,fme_point},{fme_polygon,fme_area}

 

下面的代码演示如何从一个简单几何图形要素获取坐标并加入points列表colDisplayList集合:

Private Sub GetSimpleCoords(ByVal fmeFeature As FMEOFeature,
ByVal colDisplayList As Collection)
    Dim objPoint As clsPointObject
    Dim lCoordCount As Integer
    Dim i As Integer
    Dim colPointList As New Collection
    lCoordCount = fmeFeature.numCoords
    For i = 0 To lCoordCount - 1
        Set objPoint = New clsPointObject
        objPoint.X = fmeFeature.xCoordinate(i)
        objPoint.Y = fmeFeature.yCoordinate(i)
        Call colPointList.Add(objPoint)
    Next i
    Call colDisplayList.Add(colPointList)
End Sub

上面的clsPointObject类代码如下

Dim dXCoord As Double
Dim dYCoord As Double
Public Property Get X() As Double
X = dXCoord
End Property
Public Property Let X(ByVal dX As Double)
dXCoord = dX
End Property
Public Property Get Y() As Double
Y = dYCoord
End Property
Public Property Let Y(ByVal dY As Double)
dYCoord = dY
End Property

 

弧和椭圆几何图形

EllipsoidGeometry类(详见FME Feature Conceptual Data Model)描述了圆和椭圆。椭圆几何图形要素的fme_geometry为fme_point,fme_type为fme_ellipse。

 

ArcGeometry类描述了圆或椭圆弧,它的fme_geometry为fme_point,fme_type为fme_arc。ArcGeometry包含的属性还有:fme_rotation,fme_fme_primary_axis,fme_secondary_axis,fme_start_angle,fme_sweep_angle,具体描述如下:

 

image

 

范例:

a=主半径

b=次半径

tS=起始角

tE=终止角

tE-tS=夹角角度

thetaS=起始角度=45

thetaE=终止角度=180

thetaE-thetaS=夹角角度=135

 

属性值

fme_primary_axis=a=2.0

fme_secondary_axis=b=1.5

fme_start_angle=tS=arctan((a/b)*tan(thetaS))

fme_sweep_angle=tE-tS=arctan((a/b)*tan(thetaE))

arc tan stands for the inverse tangent of an angle.

 

image

 

image

 

一个椭圆几何图形是一个特殊的弧几何图形,其夹角为360度。

 

下面的代码用FMEOFeature的convertArcToPoints方法获得弧或椭圆类型要素的矢量表达,获得的点被添加到colDisplayList集合。

 

Private Sub GetArcCoords(ByVal fmeFeature As FMEOFeature, _
ByVal sFmeType As String, _
                         ByVal colDisplayList As Collection)
    Dim dCenterX As Double
    Dim dCenterY As Double
    Dim dRotation As Double
    Dim dPrimaryAxis As Double
    Dim dSecondaryAxis As Double
    Dim dStartAngle As Double
    Dim dSweepAngle As Double
    Dim dEndAngle As Double
    Dim fmeTempFeature As FMEOFeature
    Set fmeTempFeature = m_fmeSession.createFeature()
    Call fmeFeature.Clone(fmeTempFeature)
    dCenterX = fmeTempFeature.xCoordinate(0)
    dCenterY = fmeTempFeature.yCoordinate(0)
    dPrimaryAxis = fmeTempFeature.attribute( _
                                            kFME_Primary_Axis)
    dSecondaryAxis = fmeTempFeature.attribute( _

                                          kFME_Secondary_Axis)
    dRotation = fmeTempFeature.attribute(kFME_Rotation)
    If sFmeType = kFME_Type_Arc Then
        dStartAngle = fmeTempFeature.attribute( _
                                             kFME_Start_Angle)
        dSweepAngle = fmeTempFeature.attribute( _
                                             kFME_Sweep_Angle)
        dEndAngle = dStartAngle + dSweepAngle
    ElseIf sFmeType = kFME_Type_Ellipse Then
        dStartAngle = 0
        dEndAngle = 360
    Else
        Debug.Print "Invalid fme_type: " & sFmeType
        Exit Sub
    End If
    Call fmeTempFeature.convertArcToPoints(dCenterX, _
                    dCenterY, dPrimaryAxis, dSecondaryAxis, _
                    0, dStartAngle, dEndAngle, dRotation)
    Call GetSimpleCoords(fmeTempFeature, colDisplayList)
End Sub

converArcToPoints用于将弧或椭圆转化为一组线段,为了不改变原始要素,先用clone方法克隆了原始要素,GetSimpleCoords过程是之前章节编写的代码,用于将要素点写入列表集合。

 

环几何图形

DountGeometry类用来表达有洞的面要素,例如有岛的湖,标准的DonutGeometry包含的所有内部多边形都是完全被包含在外部多边形中,但也不保证所有的环都符合这个规则,例如从支持环几何图形存在自相交或重叠的数据源读取数据时,FME对象将尊重原始数据,下面是一个环几何图形:

 

image

 

环几何图形要素的fme_geometry为fme_dount,fme_type为fme_area。在要素逻辑图中,DountGeometry类是两个或多个PolygeonGeometry类,1个外部多边形和1个或多个内部多边形。

下面的代码将读取环几何图形要素的点到colDisplayList集合,FMEOFeature对象的getDontParts方法用于获得组成环的多边形,GetSimpleCoords过程是之前章节编写的代码,用于将要素点写入列表集合。

Private Sub GetDonutCoords(ByVal fmeFeature As FMEOFeature, _
                           ByVal colDisplayList As Collection)
    Dim fmeFeatureVector As FMEOFeatureVector
    Dim fmePolygonFeature As FMEOFeature
    Dim lEntries As Integer
    Dim i As Integer
    Set fmeFeatureVector = m_fmeSession.createFeatureVector
    Call fmeFeature.getDonutParts(fmeFeatureVector)
    lEntries = fmeFeatureVector.entries
    For i = 0 To lEntries - 1
        Set fmePolygonFeature = fmeFeatureVector.element(i)
        Call GetSimpleCoords(fmePolygonFeature, _
                                            colDisplayList)
    Next i
End Sub

 

提醒:FMEOFeature的getDonuParts方法不会清除输入要素向量。

 

Aggregate(聚合)几何图形

聚合几何图形要素的fme_geometry为fme_aggregate、fme_type为fme_point,fme_line,fme_area。FME聚合要素是由多个几何图形组成:几何图形均为独立的几何图形。通常情况下,聚合是由同类型部分组成,如果fme_type为fme_point,聚合包含的是点几何图形,fme_type为fme_line,聚合包含的是线几何图形,以此类推,你的应用程序也可处理不同类的聚合体,不同类聚合体没有fme_type值。

下面的代码获取聚合体的点并写入colDisplayList集合,FMEOFeature的splitAggregate方法用来分解聚合体的组成部分,splitAggregate方法的第二个布尔值参数表示如何分解聚合体中的聚合体,如果为FALSE,仅分解第一级聚合体。

Private Sub GetAggregateCoords( _
                        ByVal fmeFeature As FMEOFeature, _
                        ByVal colDisplayList As Collection)
    Dim fmeFeatureVector As FMEOFeatureVector
    Dim fmeComponentFeature As FMEOFeature
    Dim lEntries As Integer
    Dim i As Integer
    Set fmeFeatureVector = m_fmeSession.createFeatureVector
    Call fmeFeature.splitAggregate(fmeFeatureVector, True)
    lEntries = fmeFeatureVector.entries
    For i = 0 To lEntries - 1
        Set fmeComponentFeature = fmeFeatureVector.element(i)
        Call GetFeatureCoords(fmeComponentFeature, _
                                              colDisplayList)
    Next i
End Sub

上面代码将提取每一个聚合体组成部分的点。

 

Private Sub GetFeatureCoords( _
                            ByVal fmeFeature As FMEOFeature, _
                            ByVal colDisplayList As Collection)
    Dim sFmeType As String
    Dim sFmeGeometry As String
    Dim lFmeGeometry As Long
    Dim colPointList As Collection
    lFmeGeometry = fmeFeature.GeometryType
    sFmeGeometry = fmeFeature.attribute(kFME_Geometry)
    sFmeType = fmeFeature.attribute(kFME_Type)
    Select Case lFmeGeometry
         Case Is = foPoint
            Select Case sFmeType
                Case Is = kFME_Type_Point, kFME_Type_Text
                    Call GetSimpleCoords(fmeFeature, _
                                                  colDisplayList)
                Case Is = kFME_Type_Arc, kFME_Type_Ellipse
                    Call GetArcCoords(fmeFeature, sFmeType, _
                                                  colDisplayList)
            End Select
         Case Is = foLine, foPolygon
            Call GetSimpleCoords(fmeFeature, colDisplayList)
         Case Is = foDonut
            Call GetDonutCoords(fmeFeature, colDisplayList)
         Case Is = foAggregate
            Call GetAggregateCoords(fmeFeature, colDisplayList)
    End Select
End Sub

注意:GetSimpleCoords,GetArcCoords,GetDonutCoords过程都是之前编写的代码。

 

处理OpenGIS Geometries

OpenGIS为要素几何图形定义了一个Well-Know Text(WKT)表达方法,FMEOFeature对象允许应用程序使用importGeometryFromOGCWKT导入WKT或用exportGeometryFromOGCWKT导出WKT。

 

使用Schema(模式)要素

当你需要理解输入数据的结构、定义新的结构、改变已存在的结构时,模式要素非常有用。

FME对象数据要素使用良好的分类方法,如:Theme、Layer,Level,Table,Class,File等,一个模式要素提供了要素的分类数据模型。

注意:要素的类型容易和fme_type混淆,在要素逻辑数据模型图中,他们被分别表示为Feature::FeatureType和Feature::fme_type。

 

本教程第4章Reading Features from a Dataset中描述如何用FMEOFeature的readSchema方法访问模式要素。对应的数据要素的模式要素可以用FMEOFeature的getFeatureType方法获得。

 

例如:

属性类型

image

属性值

image

 

下面的代码将获得数据要素的每一个用户属性模式:

Public Sub GetSchemaInfo( _
                     ByRef fmeDataFeature As FMEOFeature, _
                     ByRef fmeSchemaFeature As FMEOFeature)
    Dim i As Integer
    Dim lCount As Integer

    Dim sName As String
    Dim sType As String
    Dim sMsg As String
    Dim fmeAttributeNames As FMEOStringArray
    Set fmeAttributeNames = m_fmeSession.createStringArray
    Call fmeDataFeature.allAttributeNames(fmeAttributeNames)
    lCount = fmeAttributeNames.entries
    For i = 0 To lCount - 1
        sName = fmeAttributeNames.element(i)
        sType = fmeSchemaFeature.attribute(sName)
        If sType <> "" Then
            sMsg = sMsg & sName & ": "
            sMsg = sMsg & sType & vbCrLf
        End If
    Next
MsgBox sMsg, vbOKOnly, "GetSchemaInfo"
    Exit Sub
End Sub

 

下表为用户属性的有效类型:

image

如果想为要素添加一个用户属性并写入目标数据集,则必须添加一个属性到对应的模式要数来指示属性类型,属性被添加到模式要素必须要有相同名的属性添加到数据要素,并且值必须符合上表的属性类型。

注意:模式不包含FME属性的类型信息(例如:fme_rotation),模式属性名字以*号开头的不能被你的应用程序使用。

 

模式要素包含一个几何要素类型描述,下面的代码演示如何返回要素类型列表:

Public Sub GetGeomInfo(ByRef fmeSchemaFeature As FMEOFeature)
    Dim i As Integer
    Dim sName As String
    Dim sGeom As String
    Dim sMsg As String
    Dim bFinished As Boolean
    i = 0
    bFinished = False
    Do While Not bFinished
        sName = "fme_geometry{" & i & "}"
        sGeom = fmeSchemaFeature.attribute(sName)
        If sGeom <> "" Then
            sMsg = sMsg & sName & ": "
            sMsg = sMsg & sGeom & vbCrLf
        Else
            bFinished = True
        End If
        i = i + 1
    Loop
    MsgBox sMsg, vbOKOnly, "GetGeomInfo"
End Sub

 

 

 

参考资料:

《Building Applications with FME Objects》February 2005

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

posted @ 2009-08-17 10:53  电电儿  阅读(744)  评论(0编辑  收藏  举报