常见的地理处理任务是将多个数据集合并到一个新的或现有的数据集中,以创建单个覆盖较大区域的数据集或包含大量记录的表。通常,合并或追加操作中使用的所有输入项的属性或字段都是相同的;但有时它们并不一致,因而必须对名称和类型不相同的字段之间的关系进行映射。有关字段映射的示例,请参阅“数据管理”工具箱中的合并工具;该工具可以使这种关系映射变得很容易,从而将数据放置到所需的输出字段中并使其具有正确的值。
FieldMap
FieldMap 对象提供一个字段定义和一个输入字段列表,该输入字段列表来自一组为该字段定义提供值的表或要素类。
FieldMap 对象的属性包括输入文本值的起始位置和结束位置,因此可以使用一组输入值创建输出值。如果 FieldMap 对象包含多个来自同一表或要素类的输入字段,则将使用 mergeRule 属性合并每个记录的值。这样可以方便地连接各个值,例如保存在一个字段中的街道名称以及保存在另一个字段中的街道类型,如 Eureka 和 Street。如果指定 mergeRule 值 Join,则将使用 FieldMap 的 joinDelimiter 属性。任何字符集(如空格)都可用作分隔符。在以上示例中,将会创建值 Eureka Street。
Fieldmappings
FieldMappings 对象是一组 FieldMap 对象,用作字段映射工具的参数值,例如合并。要处理这些对象,最简单的方法就是先创建 FieldMappings 对象,然后通过添加要组合的输入要素类或表对 FieldMap 对象进行初始化。提供了所有输入后,FieldMappings 对象将为所有输入中的每个唯一字段名提供一个 FieldMap 对象或输出字段。可对此列表进行修改,具体方法有添加新字段、更改输出字段的属性或内容,或移除任何不需要的输出字段。
示例
在以下示例中,将合并大量包含美国人口普查数据的要素类以形成一个新的要素类。在所有输入中找到的一个输入属性就是数值字段 STFID。这个包含 15 位数字的值是美国所有人口普查区块的唯一标识符。该值可分为四个部分。前两位数字表示州编码,接下来的三位数字表示县,紧随其后的六位数字标识人口普查区域,最后四位数字标识人口普查区块。值 360899912001006 表示包含纽约上州 (36) 纽约州立大学波茨坦分校在内的人口普查区块 (1006),该区块属于圣劳伦斯县 (089) 的人口普查区域 991200 。以下脚本示例将这些要素类合并到一起,并且还将创建两个新字段:TRACTID 和 BLOCKID,因为输入数据只有 STFID 属性。为此,请使用 addTable 方法来输入每项输入内容,从而对 FieldMappings 对象进行初始化。随后,修改默认的 FieldMappings 对象,方法是创建两个新的 FieldMap 对象、填充其属性,然后将其添加到 FieldMappings 对象。
import arcpy
arcpy.env.workspace = "C:/Data/CityBlocks.gdb"
outfc = "C:/Data/CityBlocks.gdb/AllBlocks"
# Each of the input Feature classes has an STFID, which is the
# combination of the Tract ID and Block ID for each block.
# Separate these values out from this field into two new
# fields, TRACTID and BLOCKID.
# Create a fieldmappings and two new fieldmaps.
fieldmappings = arcpy.FieldMappings()
fldmap_TRACTID = arcpy.FieldMap()
fldmap_BLOCKID = arcpy.FieldMap()
# List all the feature classes in the workspace that start with
# 'block' in their name and are of polygon feature type.
fcs = arcpy.ListFeatureClasses("block*", "Polygon")
# Create a value table that will hold the input feature classes to Merge
vTab = arcpy.ValueTable()
for fc in fcs:
# Adding a table is the fast way to load all the fields from the
# input into fieldmaps held by the fieldmappings object.
fieldmappings.addTable(fc)
# In this example also create two fieldmaps by 'chopping up'
# an input field. Feed the chopped field into the new fieldmaps.
fldmap_TRACTID.addInputField(fc, "STFID")
fldmap_BLOCKID.addInputField(fc, "STFID")
# Populate the input value table with feature classes
vTab.addRow(fc)
# Set the starting and ending position of the fields going into the
# TractID fieldmap. This is the location in the STFID field where the
# TractID falls.
for x in range(0, fldmap_TRACTID.inputFieldCount):
fldmap_TRACTID.setStartTextPosition(x, 5)
fldmap_TRACTID.setEndTextPosition(x, 10)
# Set the Name of the Field output from this field map.
fld_TRACTID = fldmap_TRACTID.outputField
fld_TRACTID.name = "TRACTID"
fldmap_TRACTID.outputField = fld_TRACTID
# Set the starting and ending position of the fields going into the
# BlockID fieldmap. This is the location in the STFID field where the
# blockID falls.
for x in range(0, fldmap_BLOCKID.inputFieldCount):
fldmap_BLOCKID.setStartTextPosition(x, 11)
fldmap_BLOCKID.setEndTextPosition(x, 16)
# Set the Name of the Field output from this field map.
fld_BLOCKID = fldmap_BLOCKID.outputField
fld_BLOCKID.name = "BLOCKID"
fldmap_BLOCKID.outputField = fld_BLOCKID
# Add the custom fieldmaps into the fieldmappings object.
fieldmappings.addFieldMap(fldmap_TRACTID)
fieldmappings.addFieldMap(fldmap_BLOCKID)
# Run the Merge tool.
arcpy.Merge_management(vTab, outfc, fieldmappings)
下一个示例显示的是,在创建 FieldMap 对象之后如何使用 FieldMappings 对象的 addTable 方法对其进行修改。这在输入中的字段具有不同的名称但逻辑上包含相同的值时非常重要。
import arcpy
outfc = "C:/data/CityData.gdb/AllBlocks"
# Want to merge these two feature classes together. Have a field
# that has the same content but the names are slightly different:
# Blocks1 has TRACT2000 and Blocks2 TRACTCODE. Name the output
# the same as Blocks1.
fc1 = "C:/data/CityData.gdb/Blocks1"
fc2 = "C:/data/CityData.gdb/Blocks2"
# Create a new fieldmappings and add the two input feature classes.
fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable(fc1)
fieldmappings.addTable(fc2)
# First get the TRACT2000 fieldmap. Then add the TRACTCODE field
# from Blocks2 as an input field. Then replace the fieldmap within
# the fieldmappings object.
fieldmap = fieldmappings.getFieldMap(fieldmappings.findFieldMapIndex("TRACT2000"))
fieldmap.addInputField(fc2, "TRACTCODE")
fieldmappings.replaceFieldMap(fieldmappings.findFieldMapIndex("TRACT2000"), fieldmap)
# Remove the TRACTCODE fieldmap.
fieldmappings.removeFieldMap(fieldmappings.findFieldMapIndex("TRACTCODE"))
# Create a value table that will hold the inputs for Merge.
vTab = arcpy.ValueTable()
vTab.addRow(fc1)
vTab.addRow(fc2)
# Run the Merge tool.
arcpy.Merge_management(vTab, outfc, fieldmappings)