为什么这行不通?
@ value (SP) = FD ? @ value (PCT): 0
2018-04-05 22:58:55 8.1 0.0 warn attributemanager 19:tcl错误消息:2018-04-05 22:58:55 8.1 0.0 warn无效的裸词“fd”2018-04-05 22:58:55 8.1 0.0 warn in expression“fd=fd”?10.0:0“;2018-04-05 22:58:55 8.1 0.0 warn应为“$fd”或“fd”或“fd(…)”或……2018-04-05 22:58:55 8.1 0.0 warn attributeManager_19:未能评估表达式“fd=fd”?10.0:0英寸结果设置为空。
可能是许可问题,但不知道失败的是什么。我不断地得到这个错误。
2017-10-18 10:22:55在服务亚搏在线器ABC(## #.##.# .# .# .# .# .# .#)上的端口上检测到一个安全的许可证服务,并提供FME许可证。请确保fmelicensingassistant已配置为使用它(输入“ABC”或“ABC:##### #”作为服务器名),它有足够的许可证。
启动脚本是
lappend sysString $env(TEMP)/ TEMP .fme;lappend sysString{—RESOLVE_DOMAINS};lappend sysString {YES};lappend sysString {2>@1};eval exec $sysString;
任何想法吗?我正在积极地努力,希望能解决这个问题。
例1:翻译一结束就会产生FTP结果
在某些情况下,将翻译的结果通过FTP传输到某个地方是很有用的。
这是一个FME_END_TCL脚本(我已经用它附加了一个工作空间),它就是这样做的——注意它利用了DestDataset宏(作为输出的位置发布在工作空间中)来查找用于ftp目的的输出文件:
包需要ftp
放置[数组名fme_macrovalues];
将“上载$fm_macrovalues(destdataset)”set server“某物。anotherthing.com“set user”accountnamegoesher“set passwd”passwordgoesher“set conn[::ftp::open$server$user$passwd]将“step 2”::ftp::cd$conn outgoing/servicesputs“step 3”::ftp::list$conn*puts“step 4”::ftp::put$conn$fm_macrovalues(destdataset)::ftp::close$conn puts”上传完成”
当然,在生产中,您需要包装各种::ftp::..“catch”es中的内容,以便您可以适当地标记错误。
包需要httpput [http::geturl http://www.google.ca]展示了如何获取URL并使用它的内容(这里我只是将它打印出来,但是,如果在@tcl中调用它,它可以很容易地进入一个属性中。我非常喜欢这个想法,我们把它包装成一个新的变压器“URLFetcher”,这是4300型FME的一部分。本文附带了一个示例(如果您想以另一种方式在映射文件或Tcl脚本中使用该技术,下面将粘贴底层映射文件代码)。
tcl2 proc urlfetcher_fetch url \ package需要http;\ FME_SetAttribute _url_contents {};\ if[catch fme setattribute url contents \[http::data[设置令牌$url]]\ errormsg \]\ \catch http::cleanup$token\ if {No == {Yes}} {\ FME_LogMessage fme_error \"Error retrieve URL ' $ URL ' in transformer URLFETCHER: $errorMsg\";\}else \错误\“在transformer urlfetcher中检索url`$url'时出错:$errormsg\”;\}\}else \放入$token;\ catch {http::cleanup $token};\}
FACTORY_DEF * TeeFactory \ FACTORY_NAME URLFETCHER \ INPUT FEATURE_TYPE CREATOR_CREATED_1 \ OUTPUT FEATURE_TYPE URLFETCHER_OUTPUT \ @Tcl2(“URLFETCHER_fetch {@Value(URL)}”)
您可以在以下位置阅读有关在TCL内部使用HTTP的更多信息:http://wiki.tcl.tk/1303。注意-我确实发现了一个问题,我们将记录为一个已知的问题是,如果有一个错误检索URL,似乎FME进程本身将暂停退出。
{HKEY_LOCAL_MACHINE\SOFTWARE\ESRI\ArcInfo\Desktop\8.0}设置值[registry get $path {RealVersion}]返回$value}设置ArcGISVersion [getArcGISVersion]
和往常一样,可能性是无限的。我想如果你喜欢的话,你可以把FME变成一个网络服务器,那就去玩吧!
FME“开始”Tcl“设置GTTranslationStartTime[时钟格式[时钟秒]”FME“结束”Tcl“转换开始时间:$GTTranslationStartTime \转换结束时间:[时钟格式[时钟秒]”“
fme_end_tcl proc finally \全局fme_状态;\如果{$FME_Status == "1"} {\ put \"翻译成功\";\}else \ puts \“翻译不成功\”;\};\};同样的例子也可以不用程序编写:
fme_end_tcl if$fme_status==“1”\ puts\“翻译成功”\}else \ puts \“翻译不成功\”;\}
这个映射文件中用于设置目标# dataset目录的宏是DestDataset。在tcl脚本中的dwg_dataset“$(destdataset)”source,在翻译结束时运行。#脚本与此映射文件存储在同一目录中。fme_begin_tcl source$(fme_mf_dir_unix)/backup.tcl;备份$(DestDataset)
proc backup {filename}{如果{[file exists $filename]} {file copy -force $filename.bak}}
#源代码在tcl脚本中运行,以完成此翻译。#脚本与此映射文件存储在同一目录中。fme_end_tcl source$(fme_mf_dir_unix)/tryanother.tcl
set outputFile [open c:/temp/status.txt w+] if { $FME_Status == "1" } { puts $outputFile "Translation was successful" } else { puts $outputFile "Translation failed -- running alternate translation" exec fme.exe alternateTranslation.fme 2> NUL: } close $outputFile
FME_LogMessage fme_inform {hi dale inline}
从pyfm import*log=fmelogfile()log.log(“howdy”)。
FME_END_TCL设置outputFile[打开$FME_LogFileName a];\ put $outputFile {};\放$outputFile(在末尾写一些东西);\ put $outputFile {};\关闭$outputfile;
#设置一个映射文件ID,以便Tcl最终确定过程“知道”正在运行哪个映射文件,将“文件ID形状”映射到AutoCAD记录所有消息编号,以便我们以后只能提取我们感兴趣的那些。在翻译结束时运行的Tcl脚本中的LOG_MESSAGE_NUMBERS yes # Source。#脚本与此映射文件存储在同一目录中。$ (FME_MF_DIR_UNIX) / tclFinalization.tcl FME_END_TCL来源
#打开一个文件写的翻译数据集outputFile[打开c: / temp / stats_out.txt w +] #检查翻译状态和输出所需的消息如果{$ FME_Status = = " 1 "}{把$ outputFile“翻译是成功的”}其他{把$ outputFile“翻译失败”把美元outputFile“错误消息是:$ FME_FailureMessage "};在映射文件中使用MAPPING_FILE_ID设置唯一的映射文件标识符。Puts$outputfile“———————————————————————————————————————————————Puts$outputfile“Features read summary”Puts$outputfile“——————————————————————————————————————————————————————————————————————————————————————————————并输出每组formatSpec "%-65s: %12s" foreach featType [lsort [array names FME_FeaturesRead]] {put $outputFile [format $formatSpec $featType $FME_FeaturesRead($featType)]的# count;把美元outputFile”- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -“把美元outputFile”“把美元outputFile”- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -“把美元outputFile“功能写总结”把美元outputFile”- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -“#循环排序列出的功能类型,并输出每个feattype[lsort[数组名fme-featureswritten]输出$outputfile[格式$formatspec$feattype$fme-featureswritten($feattype)]输出$outputfile“”输出$outputfile”-------------------------------------------------------------------“输出$outputfile[格式$formatspec”到al features written“$fm_total features written”输入$outputfile[格式$formatspec”输入的总坐标“$fm_total coordinates]输入$outputfile”-------------------------------------------------------------------“输入$outputfile”在日志文件中查找任何警告行,并将它们的计数输出到# summary文件中。同时,检查是否有任何“意外的输入删除程序”统计行,并报告一个非零计数,如果有(当工作台生成的映射文件针对不同功能类型的输入数据集运行时,可能会发生这种情况),并找出系统状态日志消息(即246014)并复制在输出文件中设置日志文件存在[文件存在$fme_log文件名]设置警告0如果;$log文件存在;;$log文件存在;;设置日志文件[打开$fme_log文件名r]而;[获取$日志文件行]>=0;;如果;[regexp;警告;$行];;增加警告;elseif;[regexp;\123;; \\\;$Log文件存在;$log文件存在;$log文件;$log文件存在;$log文件存在------------------------------放入$outputfile$行放入$outputfile---放入$outputfile'elseif[regexp意外的输入移除器$line]set totalfeatures 0 set acceptedfeatures 0 set rejectedfeatures 0 set line[regsub ^.*意外的$line意外的D]catch scan$line“意外的输入删除程序(testforry):测试了%d个输入功能--%d个功能通过,%d个功能失败。“totalfeatures acceptedfeatures rejectedfeatures if$rejectedfeatures>0 puts$outputfile”----------------------------------------------------------------------------puts$outputfile[format$formatspec”具有意外功能类型的功能“$rejectedfeatures]puts$outputfile”-----------------------------————————————————“Puts$outputfile”“Close$logfile Puts$outputfile”——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————“—————————————————————————————————————————————————————————放入$outputfile”“并关闭文件——关闭$outputfile”
本例使用外部脚本使用TclODBC包将翻译活动的记录插入数据库。在这个例子中,创建一个Access数据库(如果必要的话),并为每个完成的翻译填充一行。
TclODBC
要在FME环境中使用TclODBC,遵循以下步骤:
$ (FME_MF_DIR_UNIX) / recordTranslationODBC.tcl FME_END_TCL来源
#==============================================================recordtranslationdbc.tcl此脚本记录使用tclodbc包执行翻译的过程。这个例子包括创建# Access数据库和存储翻译结果的表。每次翻译运行都有一行插入到表中。注意,对于实际生产系统,“put”语句#将被删除。包需要tclodbc #==================================================================如果数据库不在,请创建它。如果#数据库是基于服务器的,我们不会这样做,但在这个例子中,我们只是使用access。如果![文件存在$db file]放置“创建数据库$db file”数据库配置配置$driver[列表“创建”“创建”“$db file\”常规“]其他放置“使用现有数据库$db file”t此数据库的源,并连接到它首先始终删除DSN(如果它已经存在)。如果我们使用ODBC连接到“真正的”数据库,然后我们假设DSN已经是有效的catch database configure remove dsn$driver“dsn=$dsn”database configure add dsn$driver[list”dsn=$dsn“”dbq=$dbfile“]database db$dsn如果要插入的表,请创建它如果[llength[db tables xlation\u results]]==0将“creating xlation\u results table in database$dbfile”db“create table xlation\u results(mappingfileid varchar(50),就不存在了,开始时间时间戳,结束时间戳,CPUTIME双,成功的CHAR (3),numFeatures integer)“else_puts”xlation_results table present in database$dbfile“譁现在我们可以插入行,#提交,如果$fme_status==0 set success no db“插入到XLation_结果(mappingfileid,开始时间,EndTime,CPUTIME成功,numFeatures)值(“$fm_mappingfileid”,\ {ts的FME_StartingTimeStamp美元\},\ {ts的FME_EndingTimeStamp美元\},$fme_cputime,时间,'成功',FME_TotalFeaturesWritten美元)“db数据库断开# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = #如果你是连接到服务器的数据库,您可能不会在最后删除ODBC DSN。但由于我们是基于文件的#,我们将删除它数据库配置remove_dsn $驱动器"DSN=$ DSN "
本例使用外部脚本使用Oratcl包将翻译活动的记录插入Oracle数据库。
奥拉特尔
要在FME环境中使用Oratcl,遵循以下步骤:
$ (FME_MF_DIR_UNIX) / recordTranslationOracle.tcl FME_END_TCL来源
#==============================================================recordtranslationoracle.tcl此脚本使用oratcl包记录翻译的执行。此示例包括创建用于存储翻译结果的XLation结果表。每次翻译运行都有一行插入到表中。软件包需要oratcl譁譁譁譁譁譁譁譁譁譁======================确定要记录结果的XLation结果表是否存在set table exists no set statementhandle[oraopen$loginhandle]orasql$statementhandle“select*from user_tables where table name='xlation_results'”while[orafetch$statementhandle-datavariable row]==0{set tableexists是如果需要,请创建xlation_结果表if$tableexists=“否”orasql$statementhandle“创建表xlation_结果(mappingfileid varchar(50),开始时间时间戳,结束时间戳,CpuTime浮动,XLationSuccessful字符(3),numFeatures integer)“如果$fme_status==0 set success no orasql$statementhandle”insert into xlation_results(mappingfileid,开始时间,EndTime,CPUTIMEXlationSuccessful,NumFeatures)值(“FME_MappingFileId美元”,时间戳“$fm_startingTimestamp”,时间戳FME_EndingTimeStamp美元,$fme_cputime,时间,'成功',$FME_TotalFeaturesWritten)" -commit # ========================================================================= # Shut down the statement handle oraclose $statementHandle # ========================================================================= # Logout of our oracle service oralogoff $loginHandle
如果{$FME_Status == "1"} {exec shutdown /l /f} else {puts \n\t[concat ==>翻译失败。< = =]\ n}
导入操作系统
如果fme_status==true:os.system(“shutdown/l/f”),否则:print“\n\t==>翻译失败。< = = \ n”
在翻译之前和翻译之后控制FME的愿望已经讨论和争论了很多年。人们想在翻译开始前做不同的设置工作,以及在翻译结束后对日志文件或其他翻译构件的不同后处理。
最后这是可能的,以非常强大的方式处理前和后处理功能,提供在处理工作区之前和/或之后执行脚本的能力。脚本可以访问许多翻译工件(如counts,日志文件,等等)。
可能性是巨大的;一些示例应用程序包括:
启动脚本在映射文件完全解析之后执行,打开日志文件后,但在读者开始处理之前。关闭脚本在写入程序完成处理并关闭日志文件后执行(或者在翻译错误终止的情况下,清除后,日志文件关闭)。
启动和关闭脚本可以是tcl或python。
FME内置Tcl解释器,因此不需要进一步安装。
如果脚本包含过程定义,脚本必须调用它定义的过程,否则,将不会执行过程本身,也不会发生任何处理。
您可以在工作台中直接定义脚本导航窗格。Workbench甚至为编写脚本提供了一个特殊的编辑窗口。
以上: navigator窗格中的Tcl和Python脚本指令。
以上: Tcl end脚本指令设置对话框。单击突出显示的按钮打开脚本编辑器。
以上:脚本编辑器。
关闭python脚本可以利用导入FmeObjects。
对于TCL脚本,没有访问FMEObjects的权限,但是您可以通过“exec”命令(TCL)启动新的进程,这些新的过程可能涉及到FME对象TCL而没有任何冲突。
启动和关闭脚本是不在FDS(自定义格式)中有效。也有一些架构上的原因必须保持这种方式。
他们可以,当然,在映射文件或工作区中使用,该文件或工作区本身使用自定义格式。
可以在启动或关闭脚本中访问已发布的参数。
的fme_宏值数组/dictionary保存这些(按宏名索引,值是实际值)-所以在Tcl中,你可以通过这样的行来获得它们:
FME_END_TCL put[数组名FME_MacroValues];
FME_BEGIN_TCL把美元FME_MacroValues (DestDataset);
在Python中,你可以像访问其他字典一样访问它,例如,这样地:
对于name,fme_macrovalues.iteritems()中的val:logger.log(“%s:%s”%(name,val))。
所以,正如我祖父曾经说过的,我的许多发明,“这有什么好处?”嗯,爷爷,它有很多用途,这里有一些例子。
有关启动和关闭脚本中可用变量的完整列表,请参阅帮助:启动和关闭Python脚本和启动和关闭TCL脚本。
从启动到关闭传递设置
Tcl启动和关闭脚本共享一个Tcl解释器,这意味着启动脚本可以设置tcl全局变量,这些变量稍后将可用于关闭脚本。
然而,该解释器完全独立于FME中使用的任何其他Tcl解释器;所以,例如,不能将@TCL和@Tcl2 FME函数的设置传递给关机脚本。
if [catch {set outputFile [open c:/temp/logfile.log {RDWR CREAT EXCL}]}] { puts stderr "ERROR - cannot open the log file."} else { set gTranslationStartTime [clock format [clock seconds]] puts $outputFile "Translation started: $gTranslationStartTime close $outputFile}另一方面,为了有目的地停止翻译,即使脚本不会导致错误,然后你可以使用TCL的“错误”命令来迫使FME停止处理,例如:
如果{[file exists $outputFilename]}{错误"输出文件已经存在-选择一个不同的目标文件名。"Python版本是:
import-osif os.path.exists(output filename):引发异常(“输出文件已存在-请选择其他目标文件名。)
fme_end_tcl exec fme.exe anothertranslation.fmw 2>nul:
可以提供一组全面的Tcl示例在这里找到。
看到这个文章对于从ESRI XML工作区文档提取域和子类型的最新方法
本文适用于FME 2015及以上版本。如果您使用的是FME 2016或更新版本,请参阅本文的最新版本,加例子,在Geodatabase转换教程:
FME将读取和解析地理数据库编码域,有些用户可能希望实际提取域表本身,在地理数据库中存储为blob。
下面的工作区分两步完成:
第一步是使用startup tcl脚本生成命令行fme generate命令,该命令创建从geodatabase到空的临时映射文件。
第二步是使用文本行阅读器读取新的映射文件,将编码的域定义提取并解析到Excel电子表格中。
另一种方法是使用ArcCatalog导出带有数据库模式的ESRI XML工作区文档。然后可以从生成的XML中提取域和子类型代码。
在更现代的FME版本中,一个更简单的替代方法是使用FeatureReader转换器读取GDB模式。如果启用读取器参数Resolve域,域定义将以使用该域的任何属性的本机数据类型提供。
PyCharm 亚搏国际在线官网Community Edition是一个免费且易于使用的IDE,用于Python项目,可以设置它为FMEObjects提供自动完成功能。
下载并安装PyCharm Community editio亚搏国际在线官网nhttps://www.jetbrains.com/pycharm/download/
python fmeobjects项目不能使用fme的内部python,因此,您可能需要从www.python.org安装完整版本的python。您还可以使用Arcgis安装的python。
为FMEObjects配置:
导入FmeObjects
FME_SetAttribute trimmedAttribute [string trim [FME_GetAttribute originalAttribute]]用属性中的空格替换所有非数字字符:
FME_SetAttribute anAttribute [regsub -all {[^0-9]] [FME_GetAttribute anAttribute] [}]注意,在这种情况下,返回值是实际进行的替换的数量。
$} [FME_GetAttribute anAttribute]此正则表达式测试属性的整个值是否仅由字母字符组成。注意,当匹配正则表达式时,如果表达式匹配,返回值为1,和0。
这是我的消息操作特征属性的推荐方法是通过以下功能:
FME_GetAttribute attrName FME_SetAttribute attrName newVal FME_CopyAttribute destAttrName srcAttrName FME_RenameAttribute destAttrName srcAttrNameFME_UnsetAttributes attrName1 [attrName2 attrName3…]如果“Use FME_Attributes数组”参数选择“Yes”,然后访问一个名为FME_Attributes的数组,每个属性都可以用名称fme_attributes(attrname)来获取或设置。注意,这会显著降低执行时间。