文章目錄
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”參數中指定函數名或方法名來確定使用哪個函數或方法來處理要素。
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文本內部的,需要在裏面特定的字符串後進行順序編號,然後保存,效果如下:
- 源文件
- 效果文件
先貼下工作流然後逐個介紹:
3.1 讀取文本
添加txt讀模塊後設置一次讀取整個文件
3.2 正則字符替換
使用StringReplacer轉換器進行關鍵詞替換:
- 1.使用正則表達式替換
- 2.設置正則表達式:(id:\d+,name:\w+,index:)
使用括號將正則表達式包住是爲了在替換文本欄進行內容複用,使用"\1"即可複用第一個括號的內容,多個括號依次類推。 - 3.在替換文本欄設置替換關鍵詞。“\1”表示複用正則表達式第一個括號內的內容,“序號”二字作爲補充的關鍵詞。
本步驟運行後的效果如下:
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寫模塊保存文本。
本實例已上傳,可免積分下載,下載鏈接: