FME做爲轉換神器,支持幾百種格式的互轉,實現互操做化。從fme.exe執行方式入手,討論Command命令式執行模板(.fmw/.fmwt)和腳本(.tcl/.py)實現自動化批量轉換。node
一、fme.exe命令分析ide
通常打開CMD命令後直接輸入fme可執行,系統環境變量已將FME按照目錄加進去了。ui
圖1 fme.exe命令this
從紅圈看出FME自己執行也是靠fme.exe來執行ControlFile(控制文件)和ScriptFile(腳本文件)的。對於ControlFile能夠利用FMEWorkBench來製做,對於ScriptFile有2種方式:FMEWorkBench和FMEQuickTranslator【這裏是FME2014】來建立。spa
注:其餘命令和參數設置這裏不作詳述。日誌
二、批量自動化轉換code
(1)ScriptFile方式,.tcl控制內容,.bat執行orm
此處可在【FME Desktop Help】中 FME Workbench > Workspace Basics > Running and Debugging Workspaces > Running a Batch Translation找到相關內容。blog
FMEWorkBench在製做完.FMW後,可在File—BatchDeploy嚮導式部署導出BAT和TCL腳本,數據源選擇可使用增長數據源目錄或多個文件。ip
圖2 batch數據源設置
FMEQuickTranslator能夠用Tools—CreateBatch來建立,數據源設置目錄或文件與圖2相同,設置原始數據格式和原始數據格式,再設置Batch導出。
圖3 FMEQuickTranslator批量腳本
生成後.bat文件就一行,fme開頭執行.tcl文件。
.tcl文件存儲了基本的設置:工做空間、原始數據及格式、目標數據及格式,日誌,相關轉換等參數,可用記事本打開查看和隨時改動,腳本方式執行.bat文件便可完成批量自動化轉換。
(2)ControlFile方式,Process程序執行【fme.exe ControlFile PublishParams】
此處可在【FME Desktop Help】中 FME Workbench > Workspace Basics > Running and Debugging Workspaces > Working with Command Files找到相關內容。
執行方式以下:
Fme.exe [.fmw/.fmwt文件] [對應發佈參數] Eg: fme.exe c:\temp\command.fmw --SourceDataset_ACAD "\"\"C:\FMEData\Data\Water\distribution_L25.dwg\" \"C:\FME Data\Data\Water\distribution_L26.dwg\"\"" --DestDataset_DGNV8 c:\temp\output.dgn LOG_FILENAME c:\fme.log |
能夠看到關鍵在於發佈參數的動態設置,一個完整的工做空間中有那麼幾個須要自定義的參數須要設置,UserParameter設置對應PromptAndRunTranslation(提示並運行轉換)相關參數是對應的,並且用戶發佈參數決定着整個工做空間運行的狀況。
圖4 用戶發佈參數與轉換參數對應
程序執行批量自動化轉換:一是提取FME核心和註冊表相關來進行命令組合,相似於打開CMD後輸入命令,不過是程序實現;二是自動提取FME用戶發佈參數,這個是核心,須要從.fmw中提取。
這裏仔細描述下用戶發佈參數提取方式,因爲是從.fmw文件中提取的,記事本或寫字板打開一個.fmw文件,搜索「DEFAULT_MACRO」,咱們就能夠找到用戶發佈參數顯示的地方,以下例爲1個【DestDataset_GEODATABASE_FILE】發佈參數,後面加地址,GUI指出文件類型,而此「DEFAULT_MACRO」和「GUI」組成一個發佈參數。
DEFAULT_MACRO DestDataset_GEODATABASE_FILE E:\KSDE\test.gdb GUI DEST_GEODATABASE DestDataset_GEODATABASE_FILE Destination ESRI Geodatabase (File-based) File: |
那麼如何利用程序從.fmw中提取出這些發佈參數?
分析:.fmw文件中針對「DEFAULT_MACRO」和「GUI」組合的內容有不少,只有前部分是用戶發佈參數,後部分是工做空間數據源、目標數據、轉換器等的相關參數,區分標識在於標籤:#! START_HEADER、#! END_HEADER,在此標籤(當作XML標籤)之間又有:
#! START_WB_HEADER、#! END_WB_HEADER;
#! START_SOURCE_HEADER、#! END_SOURCE_HEADER;
#! START_DEST_HEADER、#! END_DEST_HEADER;
利用XML形式表達層次爲:
1 < START_HEADER> 2 < START_SOURCE_HEADER> 3 <START_WB_HEADER><END_WB_HEADER> 4 < END_SOURCE_HEADER> 5 < START_DEST_HEADER> 6 <START_WB_HEADER><END_WB_HEADER> 7 < END_DEST_HEADER> 8 < END_HEADER>
由此可經過標籤過濾獲得用戶發佈參數,再經過「GUI」識別類型,經過換行符「\」和分隔符「 」進行分割獲得每一個發佈參數,最後程序實現讀取發佈參數。所以,可實現讀取和存入數據,動態的執行.fmw,達到批量自動化數據轉換。
給出發佈參數讀取方法供參考,過程源於【參考1】:
1)、經過標籤進行過濾獲得《用戶發佈參數》範圍。
1 public List<FMEParameter> GetParameters(string fmeFile) 2 { 3 List<FMEParameter> list = new List<FMEParameter>(); 4 XmlDocument document = null; 5 string str = null; 6 char[] trimChars = new char[] { '#', '!', ' ' }; 7 using (StreamReader reader = new StreamReader(fmeFile, Encoding.Default)) 8 { 9 StringBuilder builder = new StringBuilder(); 10 while (!reader.EndOfStream) 11 { 12 str = reader.ReadLine().Trim(); 13 if (str.StartsWith(Resource.StringFMWXmlPrefix)) 14 { 15 if (str == Resource.StringFMWXmlPrefix) 16 { 17 break; 18 } 19 builder.Append(string.Format("{0} ", str.TrimStart(trimChars))); 20 } 21 } 22 document = new XmlDocument(); 23 try 24 { 25 document.LoadXml(builder.ToString()); 26 } 27 catch (Exception) 28 { 29 document = null; 30 } 31 } 32 if (document != null) 33 { 34 foreach (XmlNode node2 in document.SelectSingleNode(Resource.StringFMWParameterPath)) 35 { 36 FMEParameter item = this.GetParameter(node2); 37 if (string.IsNullOrEmpty(item.Name)) 38 { 39 Trace.WriteLine(node2.Attributes[Resource.StringFMWParameterDefaultValue].Value); 40 } 41 else 42 { 43 list.Add(item); 44 } 45 } 46 } 47 return list; 48 }
2)、《用戶發佈參數》範圍解析,獲得FME發佈參數
1 private FMEParameter GetParameter(XmlNode node) 2 { 3 FMEParameter parameter = new FMEParameter { 4 DefaultValue = node.Attributes[Resource.StringFMWParameterDefaultValue].Value 5 }; 6 string input = node.Attributes[Resource.StringFMWParameterInfo].Value; 7 parameter.Optional = Regex.IsMatch(input, @"GUI\s+OPTIONAL\s+", RegexOptions.IgnoreCase); 8 parameter.Published = !Regex.IsMatch(input, @"GUI\s+OPTIONAL\s+IGNORE\s+|GUI\s+IGNORE\s+", RegexOptions.IgnoreCase); 9 input = Regex.Split(input, @"GUI\s+OPTIONAL\s+IGNORE\s+(.+)|GUI\s+IGNORE\s+(.+)|GUI\s+OPTIONAL\s+(.+)|GUI\s+(.+)", RegexOptions.IgnoreCase)[1]; 10 string[] strArray = Regex.Split(input, @"([^\s]+)\s+([^\s]+)\s+(.+)", RegexOptions.IgnoreCase); 11 parameter.Type = strArray[1]; 12 parameter.Name = strArray[2]; 13 if (this.hasConfiguration(parameter.Type)) 14 { 15 strArray = this.SplitConfigurationPrompt(strArray[3]); 16 parameter.Configuration = strArray[0]; 17 parameter.Label = strArray[1]; 18 return parameter; 19 } 20 parameter.Label = strArray[3]; 21 parameter.Configuration = string.Empty; 22 return parameter; 23 }
總結:經過fme.exe命令執行方式探討了2種批量自動化數據轉換方法,詳細論述了具體實現過程和關鍵技術點,提供相關參考。
另:有【自定義FME批處理腳本,安圖博客 】,經過DOS命令,自定義設置FME模板、數據源路經、目標數據路徑、以及日誌等信息,基本也屬於命令執行範疇。
【引用已說明出處,轉載請說明出處。】
參考:
[1] FME 開發篇(二) .安圖163博客,2014.5