4 votos

Arcpy agregar y calcular campos para entidades en una lista

Tengo un script en el que estoy trabajando y me está dando un error en tiempo de ejecución. Estoy intentando crear una lista de todos los shapefiles dentro de un directorio raíz, luego agregar un campo a cada shapefile y calcularlo con el nombre del shapefile. Puedo generar la lista (convertida de un diccionario) pero cuando intento agregar el campo me encuentro con el error.

def main():
    try:
        import arcpy, sys, traceback, os, glob
        arcpy.env.overwriteOutput = True
        masterFolder = r"Q:\\GIS\\Field_Data\\MT"
        outputFolder = r"C:\tmp\Shp_merged"

        #collect a list of subfolders in master folder
        subfolderLst = os.listdir(masterFolder)

        #declare a dictionary where a key will be shapefile name
        #... and value a list of pathes to shapefile with this name in all subfolders
        shpDict = {}

        #loop through all subfolders
        for subfolder in subfolderLst:
            #check current subfolder and make a list of pathes to each .shp file
            shpLst = glob.glob(os.path.join(masterFolder,subfolder,'*.shp'))

            #add each shapefile path to dictionary
            for shpPath in shpLst:
                shpName = os.path.basename(shpPath)

                if not shpName in shpDict:
                    shpDict[shpName] = []
                    shpDict[shpName].append(shpPath)

                else:
                    shpDict[shpName].append(shpPath)

        shpDict = shpDict.values()

        print shpDict
        for fc in shpDict:
          arcpy.AddField_management(fc, 'shpname','text')
          arcpy.CalculateField_management(fc, 'shpname', '"'+fc+'"'+ time.strftime('%m_%d_%y'))
    #arcpy.Merge_management(fcs, 'out.shp')

    except:
        print arcpy.GetMessages()
        # Get the traceback object  '"' + wildcard + '"'
        tb = sys.exc_info()[2]
        tbinfo = traceback.format_tb(tb)[0]

        # Concatenate information together concerning the error into a
        #   message string
        pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)

        # Return python error messages for use with a script tool
        arcpy.AddError(pymsg)

        # Print Python error messages for use in Python/PythonWin
        print pymsg

if __name__ == '__main__':
    main()

La lista generada se ve así:

[['Q:\\\\GIS\\\\Field_Data\\\\MT\\023N052E\\Points.shp', 'Q:\\\\GIS\\\\Field_Data\\\\MT\\023N053E\\Points.shp', 'Q:\\\\GIS\\\\Field_Data\\\\MT\\024N052E\\Points.shp']]]

y el error:

File "P:\Scripts\scratch\scratch.py", line 45, in main
    arcpy.AddField_management(fc, 'shpname','text')

: Object: Error in executing tool

Creo que tiene que ver con los cursores pero al ser novato no tengo idea de cómo resolver el problema

Gracias

10voto

Dustin Laine Puntos 213

Sospecho fuertemente que el problema está en usar un diccionario dentro del bucle for.

Si estoy leyendo tu código correctamente, quieres que 'shpname' haga referencia a un elemento en la lista shpDict. Cuando pasas estos como argumentos a la función AddField_management tal como está escrito, la computadora los interpreta como cadenas (literalmente pasando 'shpname' y 'texto' como argumentos), lo cual no tiene sentido para ArcGIS y arroja un error.

Puede funcionar mejor usar un valor de iteración en tu bucle (generalmente uso bucles while para este tipo de cosas) y luego hacer referencia al índice de la lista como una cadena en la función. Tal como:

while x < len(shpDict):
     arcpy.AddField_management(fc,str(shpDict(x),"TEXTO")
     x += 1

Como dije, así es como suelo hacer este tipo de cosas, puede haber una manera mejor. He tenido éxito con esta técnica - asegúrate de convertir el segundo argumento en una cadena usando la función str().

¡Espero que te ayude! Si alguien tiene una forma más eficiente de lograr esto, ¡me encantaría saber sobre ello!

8voto

Aissen Puntos 131

Personalmente, haría el AddField y CalculateField en cada featureclass mientras itero a través de ellas. También usaría la función ListFeatureClasses de arcpy:

def main():
    try:
        import arcpy, sys, traceback, os, glob
        arcpy.env.overwriteOutput = True
        masterFolder = r"Q:\GIS\Field_Data\MT"
        outputFolder = r"C:\tmp\Shp_merged"

        #colectar una lista de subcarpetas en la carpeta maestra
        arcpy.env.workspace = masterFolder
        arcpy.Listworkspaces('','Folder')

        for subfolder in subfolderLst:
            arcpy.env.workspace = subfolder
            fcLst = arcpy.ListFeatureClasses()
            for fc in fcLst:
                arcpy.AddField_management(fc, 'shpname','text')
                arcpy.CalculateField_management(fc, 'shpname', '"'+fc+'"'+ time.strftime('%m_%d_%y'))

    except:
        print arcpy.GetMessages()
        # Obtener el objeto de seguimiento
        tb = sys.exc_info()[2]
        tbinfo = traceback.format_tb(tb)[0]

        # Concatenar información sobre el error en un mensaje
        pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)

        # Devolver mensajes de error de Python
        arcpy.AddError(pymsg)

        # Imprimir mensajes de error de Python
        print pymsg

if __name__ == '__main__':
    main()

5voto

Aaron Puntos 25882

Parece que un error puede ser por un formato incorrecto, intenta reemplazar:

masterFolder = r"Q:\\GIS\\Field_Data\\MT"

con una de las tres formas correctas de formatear una ruta:

masterFolder = r"Q:\GIS\Field_Data\MT"

o:

masterFolder = "Q:\\GIS\\Field_Data\\MT"

o:

masterFolder = "Q:/GIS/Field_Data/MT"

4voto

Ben K. Puntos 323

Aquí está el código final. ¡Gracias a todos por la ayuda!

import arcpy

from arcpy import env import os import time def main(): try: import arcpy, sys, traceback, os, glob, shutil arcpy.env.overwriteOutput = True log = r'Q:\1-EMPLOYEE INBOX\David\downloads\logSurveyData.txt' masterFolder = r"Q:\GIS\Field_Data\MT" outputFolder = r"C:\tmp\Shp_merged" dst = r'Q:\GIS\Field_Data\z_archive\PMM'

    #shutil.copytree(masterFolder, dst + time.strftime('%m_%d_%y'))

    #collect a list of subfolders in master folder
    arcpy.env.workspace = masterFolder
    arcpy.ListWorkspaces('','Folder')
    subfolderLst = arcpy.ListWorkspaces('','Folder')
    print subfolderLst
    for subfolder in subfolderLst:
        arcpy.env.workspace = subfolder
        fcLst = arcpy.ListFeatureClasses()

        for fc in fcLst:
            #file = fc in fcLst
            filename = "'" + arcpy.env.workspace + os.sep + fc + "'"
            print filename
            arcpy.AddField_management(fc, 'shpname','text')
            arcpy.CalculateField_management(fc, 'shpname', filename, "PYTHON" )

except:
    print arcpy.GetMessages()
        # Get the traceback object '"' + wildcard + '"'
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]

    pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)

    arcpy.AddError(pymsg)

    print pymsg

    if __name__ == '__main__':
       main()

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:

X