4 votos

La forma más rápida de numerar los polígonos que se cruzan en ArcGIS

Necesito numerar miles de polígonos en grupos, para que cada grupo tenga un número único. Cada polígono que se cruza es un grupo único (ver imagen).

Así que los polígonos tienen "grupos" de campos con valores:

Los polígonos 1,2,3 son el grupo 1;

Los polígonos 4,5 son el grupo 2;

los polígonos 6,7,8,9 son el grupo 3 y así sucesivamente...

enter image description here

Mi enfoque actual es muy lento, tarda unos 5 minutos en enumerar capas con unos 10 000 polígonos (son 4 100 grupos).

¿Hay alguna forma más rápida de hacerlo?

Esto es lo que hago:

  1. Disolver todos los polígonos - esa es mi manera de encontrar grupos (arcpy.Dissolve_management)
  2. Dar números únicos a cada polígono en la capa disuelta (arcpy.CalculateField_management)
  3. Iterar cada característica en la capa disuelta (arcpy.SelectLayerByAttribute_management)
  4. Seleccione los polígonos que se cruzan con la capa original (no disuelta).
  5. Darles número de grupo (arcpy.CalculateField_management)

Aquí está una parte del código:

#1
arcpy.Dissolve_management(fc, dissolve_shp, "", "", "SINGLE_PART")

#2
arcpy.CalculateField_management(dissolve_shp, "ID", '!FID!+1', "PYTHON")

#3
number_of_rows = arcpy.GetCount_management(dissolve_shp)
number_of_rows = int(number_of_rows.getOutput(0))
lyr_dissolve = r"in_memory\Temporary_layer_DISSOLVE_DEL"
lyr_merge = r"in_memory\Temporary_layer_MERGE_DEL"    
arcpy.MakeFeatureLayer_management(dissolve_shp, lyr_dissolve)
arcpy.MakeFeatureLayer_management(fc, lyr_merge)

for i in range(number_of_rows):
    i2=i+1
    if float(i2)//100 == float(i2)/100:
        print i2, "of", number_of_rows

    arcpy.SelectLayerByAttribute_management (lyr_dissolve, "NEW_SELECTION", '"ID" = '+str(i2))

    #4
    arcpy.SelectLayerByLocation_management (lyr_merge, "INTERSECT", lyr_dissolve)

    #5
    arcpy.CalculateField_management(lyr_merge, "TERM_P_NUM", i2, "PYTHON")

5 votos

Viendo que los grupos son los individuales disueltos por qué no Intersectar (o unión) ellos, que obtiene el GroupID en los polígonos ... añadiendo un campo (OrigID) y la copia de los valores FID antes de la unión significará que usted puede encontrar el original (fuente) polígono para el área de intersección. A continuación, iterar los polígonos con un UpdateCursor utilizando whereclause GroupID = 1..n para enumerar cada polígono en el grupo.

1 votos

@MichaelMiles-Stimson No he hecho una prueba para confirmarlo, pero creo que la superposición de polígonos debería permitir al solicitante prescindir del cursor de ArcPy y de los miles de Selecciones de capas por lugares, para reducir el tiempo a unos 10-15 segundos en total. Te deben una. No creo que pidan hacer esa última enumeración que mencionas.

0 votos

¿Puede acceder a Vecinos del polígono en Análisis>Caja de herramientas de proximidad?

2voto

Tedy Puntos 46

Una forma más rápida de lograr esto es con una unión espacial para el paso 3, una vez que sus polígonos tienen su número único. Digamos que UID es el nombre del campo para su ID único de sus polígonos de disolución, Dissolve es su disolución de polígonos, Polies es su polígono de destino, y outFC será la ruta completa de su clase de característica resultante.

A continuación, me pongo un poco elegante con los mapas de campo para limitar los campos devueltos. Tenga en cuenta que no he probado el script.

#Create field mappings object
fms = arcpy.FieldMappings()
#Add fields from target
fms.addTable (Polies)

#Add UID field from dissolve
uidFm = arcpy.FieldMap ()
uidFm.addInputField (Dissolve, UID)
fms.addFieldMap (uidFm)

#Spatial join
arcpy.SpatialJoin_analysis (Polies, Dissolve, outFC, field_mapping = fms)

0 votos

+1 Un buen enfoque. Me encantaría ver un punto de referencia para ver cómo este método se compara con el de la OP;)

1voto

August Karlstrom Puntos 445

Este es otro enfoque mediante el uso de Análisis_de_vecinos_del_polígono que se introdujo en ArcGIS 10.1.

# fc                : Feature class to-be-processed
# ID_field          : Unique ID field in the feature class on which groupping will be based
# neighbour_table   : Table location where the Polygon Neighbor results will be saved,
#                     preferrably a GDB location (considering field naming limitation of dbf)
arcpy.PolygonNeighbors_analysis(fc,neighbour_table,ID_field,"NO_AREA_OVERLAP","BOTH_SIDES","#","METERS","SQUARE_METERS")
group_ID=0
pairs=[]
for row in arcpy.SearchCursor(neighbour_table):
    pairs.append([row.getValue('src_'+ID_field),row.getValue('nbr_'+ID_field)])

pairs=sorted(pairs)
group_dict={group_ID:set(pairs[0])}
for pair in pairs[1:]:
    scr,nbr=pair
    processed=False
    for k in group_dict.keys():
        if not processed:
            if scr in group_dict[k] or nbr in group_dict[k]:
                group_dict[k]=group_dict[k].union([scr,nbr])
                processed=True
        else:
            break
    if not processed:
        group_ID+=1
        group_dict[group_ID]=set([scr,nbr])

group_dict_invert=dict((val,k) for k in group_dict.keys() for val in group_dict[k])
groupping_field="Group_ID"
arcpy.AddField_management(fc,groupping_field,"Long")
up_cur=arcpy.UpdateCursor(fc)
for row in up_cur:
    ID=row.getValue(ID_field)
    if ID in group_dict_invert.keys():
        row.setValue(groupping_field,group_dict_invert[ID])
    else:
        group_ID+=1
        row.setValue(groupping_field,group_ID)
    up_cur.updateRow(row)

del row,up_cur

enter image description here

0 votos

+1 Verás mejoras en la velocidad si utilizas el da cursores. Sería interesante ver una prueba de referencia utilizando este método frente al del OP;)

1 votos

Polygon Neighbors no necesita Advanced - por lo menos para las últimas versiones Basic es suficiente y creo que desde que la herramienta se introdujo en alrededor de 10.1.

1 votos

He editado rápidamente una captura de pantalla (del enlace que has proporcionado) en tu respuesta para ilustrar que tiene licencia a todos los niveles.

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