2 votos

Selección masiva por ObjectID usando arcpy

Al intentar actualizar en bloque clases de características versionadas que contienen más de 30.000 registros, se produce un problema debido a que el proceso Reconciliar/Contabilizar tarda demasiado y termina con un aviso que indica que la versión de destino ha cambiado y que el usuario debe Reconciliar y Contabilizar de nuevo (y todo el proceso se repite).

He intentado escribir un pequeño script que creará subconjuntos (que contienen unos 5000 registros) de mi selección original y ejecutará las funciones Calcular campo, Reconciliar y Contabilizar en cada subconjunto en lugar de en toda la selección.

Puedo obtener la lista de ObjectIDs de toda la selección original utilizando desc.FIDSet Sin embargo, toda la documentación indica que FIDSet es de sólo lectura. En la secuencia de comandos he generado una consulta de selección para utilizarla en la función SelectLayerByAttribute pero me gustaría saber si hay alguna forma de recrear simplemente el FIDSet (o un término alternativo si no es FIDSet) en lugar de pasar por la consulta Select.

¿O hay una forma mejor de conseguir lo que intento?

desc = arcpy.Describe(FeatureLayer) # Enables listing selected records by ObjectID through FIDSet

if desc.FIDSet != '': # Check if there are selected records
    FullSel = desc.FIDSet.split(";") # Create list of ObjectIDs of selected records
    print "Number of selected features: {}".format(len(desc.FIDSet.split(";")))

    while FullSel: # Keep going while there are still records to process
        SubsetSel = [] # Create SubsetSel list for groups of selected features
        for Sel in FullSel:
            if len(SubsetSel) < MaxLoopFeatures: # SubsetSel list will only have maximum number of features from MaxLoopFeatures
                SubsetSel.append(Sel) 

        ##======================================
        ## Is there a better way to do this??
        ##======================================
        query = 'OBJECTID IN (' + ','.join(map(str, SubsetSel)) + ')' # Create query for SelectlayerByAttribute to reselect features using SubsetSel
        ##print query
        arcpy.SelectLayerByAttribute_management(FeatureLayer, "NEW_SELECTION", query) # Reselect features
        ##======================================
        ##======================================

        desc2 = arcpy.Describe(FeatureLayer)
        print "Selection Set: {}".format(desc2.FIDSet)
        print "Number of selected features: {}".format(len(desc2.FIDSet.split(";")))

        # Run intended process here
        #arcpy.CalculateField_management()
        #arcpy.ReconcileVersion_management()

        FullSel = [x for x in FullSel if x not in SubsetSel] # Remove processed features from FullSel and repeat on remaining features
else:
    print "Nothing Selected"

2voto

FelixIP Puntos 4035

Tanto la selección por atributo como la calculadora de campos son muy lentas. Además, he descubierto que las expresiones de la calculadora no son fáciles de construir.

Por eso sugiero utilizar da.UpdateCursor con sql_clause para dividir el conjunto de datos en grupos y modificar los valores de los campos.

BTW FIDset cambia automáticamente, no es necesario volver a describir FeatureLayer cada vez

0voto

Gavin Schulz Puntos 592

Ayer encontré la respuesta a esta pregunta mientras buscaba otra cosa.

En El objeto Capa tiene dos métodos getSelectionSet() y setSelectionSet() .

getSelectionSet() es similar al Describe.FIDSet excepto que devuelve una Lista de ObjectIDs en lugar de la cadena de ObjectIDs de FIDSet.

setSelectionSet() pasará una lista de ObjectIDs a la capa para seleccionarlos. Funciona mucho más rápido que el método query = ... y arcpy.SelectLayerByAttribute_management código en mi pregunta anterior.

Si elimino Describe y FIDSet y los sustituyo por

lyr = arcpy.mapping.Layer(FeatureLayer)
FullSel = lyr.getSelectionSet()

if FullSel:

y sustituir la consulta y la selección por

lyr.setSelectionSet("NEW", SubsetSel)

mi prueba dura unos 24 segundos en lugar de casi 2 minutos.

lyr = arcpy.mapping.Layer(FeatureLayer) 
FullSel = lyr.getSelectionSet() # Enables listing selected records by ObjectID through SelectionSet

if FullSel: # Check if there are selected records
    print "Number of selected features: {}".format(len(FullSel))

    while FullSel: # Keep going while there are still records to process
        SubsetSel = [] # Create SubsetSel list for groups of selected features
        for Sel in FullSel:
            if len(SubsetSel) < MaxLoopFeatures: # SubsetSel list will only have maximum number of features from MaxLoopFeatures
                SubsetSel.append(Sel) 

        ##======================================
        ## Better way to do it!
        ##====================================== 

        lyr.setSelectionSet("NEW", SubsetSel)

        ##======================================
        ##======================================

        # Run intended process here
        #arcpy.CalculateField_management()
        #arcpy.ReconcileVersion_management()

        FullSel = [x for x in FullSel if x not in SubsetSel] # Remove processed features from FullSel and repeat on remaining features
else:
    print "Nothing Selected"

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