Escribí un script de Python que hace una unión espacial y algunos cálculos simples. Mi problema es establecer la regla de fusión para un campo específico y dejar el resto de los campos como están. Por ejemplo, tengo un campo de población que, cuando se une por ubicación espacial, utiliza la regla de combinación "Primero", que toma el primer recuento de población. Quiero poder establecer la regla de fusión en "Suma" para sumar los valores de población entre todos los polígonos encontrados en la extensión espacial de otro polígono .
He realizado algunos ajustes intensos con mapas de campo y objetos de mapeo de campo, pero parece que no puedo hacer que funcione correctamente. Específicamente, he probado el método: popFieldMap.mergeRule = 'Sum' para establecer mergeRule, pero siempre vuelve a "Primero".
¿Alguna idea de cómo puedo cambiar mediante programación la regla de fusión para un campo en una Unión espacial?
¡Gracias!
Aquí está mi código (tenga en cuenta que es bastante específico para mis datos y contiene líneas para probar ciertas etapas del script):
import arcpy,sys,os
#Get the Files involved, set some variables.
SectorTable = sys.argv[1]
SectorShape = sys.argv[2]
MaxDev = sys.argv[3]
PopulationFC = sys.argv[4]
OutputFC = sys.argv[5]
DeviationField ="Angle_Deviation"
ID = "SectorID"
newID = "BP_ID"
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)[0]
#Check to see if ID field types and name match
try:
SectorShapeFields = arcpy.ListFields (SectorShape,ID)
SectorTableFields = arcpy.ListFields (SectorTable,ID)
arcpy.AddMessage("Finished Listing Fields")
nameCheck = SectorShapeFields[0].name == SectorTableFields[0].name
typeCheck = SectorShapeFields[0].type == SectorTableFields[0].type
except:
arcpy.AddMessage("Failed to List Fields")
#If they do not match, add new fields to correct.
if not nameCheck:
arcpy.AddMessage("Field Names do not match! Adding new field to circumvent...")
if not typeCheck:
arcpy.AddMessage("Field Types do not match! Adding new field to circumvent...")
if SectorShapeFields[0].type != SectorTableFields[0].type:
try:
arcpy.AddField_management(SectorShape, newID, SectorTableFields[0].type,10)
arcpy.CalculateField_management(SectorShape, newID,"!"+ID+"!", "PYTHON")
arcpy.RefreshTOC()
except:
arcpy.AddMessage("Error in Creating Field. Does it already exist?")
#Join the two together
arcpy.AddMessage("Performing Join")
arcpy.AddJoin_management( SectorShape, newID, SectorTable, ID)
arcpy.SelectLayerByAttribute_management (SectorShape,"NEW_SELECTION","Angle_Deviation>"+str(MaxDev))
df.zoomToSelectedFeatures()
#Field Mapping ...
myMap = arcpy.FieldMappings()
myMap.addTable(PopulationFC)
myMap.addTable(SectorShape)
#Verify the field merge rule for the pop10 field.
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))
popFieldMap.mergeRule = 'Sum'
arcpy.AddMessage(str(popFieldMap.mergeRule))
popFieldMap2 = popFieldMap
##Test
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))
#Perform Spatial Join
arcpy.AddMessage("Performing Spatial Join")
arcpy.SpatialJoin_analysis(SectorShape, PopulationFC, OutputFC,"JOIN_ONE_TO_ONE","",myMap,"INTERSECT")
#Add Result and Symbolize
arcpy.mapping.AddLayer(df,arcpy.mapping.Layer(OutputFC))
translayer = arcpy.mapping.ListLayers(mxd,"",df)[0]
translayer.transparency = 50
arcpy.RefreshActiveView()
EDITAR: ¡a continuación se muestra el código con la solución implementada!
import arcpy,sys,os
#Get the Files involved, set some variables.
SectorTable = sys.argv[1]
SectorShape = sys.argv[2]
MaxDev = sys.argv[3]
PopulationFC = sys.argv[4]
OutputFC = sys.argv[5]
DeviationField ="Angle_Deviation"
ID = "SectorID"
newID = "BP_ID"
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)[0]
#Check to see if ID field types and name match
try:
SectorShapeFields = arcpy.ListFields (SectorShape,ID)
SectorTableFields = arcpy.ListFields (SectorTable,ID)
arcpy.AddMessage("Finished Listing Fields")
nameCheck = SectorShapeFields[0].name == SectorTableFields[0].name
typeCheck = SectorShapeFields[0].type == SectorTableFields[0].type
except:
arcpy.AddMessage("Failed to List Fields")
#If they do not match, add new fields to correct.
if not nameCheck:
arcpy.AddMessage("Field Names do not match! Adding new field to circumvent...")
if not typeCheck:
arcpy.AddMessage("Field Types do not match! Adding new field to circumvent...")
if SectorShapeFields[0].type != SectorTableFields[0].type:
try:
arcpy.AddField_management(SectorShape, newID, SectorTableFields[0].type,10)
arcpy.CalculateField_management(SectorShape, newID,"!"+ID+"!", "PYTHON")
arcpy.RefreshTOC()
except:
arcpy.AddMessage("Error in Creating Field. Does it already exist?")
#Join the two together
arcpy.AddMessage("Performing Join")
arcpy.AddJoin_management( SectorShape, newID, SectorTable, ID)
arcpy.SelectLayerByAttribute_management (SectorShape,"NEW_SELECTION","Angle_Deviation>"+str(MaxDev))
df.zoomToSelectedFeatures()
#Field Mapping ...
myMap = arcpy.FieldMappings()
myMap.addTable(PopulationFC)
myMap.addTable(SectorShape)
#Verify the field merge rule for the pop10 field.
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))
popFieldMap.mergeRule = 'Sum'
arcpy.AddMessage(str(popFieldMap.mergeRule))
myMap.replaceFieldMap(fIndex,popFieldMap)
##Test
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))
#Perform Spatial Join
arcpy.AddMessage("Performing Spatial Join")
arcpy.SpatialJoin_analysis(SectorShape, PopulationFC, OutputFC,"JOIN_ONE_TO_ONE","",myMap,"INTERSECT")
#Add Result and Symbolize
arcpy.mapping.AddLayer(df,arcpy.mapping.Layer(OutputFC))
translayer = arcpy.mapping.ListLayers(mxd,"",df)[0]
translayer.transparency = 50
arcpy.RefreshActiveView()
fuente
population
campo?Respuestas:
Creo que debes usarlo
FieldMappings.replaceFieldMap
para que persista. Ejemplo del tema de ayuda Asignación de campos de entrada a campos de salida :Otro pensamiento es que cuando pruebo mapas de campo, me gusta usar una herramienta de secuencia de comandos y un comportamiento personalizado de la herramienta de secuencia de comandos para poder inspeccionar visualmente el mapa de campo en lugar de tratar de decodificar las cadenas largas y locas que producen.
Ejemplo de
ToolValidator
clase que solía concluir que sí,replaceFieldMap
es necesario para que se mantenga en el valor del parámetro:fuente