6 votos

¿Cómo dividir una clase de características en rangos?

Tengo un shapefile que consta de unos 4000 polígonos. Los polígonos se han creado a partir de un buffer alrededor de un número similar de islas en algún lugar del archipiélago noruego. Debido a un error en la funcionalidad de disolver usando arcpy disolver falla. Estoy asumiendo que esto es porque arcpy.Gestión_de_disolución no puede manejar demasiadas características superpuestas.

Para tratar de evitarlo, tengo previsto dividir mi archivo inicial en diez archivos separados que constan de unas 400 características que se disuelven por separado. A continuación, estos diez archivos se fusionan y se realiza una disolución final.

¿Cómo puedo hacer esa selección? El arcpy.select_analysis permite una cláusula where. ¿Cómo puedo utilizarla para seleccionar las n primeras características, luego las características n+1 a n*2, luego las características n*2+1 a n*3, etc.?

Mi objetivo final es hacer una pequeña función de arcpy que pueda ser un arreglo preliminar para nosotros, simples mortales, que dependemos de la corrección de errores de ESRI.

6voto

skamradt Puntos 13049

Utilice el bucle y el valor de la variable como se muestra en la respuesta de Aragón con el campo FID (este es el campo de ID de objeto basado en cero para shapefiles) como el campo de selección como se muestra en la respuesta de L_Holcombe para generar la cláusula where, y todo debería estar bien. Para programar el número total de características, utilice la función Obtener el recuento y dividir por 10 asignado a la variable. También necesitará Hacer capa de características . Las líneas con el carácter "#" deben ajustarse a sus datos y eliminar el "#" cuando estén listas para ser ejecutadas.

#lyr = arcpy.MakeFeatureLayer_management(specify input file here)
#getcount = int(arcpy.GetCount_management(lyr).getOutput(0))
getcount = 4000     # just an example - remove line and use get count from above
numfiles = 10
numfeatures = getcount / numfiles

for i in range(0, getcount, numfeatures):
    select_features = specify output file here
    #dissolve_features = specify output file here
    j = i + numfeatures
    if i != 0:
        where_clause = '"FID" > ' + str(i) + ' AND "FID" <= ' + str(j)
    else:
        where_clause = '"FID" <= ' + str(j)
    print where_clause
    #arcpy.Select_analysis(lyr, select_features, where_clause)
    #arcpy.Dissolve_management(select_features, dissolve_features, {dissolve_field})

5voto

sebastiaan Puntos 2910

Terminé haciendo la función sugerida a continuación. En parte inspirado por las aportaciones de otros colaboradores en esta cuestión. El manejo de objetos es tosco y crea muchos archivos temporales.

Estoy seguro de que esta función podría mejorarse mucho. Si se pule adecuadamente podría ser una solución preliminar decente para el error de disolución de ESRI. Lo estoy convirtiendo en una wiki comunitaria.

# Import modules
import arcpy, os

def shape_dissolve(file_in, file_out,group_by):  
    count           =  0
    current_min     =  0
    current_max     =  group_by
    joinstring      =  []

    features_total    =  int(arcpy.GetCount_management(file_in).getOutput(0))

    while (current_max < (features_total+group_by)):

        resulting_file  = "%sbuffer_result_%s.shp" % (path_maps_basis,count)

        where_clause    = '"FID"> %s AND "FID" <= %s' %(current_min,current_max)

        arcpy.Select_analysis(file_in, resulting_file, where_clause)

        resulting_file_d = "%sbuffer_result_d_%s.shp" % (path_maps_basis,count)

        arcpy.Dissolve_management(resulting_file, resulting_file_d,"","","SINGLE_PART","")

        # delete temporary files
        arcpy.Delete_management(resulting_file)

        joinstring.append(resulting_file_d)

        current_min = group_by*count
        current_max = current_min + group_by

        count +=1

    resultbuffer = "%sresultbuffer.shp" % (path_maps_basis)

    arcpy.Merge_management(joinstring, resultbuffer,"")

    # delete temporary files
    for shapefile in joinstring:

        arcpy.Delete_management(shapefile)

    arcpy.Dissolve_management(resultbuffer, file_out,"","","SINGLE_PART","")

    # delete temporary files
    arcpy.Delete_management(resultbuffer)

#Calling the function with these sample values
group_by = 700
path_maps_basis     = "C:/"
multi_feature_file  = "%sbuffer_complex.shp"    % (path_maps_basis)
resulting_file      = "%sbuffer_dissolved.shp"  % (path_maps_basis)

shape_dissolve(multi_feature_file,resulting_file,group_by)

4voto

texai Puntos 178

Puedes utilizar la función enumarete en python.

myList = []

n = 99

for i, v in enumarete(myList):
    if i == n:
        print v 'first 100 item' #append your list
    if i > n and i < (n+2)*2:
        print v 

O puede utilizar este script de SO :

def split_list(alist, wanted_parts=1):
    length = len(alist)
    return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts] 
             for i in range(wanted_parts) ]

A = [0,1,2,3,4,5,6,7,8,9]

print split_list(A, wanted_parts=1)
print split_list(A, wanted_parts=2)
print split_list(A, wanted_parts=8)

Espero que te ayude...

3voto

MikeJ Puntos 6577

¿Quizás algo sencillo podría funcionar? Asumiendo que "gid" es una columna con enteros consecutivos:

arcpy.Select_analysis("in_features", "out_features", '"gid" < 400')
arcpy.Select_analysis("in_features", "out_features", '"gid" < 800 AND "gid" >= 400')

etc.

No he probado esto, pero debería funcionar.

Referencia de la expresión SQL de ArcGIS: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00s500000033000000

2voto

auramo Puntos 161

Puedes adaptar la metodología de partición utilizada en este script para tus propósitos: Portar el código de la avenida "Producción de sombras de edificios" a ArcGIS 10 . Una vez que lo tengas funcionando podrías incluso experimentar con el multiprocesamiento adaptando otras partes del script (su propósito era mejorar el rendimiento usando múltiples núcleos de CPU).

La función correspondiente:

def getOidRanges(inputFC, oidfield, count):
    oidranges = []
    if procfeaturelimit > 0:
        message("Partitioning row ID ranges ...")
        rows = arcpy.SearchCursor(inputFC, "", "", oidfield, "%s A" % oidfield)
        minoid = -1
        maxoid = -1
        for r, row in enumerate(rows):
            interval = r % procfeaturelimit
            if minoid < 0 and (interval == 0 or r == count - 1):
                minoid = row.getValue(oidfield)
            if maxoid < 0 and (interval == procfeaturelimit - 1 or r == count - 1):
                maxoid = row.getValue(oidfield)
            if minoid >= 0 and maxoid >= 0:
                oidranges.append([minoid, maxoid])
                minoid = -1
                maxoid = -1
        del row, rows
    return oidranges

Nota: procfeaturelimit es una variable global que especifica el número máximo de características que debe asignarse a cada "partición".

Que se utiliza así:

count = int(arcpy.GetCount_management(inputFC).getOutput(0))
# Get the appropriately delmited field name for the OID field
oidfielddelimited = arcpy.AddFieldDelimiters(inputFC, oidfield)
oidranges = getOidRanges(inputFC, oidfield, count)
for o, oidrange in enumerate(oidranges):
    # Build a where clause for the given OID range
    whereclause = "%s >= %d AND %s <= %d" % (oidfielddelimited, oidrange[0], oidfielddelimited, oidrange[1])
    # Do your Select_analysis and whatever else here with the given whereclause

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