12 votos

"Asignación de campo" en ArcGIS 10 - ArcPy

Yo he escrito un Python script que hace una unión espacial y algunos cálculos sencillos. Mi problema es con la configuración de la regla de combinación para un campo específico, y dejando el resto de los campos tal y como es. Por ejemplo, tengo una esfera de la población y que cuando se unió por la ubicación espacial de los usos de la combinación de la regla de "Primero" que se agarra a la que ocurre por primera vez de un recuento de la Población. Quiero ser capaz de establecer la regla de combinación de "Suma" para sumar los valores de la población entre todos los polígonos se encuentran en la extensión espacial de otro polígono.

He hecho algunas intensa jugando con los mapas de campo y de asignación de campo de los objetos, pero parece que no puede conseguir que funcione correctamente. Específicamente he probado el método: popFieldMap.mergeRule = 'Suma' para establecer el mergeRule, pero siempre vuelve a la "Primera".

Alguna idea de cómo puedo cambiar mediante programación la regla de combinación para un campo en una unión Espacial?

Gracias!

Aquí está mi código (tenga en cuenta que es muy específico a mis datos y contiene las líneas de probar ciertas etapas de la secuencia de comandos):

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()

13voto

auramo Puntos 161

Creo que usted necesita para realmente usar FieldMappings.replaceFieldMap para llegar a persistir. Ejemplo de tema de ayuda de Mapeo de los campos de entrada para los campos de salida:

# 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)

Otro pensamiento es que cuando las pruebas de campo de los mapas, me gusta usar una herramienta de secuencia de comandos y secuencias de comandos personalizadas comportamiento de la herramienta para que yo pueda inspeccionar visualmente el mapa de campo en lugar de tratar de decodificar el loco de cadenas largas que producen.

Ejemplo ToolValidator de clase I se utiliza a la conclusión de que sí, replaceFieldMap es necesario para que se conserva en el valor de parámetro:

class ToolValidator:
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    import arcpy
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parmater
    has been changed."""
    if (not self.params[0].hasBeenValidated
    or not self.params[1].hasBeenValidated):
        targetFeatures = self.params[0].value
        joinFeatures = self.params[1].value
        fieldMappings = arcpy.FieldMappings()
        if targetFeatures:
            fieldMappings.addTable(targetFeatures)
            if joinFeatures:
                fieldMappings.addTable(joinFeatures)
                idx = fieldMappings.findFieldMapIndex("PRIORITY")
                fieldMap = fieldMappings.getFieldMap(idx)
                fieldMap.mergeRule = 'Sum'
                fieldMappings.replaceFieldMap(idx, fieldMap) # if this line is commented out, the merge rule reverts to 'First'
        self.params[3].value = fieldMappings.exportToString()
    return

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by: