原文发布时间:2010-12-21
作者:OLIVER
翻译:乱马
续上一篇《Python与FME(一)》
4 使用pythoncaller
启动Workbench,加载points.shp的shape文件作为源数据,添加转换器PythonCaller到画布中。
有两种添加Python代码到PythonCaller转换器中:
1) 在FME集成的源代码编辑器中添加代码;
2) 引用一个外部文件中的Python脚本,例如myFactories.py。
需要更详细的内容,请参考文章 How can I Modularize My Python Code。
4.1 使用FME自带编辑器
连接源数据到PythonCaller上,点击转换器上的红色的属性设置按钮,对转换器的属性进行设置。然后点击[…]启动FME集成的代码编辑器。
输入以下代码:
# script 1
class MyPythonFactory(object):
def __init__(self):
pass
def input(self,feature):
self.pyoutput(feature)
def close(self):
pass
注意:请注意代码缩进风格! FME的源代码编辑器使用真正的Tab缩进制表位,而其他的Python IDE编辑器,例如IDLE,使用四个空格代替Tab缩进(默认方式)。在同一个段代码中混合风格是不允许的。当你从其他IDE中的代码复制到FME代码编辑器时,可能需要更换Tab或者空格以避免错误。
现在可以点击“确定”(OK)按钮关闭编辑器,返回PythonCaller参数设置对话框。
在“Edit PythonCaller Parameters”对话框中,你必须要引用你在代码中编写的Python类。
在Python symbol to use: 输入框中,输入类的名字:
MyPythonFactory
点击“确定”(OK)按钮关闭参PythonCaller数设置界面,然后连接该转换器到Visualizer上,最后运行Workbench,查看一下转换日志。如果一起运行正常,你会看到以下的信息:
(...)
FME API version of module 'PythonFactory' matches current internal version (3.6 20090807)
Loaded C:\Windows\system32\python26.DLL
Loading fmepython module: fmepython26 ...
Importing pyfme module...
Loading pyfme dll: D:\Program Files\FME\fmeobjects\python26\_pyfme.pyd ...
Loaded _pyfme library `D:\Program Files\FME\fmeobjects\python26\_pyfme.pyd'
_pyfme.dll version is 26
Initializing pyfme.dll...
pyfme initialized.
Adding directory `C:\Users\antu\AppData\Local\Temp' to the python path
(...)
目标数据集看起来没有变化,但是每个要素都被PythonCaller进行了处理,在后面你将看到他们发生了什么变化。
4.2 使用外部模块
如果你习惯了使用其他Python IDE编辑器,没有问题。它工作方式和刚才的很像。
把刚才的脚本输入在编辑器中,然后保存成myFactories.py。
# script 1
class MyPythonFactory(object):
def __init__(self):
pass
def input(self,feature):
self.pyoutput(feature)
def close(self):
pass
把这个myFactories.py复制到一个FME将会搜索的路径下。
FME会自动添加以下的目录到Python的搜索路径(sys.path):
$FME_HOME/python
all 'transformer' directories
$FME_MF_DIR, i.e. where the mapping file/workspace is saved
另外,你可以创建一个“Startup Python Script(Python启动脚本)”来更新sys.path,它是工作空间的高级设置。
启动Workbench,加载源数据,然后连接到转换器PythonCaller。在“Edit PythonCaller Parameters”对话框中,你要引用外部的脚本(模块)和你的MyPythonFactory类,如下显示:
myFactories.MyPythonFactory
注意:在FME 2007的PythonCaller,尽管你使用外部的模块,也需要有输入在内嵌的编辑器中。因此需要打开编辑器,输入:
Pass
这个问题在FME 2008及以后的版本得到了修正。
余下的设置和上面说的一样,把PythonCaller连接到一个输出,然后运行Workbench。
4.3 如何工作
类MyPythonFactory中由3个方法:
1)__init__
2)input
3)close
__init__是构造器。当一个类被调用或者一个对象被创建的时候,构造器自动被调用。这里,只有一个Pass声明在构造器中分配,而没有执行任何任务。
方法input带有两个参数:self和feature。Feature是pyfme.Feature中的实例。
方法close只有一个参数:self。
概括起来:
类MyPythonFactory从FME接受一个要素对象为输入。 现在__init__方法会自动调用。输入的要素由一个相对应的方法input处理。在处理完成后,使用一个pyoutput方法,要素返回到FME。如果现在是一个close方法,那这个过程就结束了。
4.4 提醒:使用函数而不是类
并不是在所有的情况下,你都需要__init__和close这些方法。为了简化,使用Python 函数也是足够的。
仅定义一个函数而不是类:
def myFunction(feature):
feature.{any method of pyfme.FMEFeature}
#feature.setAttribute('TITLE','Mr.') # example
调用函数的方式和调用类的方式相似。如果你喜欢使用FME内部的编辑器,Python symbol to use 中填写的就是函数名称,例如myFunction。如果你使用外部编辑器,你需要在外部编辑器中添加一个名称,例如myFoctories.myFunction。
注意:这段是2010年3月添加的补充内容。任何后面的解释都是基于使用类的详细的变量。
4.5 罗嗦一下:FME feature(FME 要素)
什么是FME要素?
根据 使用FME Object建立应用 中介绍,要素是FME的基础数据单位。“…一个要素,是由一组属性和带有坐标系的几何对象构成”。
只有属性的要素也是支持的,但是如果有几何对象,那么一个时点下只能有一个坐标系。
“当一个应用从数据集中读取数据,它接受数据是一次一个要素。当应用写到数据集,它发送数据是一次一个要素。”这个意味什么?
如果FME处理要素,在处理前是不知道这个要素的任何情况,要素是要下一步处理的。这意味着一次你只能访问一个要素,但是你不能得到全部数据集的任何信息,比如数据集的范围,总要素数量等。