Любая задача геообработки сводится в общем к тому, чтобы соединить много наборов данных в одном новом или уже существующем наборе данныхс целью получить один единственный набор данных, который охватывал бы более широкую область или таблицу, содержащую большее число записей. Зачастую, атрибуты или поля являются одинаковыми для всех входных данных, которые используются в операции слияния или присоединения; однако, бывают случаи, когда они не совпадают, что требует преобразования отношений между различного типа полями с разными именами (далее: сопоставление полей – прим. переводчика). Рассмотрим сопоставление полей на примере инструмента Слияние (Merge) в наборе инструментов Управление данными (Data Management). Он способствует преобразованию отношений между полями таким образом, что данные размещаются в нужные выходные поля с правильными значениями.
FieldMap
Объект FieldMap задаетопределение поля и список входных полей из набора таблиц или классов объектов, которые тоже имеют свои собственные значения.
Свойства объекта FieldMap включают начальное и конечное положения входного текстового значения, поэтому новое выходное значение можно создать с использованием лишь части входного значения. Если объект FieldMap содержит несколько входных полей из одной таблицы или класса объектов, то значения каждой записи объединяются с помощью свойства mergeRule. Этот способ удобен для объединения таких значений, как название улицы из одного поля и тип улицы из другого поля, например: Eureka и Street. Свойство joinDelimiter объекта FieldMap применяется, если для mergeRule задано значение Join. Любой набор символов, например, пробел, можно использовать в качестве разделителя. В приведенном выше примере, таким образом, будет создано значение Eureka Street.
Fieldmappings
Объект FieldMappings представляет собой набор объектов FieldMap и используется как значение параметра для инструментов, выполняющих сопоставление полей; к таким инструментам относится, в частности, инструмент Слияние (Merge). Проще всего с этими объектами работать следующим образом — сначала создать объект FieldMappings, а затем инициализировать его объекты FieldMap посредством добавления входных классов объектов или таблиц, которые необходимо с ним соединить. Когда будут заданы все входные данные, объект FieldMappings будет содержать один объект FieldMap или выходное поле для каждого уникального имени поля из всех входных данных. Этот список можно изменять, добавляя в него новые поля, изменяя свойства и/или содержимое выходного поля или удаляя из него ненужные выходные поля.
Примеры
В приведенном ниже примере несколько классов объектов, содержащих данные переписи США, будут объединены в новый класс объектов. Один из входных атрибутов, который имеется во всех входных данных, — числовое поле STFID. Это 15-значное значение служит уникальным идентификатором для всех переписных участков США. Это значение можно разбить на четыре компонента. Первые две цифры представляют код штата, следующие три — округ, следующие шесть — переписной район, а последние четыре — переписной участок. Значение 360899912001006 представляет переписной участок (1006), в который входит Государственный Университет штата Нью-Йорк в Потсдаме в северной части штата Нью-Йорк (36), в переписном районе 991200 округа Сент-Лоуренс (089). В данном примере эти классы объектов будут объединены вместе, а также будут созданы два новых поля – TRACTID и BLOCKID, поскольку входные данные имеют только атрибут STFID. С этой целью инициализируется объект FieldMappings с помощью метода addTable для ввода каждого элемента входных данных. Затем объект 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 после его создания с помощью метода addTable объекта FieldMappings. Это важно, когда входные данные имеют поля с разными именами, но логически содержат одинаковые значения.
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)