在FME中調用PythonCaller介紹+實例+下載

0 前言

Python是一門強大而又靈活的編程語言,其本身語法簡潔嚴謹容易上手,擁有衆多開發者分享的拓展模塊,是IT從業者手中的一把利器。FME擅長可視化操作,是數據處理行業的瑞士軍刀。當兩者結合在一起,那就是雙雄聯手,所向披靡。

1 Python的版本

目前主流使用的版本有Python2.x和Python3.x。Python3.x相對於Python2.x是一個大的升級,他們之間有一些不同的地方,在選擇版本需要注意。
比如說“print”命令,在Python2.x版本中是命令語句,其後加上字符串可以直接使用,到了Python3.x版本,“print”變成了函數,參數必須寫在括號內部。

print 'hello world'    #Python2.x中print的用法
print('hello world')   #Python3.x中print的用法

還有一個大的區別是Python2.x使用ASCII編碼,Python3.x使用utf-8編碼,因此Python3.x直接支持中文字符串的輸入輸出,而Python2.x還需專門設置字符編碼。在沒有特殊要求的情況下,推薦使用Python3.x。

2 PythonCaller轉換器

在FME中調用Python腳本可以通過2個裝換器:PythonCreater 和 PythonCaller。
PythonCreater主要用來創建要素,而處理FME中的要素則需要使用PythonCaller。
PythonCaller有一個入口,可以接收其他工作流的要素輸出, 作爲輸入。

打開PythonCaller轉換器的參數窗口可以看到已經定義好的代碼模板,代碼模板定義了一個函數和方法,兩者是有所區別的。幫助文檔上推薦使用“函數”(Function)來逐條處理輸入的要素,使用“方法”(Class)來處理複雜的計算,比如說需要讀取整個列表的運算。而在代碼窗口的上方,需要在“Class or Function to Process Features”參數中指定函數名或方法名來確定使用哪個函數或方法來處理要素。
PythonCaller Parameters

2.1 函數(Function)

函數只能接收一個“feature object”作爲輸入參數,“feature obejct”就是從輸入端口接收的要素。
每個輸入的要素都會作爲參數觸發一次函數的執行,執行後的要素會繼續作爲輸出要素。
在代碼模板中的函數例子是“processFeature(feature)”。在函數中獲取要素內容和設置屬性值需要用到2個函數:getAttribute()和setAttribute(),例子如下:

import fmeobjects

def processFeature(feature):
    str_name = feature.getAttribute('name')    # 參數name是輸入要素的屬性名,本行代碼也可在左側的FME Feature Attributes裏雙擊獲取
    feature.setAttribute('aliasname', str_name) # 第一個參數指定屬性名,第二個參數設置屬性值

2.2 方法(Class)

方法擁有3個函數:_init_(self)、input(self,feature)、close(self)
_init_(self))close(self) 不管是否有輸入要素,都會在運行期間的開頭和結束執行一遍,而input(self,feature) 則是介於二者之間。

與函數(Function)相同的是在方法(Class)裏面也需要通過getAttribute()和setAttribute()來獲取和設置屬性,不同的是在方法(Class)中,還需要一個額外的函數來使設置的屬性值生效——self.pyoutput(feature)。

搬運幫助文檔中的例子供大家參考,該例子將所有要素的面積求和後賦值給每個要素:

import fmeobjects
 
class FeatureProcessor(object):
    def __init__(self):
        self.featureList = []
        self.totalArea = 0.0
 
    def input(self,feature):
        self.featureList.append(feature)
        self.totalArea += feature.getGeometry().getArea()   # 這裏用到了getGeometry(),更多用法可以參考幫助文檔
 
    def close(self):
         for feature in self.featureList:
            feature.setAttribute("total_area", self.totalArea)  # 使用了setAttribute()來設置值
            self.pyoutput(feature)  # 還需要調用pyoutput(feature)來使設置值生效

2.3 輸出屬性設置

  • Attribute to Expose:選擇要暴露的屬性,例如在Python中創建的屬性
  • Attribute to Hide:選擇要隱藏的屬性,例如在Python中刪除的屬性
  • Attribute to Hide:選擇要隱藏的列表,例如在Python中創建的過程的列表

3 舉個栗子

介紹完如何在FME中調用Python後舉個我碰到的實際問題,這個問題剛剛好是個典型的FME和Python結合的例子,很好的使用了Python的優點彌補了FME的缺點。FME中的StringReplacer轉換器能夠使用正則表達式進行字符替換,但是替換的內容是固定的,沒有辦法生成序號,這個時候就用Python彌補這個功能。
首先說一下數據,數據是存在一個txt文本內部的,需要在裏面特定的字符串後進行順序編號,然後保存,效果如下:

  • 源文件
    log.txt
  • 效果文件
    result.txt
    先貼下工作流然後逐個介紹:
    workflow

3.1 讀取文本

添加txt讀模塊後設置一次讀取整個文件
reader setting

3.2 正則字符替換

使用StringReplacer轉換器進行關鍵詞替換:

  • 1.使用正則表達式替換
  • 2.設置正則表達式:(id:\d+,name:\w+,index:)
    使用括號將正則表達式包住是爲了在替換文本欄進行內容複用,使用"\1"即可複用第一個括號的內容,多個括號依次類推。
  • 3.在替換文本欄設置替換關鍵詞。“\1”表示複用正則表達式第一個括號內的內容,“序號”二字作爲補充的關鍵詞。
    stringreplacer setting
    本步驟運行後的效果如下:
    stringreplace result

3.3 使用PythonCaller

首先輸入processFeature作爲執行函數,然後在processFeature(feature)內使用如下代碼,思路是查找“序號”關鍵詞並逐一替換成順序號:

def processFeature(feature):
    text = feature.getAttribute('text_line_data')
    go = True
    index = 0
    while go:
        index = index + 1
        text = text.replace('序號', str(index), 1)
        if text.find('序號') == -1:
            go = False
            
    feature.setAttribute('text_line_data', text)

3.4 保存文本

最後添加txt寫模塊保存文本。
本實例已上傳,可免積分下載,下載鏈接:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章