将输入字段映射到输出字段
常见的地理处理任务是将多个数据集合并到一个新的或现有的数据集中,以创建单个覆盖较大区域的数据集或包含大量记录的表。通常,合并或追加操作中使用的所有输入项的属性或字段都是相同的;但有时它们并不一致,因而必须对名称和类型不相同的字段之间的关系进行映射。有关字段映射的示例,请参阅“数据管理”工具箱中的合并工具;该工具可以使这种关系映射变得很容易,从而将数据放置到所需的输出字段中并使其具有正确的值。
FieldMap 对象提供一个字段定义和一个输入字段列表,该输入字段列表来自一组为该字段定义提供值的表或要素类。
FieldMap 对象的属性包括输入文本值的起始位置和结束位置,因此可以使用一组输入值创建新的输出值。如果 FieldMap 对象包含多个来自同一表或要素类的输入字段,则将使用 mergeRule 属性合并每个记录的值。这样可以方便地连接各个值,例如保存在一个字段中的街道名称以及保存在另一个字段中的街道类型,如 Eureka 和 Street。如果将 mergeRule 的值指定为 Join,则使用 FieldMap 的 joinDelimiter 属性。任何字符集(如空格)都可用作分隔符。在以上示例中,将会创建值 Eureka Street。
属性 |
说明 |
---|---|
inputFieldCount |
所定义的输入字段的数量。 |
joinDelimiter |
字符串值,用于在输出字段类型为字符串而 mergeRule 的值为 Join 时分隔同一个表中的输入值。 |
mergeRule |
定义如何将同一输入表中的两个或多个字段值合并成单个输出值。可供选择的选项如下:
|
outputField |
输出字段的属性在字段对象中进行设置或返回。 |
方法 |
说明 |
---|---|
addInputField(table_dataset, field_name, {start_position}, {end_position}) |
通过指定名称来将字段添加到输入字段列表中,其中包括字段输入表或要素类的路径和字段名称,以及字段值的起始位置和结束位置(如果输入值来自文本字段)。 |
findInputFieldIndex(table_dataset, field_name) |
返回特定字段在输入字段的 FieldMap 列表中的索引位置。 |
getEndTextPosition(index) |
返回输入字段值中新输出值的结束位置。仅当输入字段类型是文本时,才会使用此属性。 |
getInputFieldName(index) |
返回特定输入字段的字段名。 |
getInputTableName(index) |
返回特定输入字段的表名。 |
getStartTextPosition(index) |
返回输入字段值中新输出值的开始位置。仅当输入字段类型是文本时,才会使用此属性。 |
removeAll() |
删除 FieldMap 输入字段列表的内容。 |
removeInputField(index) |
从输入字段的 FieldMap 列表中移除输入字段。 |
setEndTextPosition(index, end_position) |
定义一个值,该值指示用来定义新输出值的输入值中最后一个字符的位置。仅当输入字段类型是文本时,才会使用此属性。 |
setStartTextPosition(index, start_position) |
定义一个值,该值指示用来定义新输出值的输入值中第一个字符的位置。仅当输入字段类型是文本时,才会使用此属性。 |
FieldMappings 对象是一组 FieldMap 对象,它用作执行字段映射的工具的参数值,如 Merge。要处理这些对象,最简单的方法就是先创建 FieldMappings 对象,然后通过添加要组合的输入要素类或表对 FieldMap 对象进行初始化。提供了所有输入后,FieldMappings 对象将为所有输入中的每个唯一字段名提供一个 FieldMap 对象或输出字段。可对此列表进行修改,具体方法有添加新字段、更改输出字段的属性和/或内容,或移除任何不需要的输出字段。
属性 |
说明 |
---|---|
fieldCount |
输出字段的数目。 |
fieldValidationWorkspace |
工作空间类型定义属性字段的命名规则。确定输出字段名称时将使用这些规则,输出字段名称基于输入表或要素类中输入字段的名称。例如,包含 shapefile 的文件系统工作空间只能具有最长为 10 个字符的字段名。 |
字段 |
字段对象列表。每个字段对象分别表示一个输出字段的属性。 |
方法 |
说明 |
---|---|
addFieldMap(field_map) |
添加用于定义新输出字段的新 FieldMap 对象 |
addTable(table_dataset) |
指定其字段将用于定义输出字段的表或要素类 |
exportToString() |
将 FieldMappings 对象的内容保存为字符串值 |
findFieldMapIndex(field_map_name) |
使用输出字段的名称,返回该字段的 FieldMap 对象在用来定义输出字段的 FieldMap 对象列表中的位置 |
getFieldMap(index) |
使用 FieldMap 在输出字段列表中的索引位置,返回该列表中的 FieldMap 对象 |
loadFromString() |
使用 FieldMappings 对象的字符串定义填充 FieldMappings 对象的内容 |
removeAll() |
删除 FieldMap 列表的内容,以便不定义任何输出字段 |
removeFieldMap(index) |
移除用来定义输出字段的 FieldMap 对象列表中的输出字段 |
replaceFieldMap(index, value) |
使用新 FieldMap 对象替换用来定义输出字段的 FieldMap 对象列表中的现有输出字段 |
在以下示例中,将合并大量包含美国人口普查数据的要素类以形成一个新的要素类。在所有输入中找到的一个输入属性就是数值字段 STFID。这个包含 15 位数字的值是美国所有人口普查区块的唯一标识符。该值可分为四个部分。前两位数字表示州编码,接下来的三位数字表示县,紧随其后的六位数字标识人口普查区域,最后四位数字标识人口普查区块。值 360899912001006 表示包含纽约上州 (36) 纽约州立大学波茨坦分校在内的人口普查区块 (1006),该区块属于圣劳伦斯县 (089) 的人口普查区域 991200。以下脚本示例将这些要素类合并到一起,并且还将创建两个新字段:TRACTID 和 BLOCKID,因为输入数据只有 STFID 属性。为此,使用 addTable 方法对 FieldMappings 对象进行初始化,以输入各个输入项。随后,修改默认的 FieldMappings 对象,方法是创建两个新的 FieldMap 对象、填充其属性,然后将其添加到 FieldMappings 对象。
import arcpy from arcpy import env 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)