ModelBuilder 是 ArcGIS for Desktop 产品中最可爱的功能之一,它可以尽可能免代码地将我们从重复劳动中解放出来。使用 ModelBuilder 的过程常常被比喻为“搭积木”,我们只需要拿着 ArcGIS for Desktop 中为我们提供的“积木”去搭建满足于自己的特定工作流模型。

再打个比方,我们要实现的某个功能比作是自己做面包。首先要准备食材,例如面粉、牛奶、鸡蛋、黄油、糖、盐、酵母,类比为 地理数据; 食材齐备了,就可以顺序开始和面、发酵、烘焙,这些工作由特定的器具承担,例如各种烘焙工具、烤箱,就好比ArcGIS提供的 工具,例如 ArcToolbox中的工具们; 面包制作过程中可以根据自己口味,规定发酵时间、控制糖和盐的多少等,这就类比为工具的自定义 参数

如果自己享受整个烘焙的过程,不厌其烦地面面俱到,那大可维持现状;可是如果你觉得做面包是个体力活,你只是想吃到自家面包,而希望把做面包的过程“外包”出去,那么面包机的市场就来了。这篇blog就和大家说说如何制作“面包机”。


1 明确需求

我们从一个简单常见的实例开始……

需求:现有一些表示各种研究对象的地理数据,小明希望把所有研究数据变换到需要的坐标系统,并且全部裁剪至研究范围。

如果只有一份数据,小明会不假思索的找到 ArcToolbox中的 Project和Clip工具,顺序执行即可解决问题;如果是3+份数据,小明可能会想,该做个工具了。


2 构建工作流

从【地理处理】菜单,打开 ModelBuilder 窗口,依次拖拽和连接 Project 和 Clip 两个工具。Project 工具的输出作为 Clip 工具的输入。

双击工具可以打开工具继续填补工具需要的参数,直至Model因参数完全而变成彩色。


3 使用迭代器

前一步的工具已经满足一次任务的需要了,接着就是解决批量处理的问题。ModelBuilder提供了一些额外的自带工具来满足我们的一些高级需求,其中一类就是 迭代器,它用来实现循环。

在这个例子中,需要遍历的对象是表示各种研究对象的要素类,因此选择 迭代要素类 / Iterate Feature Classes。当然也可以根据自己的实际需求选择其他迭代器。

接下来就是把迭代器与工具串联起来。首先,双击迭代器的六边形为迭代器设置工作空间,即地理数据库/GDB,或者文件夹目录(例如shapefile所在的目录)。这样,迭代器会在指定的工作空间遍历要素类。删除现有Project工具的输入数据,将迭代器的输出数据连接到Project工具。

工具基本准备完毕,但是还差了重要的一步。目前,最后的输出数据是常量,也就是说,即使前面的工具执行了N次,那结果都将被同名覆盖。那么,行内变量 就显出用武之地了。

迭代器每次遍历到一个要素类,会返回一个 Name,内容是当前要素类的名称,这个Name就是行内变量。引用的方法就是使用百分号括起来,即 %Name%

输出数据设置示例:

至此我们就完成了一次批量任务。


4 复用工具

如果我们以后想按照这个相同的需求处理数据,完全可以将其做成模型工具。将输入数据和输出数据设置为模型变量,我们就可以在“运行”状态下使用。

设置方法,在需要作为参数方便后续修改的项目上右键,勾选 “模型参数”即可,然后项目的头上顶了个“P”,( ̄▽ ̄)”。

将模型保存至工具箱后,双击运行工具。现在就可以把它当成“面包机”,放入食材,等面包即可。


5 注意事项

下面是些有用的提示,FYI:

  • 每个模型仅可使用唯一一个迭代器。如果模型中已经存在一个迭代器,那么用于添加迭代器的菜单就不可用了。这是限制之一。

  • 如果将含有迭代器的模型导出为 Python 脚本,则导出的脚本中将不会包括迭代逻辑。这是限制之二。Python中有list函数,也可以实现类似的需求,但是需要重写。

  • 尽管Model可以嵌套调用,但是迭代器的嵌套循环逻辑不佳,不建议使用。如果需要实现嵌套循环,强烈建议使用python脚本。例如,实现遍历工作空间内每个要素类中的每个要素(记录)这样的需求,可以使用 ArcPy中的函数 ListFeatureClassesSearchCursor来实现。