I'm scripting a spatial join in ArcGIS with Python. I only want the resultant feature class to have a single field containing one attribute from the join features. In general, many join features overlap a single target feature and I want to preserve the attributes from all of them. I'm joining one-to-one, with the 'join' merge rule and a comma delimiter.
The problem arises when the new field exceeds 50 characters (the default) and the spatial join fails. I need to update the field's 'length' attribute, but I can't - if I assign a new value to it, nothing changes.
Here's a snippet that generates the field mapping object that I'll pass to spatial join:
# Generate a field mappings object and add the two join layers
fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable(outPolys)
fieldmappings.addTable(overlapping_SAs)
# facID_str is the field that we want
# Set its merge rule to 'join' and add a comma delimiter
# Get all field names from the join features
fnames = arcpy.ListFields(overlapping_SAs)
for field in fnames:
if field.name == "facID_str":
fidx = fieldmappings.findFieldMapIndex(field.name)
fmap = fieldmappings.getFieldMap(fidx)
# Set the merge rule to sum and update the object
fmap.mergeRule = "join"
fmap.joinDelimiter = ","
fieldmappings.replaceFieldMap(fidx, fmap)
# Delete all other fields
else:
fidx = fieldmappings.findFieldMapIndex(field.name)
if fidx > 0:
fieldmappings.removeFieldMap(fidx)
I can see the field I want by calling fieldmappings.fields[1].length
but if I try to set the length to something other than 50, nothing happens. For example:
>>> fieldmappings.fields[1].length
50
>>> fieldmappings.fields[1].length = 500
>>> fieldmappings.fields[1].length
50
The eventual call to spatial join looks like this: arcpy.SpatialJoin_analysis(outPolys, overlapping_SAs, outJoin, "JOIN_ONE_TO_ONE", "KEEP_COMMON", fieldmappings, "WITHIN")
How do I set length to a value more appropriate for my application?
Answer
Looking at the help for fieldmappings
the property fields returns a read only list of field objects I guess this is why its not working. You need to access the length property of the field
object via the fieldmap
object. Below is the corrected code:
import arcpy
fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable("Catchment")
fieldmappings.addTable("Field Sites")
fnames = arcpy.ListFields("Field Sites")
for f in fnames:
if f.name == "SiteLabel":
print "DOING SITE LABEL!"
fidx = fieldmappings.findFieldMapIndex(f.name)
fmap = fieldmappings.getFieldMap(fidx)
fmap.mergeRule = "join"
fmap.joinDelimiter = ","
##### Here is how you change the field length of the output field
theField = fmap.outputField
theField.length = 1000
fmap.outputField = theField
#####
fieldmappings.replaceFieldMap(fidx,fmap)
else:
print "DROPPING " + f.name
fidx = fieldmappings.findFieldMapIndex(f.name)
if fidx > 0:
fieldmappings.removeFieldMap(fidx)
arcpy.SpatialJoin_analysis("Catchment", "Field Sites", "in_memory/xxx6", "JOIN_ONE_TO_ONE", "KEEP_COMMON", fieldmappings, "INTERSECT")
No comments:
Post a Comment