學習《Building Applications with FME Objects》 之九 進階要素處理

來源:互聯網
上載者:User

在本教程第三張介紹了FME要素對象FMEOFeature的屬性、幾何圖形和座標系統,第三章是本章的基礎,本章將介紹更多更強大的要素處理功能。

 

介紹要素處理時,要區分基於要素的處理和基於集合的處理,基於要素的處理是指操作獨立要素,基於集合的處理是指操作一批獨立要素。

 

本章將學習:

  • 建立拓撲面(基於集合)
  • 融合多邊形(基於集合)
  • 緩衝要素(基於要素)
  • 產生多邊形內部點(基於要素)
  • 在要素上執行任意函數(基於要素)
  • 位移、旋轉和縮放幾何要素(基於要素)
  • 操作彙總要素(基於要素和集合)
  • 操作環要素(基於要素和集合)
  • 應用處理器管道(factory pipeline)(基於要素和集合)

 

建立拓撲面

一些GIS儲存幾何要素用來反映一個spaghetti(公路)資料模型,在公路模型中,任何幾何要素依賴於集合中的其他要素。

 

通常空間資料處理從一個公路模型到拓撲模型轉換到面要素,如果線有適當的節點FME可以解決這個問題:所有線交匯節點的開始和結束位置(或節點),建立一個拓撲面就是一個典型的基於集合的要素處理。

 

下面有10根線要素a,是一個公路模型,拓撲模型結果為彙總要素b,注意F10沒有包含在拓撲中,因為它沒有形成面要素。

FMEOFeature的processFeatures方法提供了一個一個簡單的方法為有正確節點的線建立拓撲面,該方法嘗試從1個多邊形、1個環、1個包含多邊形和環的彙總體建立面要素,產生的面關聯到一個要素。

例如,m_fmeFeatureVector包含一組相同feature type和要素屬性的線要素,下面代碼用processFeatures從m_fmeFeatureVector建立面,所有面要素屬性從第一個線要素複製而來:

Set fmeParams = m_fmeSession.createStringArray
Call fmeParams.append("fme_convert_to_area")
Call fmeParams.append("fme_drop_line")
Set fmeFeature = m_fmeSession.createFeature
Call m_fmeFeatureVector.element(0).cloneAttributes _
                                        (fmeFeature)
Call fmeFeature.processFeatures(m_fmeFeatureVector, _
                                            fmeParams)

注意:當調用processFeatures時,應用程式放棄了對要素向量的所有控制,fmeFeature本身會被刪除,如果程式後續還要用到femFeare,則在調用processFeatures前先對fmeFeature做深度拷貝(複製)。

 

預設情況下,未用的線要素(例中F10)也會被返回到結果要素數組m_fmeFeatureVector中,如果你不想返回未用的要素可以給fmeParams參數列表中店家fme_drop_line。

 

注意:如果應用程式需要處理大型資料集,則用processFeaturesOnDisk代替processFeatures,該方法工作在基於磁碟的對象集合。關於FMEOFeatureVectorOnDisk參看本教程第10章。

 

融合多邊形

通過消除相鄰的多邊形公用邊來融合多邊形,通過公用屬性來融合相鄰的多邊形,合并多邊形是非常實用的功能,例如,融合地區為一個銷售區片。

 

FMEOFeature的processFeatures提供簡單的方法來融合多邊形,給定一些多邊形,融合為一個面要素,可以是多邊形,環,或彙總體(含島),合并多邊形是一個典型的基於集合的要素處理。

 

例如,圖a的六個多邊形融合,結果b

 

m_fmeFeatureVector包含了一組相同屬性和要素類型的要素,下列代碼示範如何使用processFeatures去融合它們,合并後的要素屬性複製m_fmeFeatureVector中的第一個要素,處理結果關聯到一個fmeFeature。

 

Set fmeParams = m_fmeSession.createStringArray
Call fmeParams.append("fme_polygon_dissolve")
Call fmeParams.append("fme_drop_line")
Set fmeFeature = m_fmeSession.createFeature
Call m_fmeFeatureVector.element(0).cloneAttributes _
                                        (fmeFeature)
Call fmeFeature.processFeatures(m_fmeFeatureVector, _
                                            fmeParams)

 

提示:當processFeatures調用時,應用程式失去對要素的控制,fmeFeature被刪除,如果後續還想使用features,則在處理前應對其複製。

 

內部的線要素被返回到m_fmeFeatureVector,如果不想返回內部線要素,則給fmeParams參數添加fme_drop_line。

 

緩衝要素

一個緩衝區或簡單緩衝是一個與點,線,多邊形有一定距離的封閉的多邊形,緩衝區對於臨近分析非常有用,例如:尋找距離小河300英尺範圍內的森林面積,緩衝區是典型的基於要素的幾何處理。

 

FMEOFeature的buffer方法提供簡單的方法建立一個要素的緩衝,它用一個新的面要素來替換幾何要素以表示緩衝。下面代碼為m_fmeFeatureVector內的每一要素建立緩衝,並添加新要素到集合,結果m_fmeFeatureVector將包含原始要素和緩衝要素,每個要素距離原始要素0.1個單位,採樣角度5,緩衝要素屬性複製自原始要素。

 

Dim fmeFeature As FMEOFeature
Dim i As Integer
Dim lCount As Integer
lCount = m_fmeFeatureVector.entries
For i = 0 To lCount – 1

    Set fmeFeature = m_fmeSession.createFeature
    Call m_fmeFeatureVector.element(i).Clone(fmeFeature)
    Call fmeFeature.buffer(0.1, 5)
    fmeFeature.attribute("fme_type") = "fme_area"
    Call m_fmeFeatureVector.append(fmeFeature)
Next i

FMEEOFeature的buffer函數使用@Buffer函數。

 

建立對變形的內部點

給一個多邊形要素,你的應用程式產生這個多邊形內部點,使用FMEOFeature的generatePointInPolygon方法,基於要素的幾何處理。

 

下面建立m_fmeFeatureVector集合中的每個多邊形要素的內部點並添加到m_fmeFeatureVector,結果m_fmeFeatureVector將包含原始多邊形要素和新的點要素。點屬性複製自多邊形。

 

Dim fmeFeature As FMEOFeature
Dim sFeatureType As String
Dim i As Integer
Dim lCount As Integer
Dim X As Double
Dim Y As Double
Dim z As Double
sFeatureType = m_fmeFeatureVector.element(0).featureType
lCount = m_fmeFeatureVector.entries
For i = 0 To lCount - 1
    Set fmeFeature = m_fmeSession.createFeature
    Call m_fmeFeatureVector.element(i). _
                generatePointInPolygon(False, X, Y, z)
    Call fmeFeature.addCoordinate(X, Y, z)
    fmeFeature.featureType = sFeatureType
    fmeFeature.attribute("fme_type") = "fme_point"
    fmeFeature.GeometryType = foPoint
    Call m_fmeFeatureVector.append(fmeFeature)
Next i

 

generatePointInPolygon的第一個參數是一個標誌,如果為True,generatePointInPolygon將尋找中心點,需要比較長的計算時間,如果是三維要素,則也要運算Z值。

 

執行任意函數

FME函數提供了靈活的功能來操作要素,有兩類函數:屬性函數用來計算屬性值,要素函數用來操作要素。要素函數操作要素的幾何要素屬性,如果你的應用程式需要FME函數,你則需要閱讀FME Foundation手冊的FME Functions章節,FME Functions, Factories and Transformers手冊頁是非常有用的參考。

 

FMEOFeature對象的performFunction 方法可基於要素運行任何函數,例如,使用@Log要素函數去記錄一個要素:

Call fmeFeature.performFunction("@Log(Data Feature:,-1)", _
                                                    sResult)

提示:如果調用函數時沒有參數,performFunction將報告一個錯誤。

 

performFunction調用一個要素函數時,結果參數將返回一個Null 字元串。當屬性函數被調用,結果參數返回函數的輸出,例如,下面代碼添加一個lot_area屬性到要素:

Call fmeFeature.performFunction("@Area(1000)", sResult)
fmeFeature.real32Attribute("lot_area") = sResult

 

位移、旋轉、縮放要素

通過變換座標到新的位置來位移要素,位移需要指定x,y還有z(可選),FMEOFeature對象的offset方法用於位移。

 

另一個有用的幾何變換是圍繞一個中心點旋轉要素,FMEOFeature對象用rotate2D來圍繞中心逆時針旋轉要素。

 

還可以縮放要素,使用FMEOFeature的scale方法。

 

位移,旋轉,縮放都是典型的基於要素的幾何處理,例如:

 

Call m_fmeFeatureVector.element(i).offset(dXOffset, _
                                    dYOffset, dZOffset)
Call m_fmeFeatureVector.element(i).rotate2D(dXCenter, _
                                    dYCenter, dAngle)
Call m_fmeFeatureVector.element(i).scale(dXFactor, _
                                    dYFactor, dZFactor)

 

操作彙總要素

彙總要素在第三章介紹過了,FMEOFeature的splitAggregate方法用來將要素分解成非彙總要素並返回包含這些非彙總要素的列表。

注意:該方法不清除輸入的要素,僅添加結果。

 

有兩個辦法建立彙總要素:chopUp和buildAggregateFeature。

 

基於要素處理的chopUp方法用於將現有的非彙總面或線要素加入彙總,如果要素幾何圖形的向量超過一定數量,則超過的部分將不被彙總,最小的彙總閥值是10,對於面要素,chopUp分解面為非面的片段,對於線要素根據向量閥值打算為段,chopUp方法調用樣本:

Call m_fmeFeatureVector.element(i).chopUp(20)

基於集合處理的buildAggregateFeature 方法用輸入的幾何要素建立彙總幾何體,文法如下:

Call fmeFeature.BuildAggregateFeature(m_fmeFeatureVector)

操作環要素

環要素在第三章介紹過,FMEOFeature的getDonutParts方法返回組成環要素的多邊形幾何圖形。

注意:該方法不清除輸入要素,僅添加。

 

建立環要素可以十一偶那個makeDonuts方法。

 

makeDonuts方法從一些多邊形要素中構造一個或多個環要素,返回的結果是彙總體,該方法調用如下:

Call fmeFeature.makeDonuts(m_fmeFeatureVector, False)

該方法第二個參數是keepHoles標誌,如果為True,該方法返回作為要素島的多邊形。

 

outerShell方法獲得環要素的外圈多邊形,如果調用outerShell方法的要素不是環要素,則沒有作用,方法調用如下:

Call fmeFeature.outerShell

如果你處理的格式對環的組成部分座標有方向規則(左手或右手規則),則你可以使用getOrientation和setOrientation方法控制座標儲存順序。

 

應用處理器管道(Factory Pipeline)

 

FME處理器是整合了要素和屬性值的函數,並且被處理器管道所串連。處理器管道允許FME對象執行基於要素和基於集合的處理任務,實際上,所有本章介紹的要素處理都是用FMEOFeature方法,這些方法也都可以用要素處理器代替,用處理器管道代替內建方法需要一些設定,但它更強大,更易於修改和擴充。

 

如果想使用處理器管道,推薦你閱讀FME Foundation 手冊的FME Factories 章節,它提供了一些FME處理器的基礎資訊,FME Functions, Factories and Transformers 手冊也很有參考價值。

 

FMEOPipelin對象提供了介面來構造和使用處理器管道,方法和屬性如:

 

使用處理器管道需要以下步驟:

  • 建立和定義管道
  • 在管道中插入要素
  • 從管道擷取要素

 

建立和定義管道

建立新的處理器管道,你必須用FMEOSession對象的createFactoryPipeline方法,代碼如下:

Set fmePipeline = m_fmeSession.createFactoryPipeline( _
                                        "Test", fmeDirectives)

 

第一個參數是管道名,第二個參數允許你指定管道中的處理器和函數的參數,配置參數關鍵字必須有”__”首碼。

注意:FMEOPipeline的configureFunction方法為函數指定配置,例如@Lookup,@Relate和@Sql這些函數需要配置參數。

 

一旦管道被建立,有3個辦法指定要素處理器:

  • 放置所有的處理器到一個文字檔並調用addFactories方法。
  • 每個獨立的處理器放到一個字串,並為每一個字串調用addFactories方法。
  • 放置每一個處理器到FME字串數組並調用addFactoryFromStringArray。

你可以選擇使用你覺得合適的方法來添加處理器,首先所有的處理器管道在一個檔案中在開發和調試時較少發生錯誤,管道檔案使用標準的FME對應檔文法(包括串連字元)你可以用FME Universal Viewer應用管道到現有資料集來測試處理器管道(在Display Control面板中的View節點上點右鍵,Apply Pipleline命令)。

 

注意:在FME Universal Viewer 進行測試時,如果視圖中有多個資料集,則每個資料集將被一個對應的管道執行個體處理。

 

一旦管道功能被設計、實現和測試,addFactory和addFactoryFromStringArray方法可以將管道代碼與程式碼一同編譯,協助保護你的智慧財產權,這兩個方法也可以裝在基於檔案的管道,方法使用範例:

sFactory = "FACTORY_DEF * DonutHoleFactory "
sFactory = sFactory & "INPUT FEATURE_TYPE * "
sFactory = sFactory & "fme_geometry fme_donut "
sFactory = sFactory & "OUTPUT OUTERSHELL FEATURE_TYPE * "
sFactory = sFactory & "OUTPUT HOLE FEATURE_TYPE *"
Call fmePipeline.addFactory(sFactory, " ")

注意:當空格作為addFactory的分割符,函數調用則不能包含空格在參數列表中,如果處理器包含屬性值包含空格,你將需要選擇其他字元來代替空格作為分割幅(入”|” 或”;”)

 

 

下面的內容講解addFactorys方法。

 

插入一些要素到管道

一旦處理器管道被建立和定義,它就準備開始接受要素,添加要素到處理器管道,你的應用程式必須使用FMEOPipeline的processFeature方法:

Call fmePipeline.processFeature( _
       m_fmeFeatureVector.element(i))

processFeature方法處理傳入的要素,返回空值,如果應用程式希望保留原始要素,在處理前需要用FMEOFeature的clone方法做拷貝。

 

從管道返回一些要素

你的應用程式通過管道返回和處理要素,輸入的原始的要素並沒有被管道改變。

如果你的管道僅包含一個基於要素處理的處理器,在processFeature返回控制權給應用程式後,結果將理解可用,獲得返回的要素用getOutputFeature,例如:

Call fmePipeline.processFeature( _
       m_fmeFeatureVector.element(i))
bEnd = fmePipeline.getOutputFeature(fmeFeature)

當最後一個要素被讀取後,getOutputFeature返回True。

當管道包含一個或多個基於集合處理的處理器時,例如TopologyFactory,PolygonFactory或SortingFactory,你的應用程式在最後一個要素被插入後用FMEOPipeline的 allDone方法通知管道,在allDone方法返回控制權後,返回的要素立即變為可用。如果在allDone前調用getOutputfeature,則不能從輸入讀取要素,儘管有一些要素可能在管道中,但getOutputFeature將返回True。

 

注意:一個管道不能在調用allDone方法後重用,換句話說,調用allDone後,addFeature調用將失效。

 

綜合練習

下面展示了本章所以學知識,用基於檔案的處理器管道標記sPipelinefile來處理m_fmeFeatureVector中的要素。

Sub ApplyPipeline(sPipelineFile As String)
    Dim i As Integer
    Dim lCount As Integer
    Dim bEnd As Boolean
    Dim fmePipeline As FMEOPipeline
    Dim fmeFeature As FMEOFeature
    Dim fmeDirectives As FMEOStringArray
    Set fmePipeline = m_fmeSession.createFactoryPipeline( _
                                            "Test", fmeDirectives)
    Call fmePipeline.addFactories(sPipelineFile)
    lCount = m_fmeFeatureVector.entries
    For i = 0 To lCount - 1
        Call fmePipeline.processFeature( _
               m_fmeFeatureVector.element(i))
    Next i
    Call fmePipeline.allDone
    m_fmeFeatureVector.Clear
    bEnd = False
    Do While bEnd = False
        Set fmeFeature = m_fmeSession.createFeature
        bEnd = fmePipeline.getOutputFeature(fmeFeature)
        If bEnd = False Then
            Call m_fmeFeatureVector.append(fmeFeature)
        End If
    Loop
End Sub

 

如果你想建立一個拓撲面,你可以用上面的函數調用管道檔案,管道檔案內容如下:

FACTORY_DEF * PolygonFactory \
FACTORY_NAME POLYGONBUILDER \
INPUT FEATURE_TYPE *  \
fme_geometry fme_line  \
fType @FeatureType() \
GROUP_BY fType \
VERTEX_NODED \
OUTPUT POLYGON FEATURE_TYPE * \
@FeatureType(&fType) \
@RemoveAttributes(fType) \
fme_type fme_area

融合多邊形,可以用下面的管道檔案:

FACTORY_DEF * PolygonFactory \
FACTORY_NAME POLYGONBUILDER \
INPUT FEATURE_TYPE *  \
fme_geometry fme_line  \
fType @FeatureType() \
GROUP_BY fType \
VERTEX_NODED \
OUTPUT POLYGON FEATURE_TYPE * \
@FeatureType(&fType) \
@RemoveAttributes(fType) \
fme_type fme_area

至於緩衝區要素和產生多邊形內部點的管道檔案由讀者自行練習。

 

 

 

參考資料:

《Building Applications with FME Objects》February 2005

轉載請註明文章來源 http://www.cnblogs.com/booolee

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.