¿Obteniendo la extensión de cada polígono en shapefile usando ArcPy?


20

En ArcGIS 10 y Python, quiero obtener la información de extensión (xmax, ymax, xmin, ymin) de cada uno de los polígonos en un shapefile.

Puedo obtener la extensión de todo el archivo de forma usando

file=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
desc=arcpy.Describe(file)
print desc.extent.Xmax

394551.52085039532

Pero parece que no puedo entender cómo obtener la misma información para cada fila del conjunto de datos.

rows = arcpy.SearchCursor("100k_trc_tiles_TVM")
for row in rows:
 print row

imprime las 31 filas en el conjunto de datos pero

for row in rows:
 desc=arcpy.Describe(row)
 print desc.extent.Xmax

da un error

Error de tiempo de ejecución: objeto: describir el valor de entrada no es un tipo válido

Estaba pensando en agregar los valores de extensión a la tabla usando "calcular geometría", pero esto solo da el centroide. Entonces supongo que podemos usar algo como row.GetValue ("xmax").

Dicho esto, sé que podemos crear X / Y, max / min usando la función de http://www.ian-ko.com/free/free_arcgis.htm, pero sería mejor si evitáramos tener que agregar campos, especialmente si ArcPy puede obtener estos valores.

Básicamente, necesito obtener las extensiones para alimentar la herramienta de recorte para recortar 30 áreas de datos (de acuerdo con las hojas de mapa 1: 100,000) para el geoprocesamiento, ya que la herramienta Dividir falla debido al gran tamaño del conjunto de datos (consulte Por qué Intersect proporciona ERROR 999999: Error al ejecutar la función Topología no válida [¿Demasiados puntos finales lineseg]? ). Quiero automatizar esto, ya que se repite en varios conjuntos de datos.

=== script de trabajo ===

# Emulates Arc Info SPLIT tool by using Clip but
# Requires a FC from which each row is used as the input clip feature.
# Each row must be rectangular.
# Used on 12GB FGDB with 100 million records.


#Licence: Creative Commons
#Created by: George Corea; georgec@atgis.com.au, coreagc@gmail.com
import arcpy, string

#inFrame=arcpy.GetParameterAsText(0) # Input dataframe FC
#inFile=arcpy.GetParameterAsText(1) # Input FC for splitting
#outDir=arcpy.GetParameterAsText(2) # Output FGDB

inFrame=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
inFile=r"c:\junk\106\data\7_Merge.gdb\FullRez_m2b"
outDir=r"D:\SCRATCH\Projects\206\datasplit\test_slaasp.gdb"
#NameField="Name_1"

#arcpy.env.workspace = r"C:/Workspace"
arcpy.env.overwriteOutput = True

rows = arcpy.SearchCursor(inFrame)
shapeName = arcpy.Describe(inFrame).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    Name = row.Name_1
    print "Executing clip on: "+str(Name)
    extent = feat.extent
    #print extent.XMin,extent.YMin,extent.XMax,extent.YMax
# Create an in_memory polygon
    XMAX = extent.XMax
    XMIN = extent.XMin
    YMAX = extent.YMax
    YMIN = extent.YMin
    pnt1 = arcpy.Point(XMIN, YMIN)
    pnt2 = arcpy.Point(XMIN, YMAX)
    pnt3 = arcpy.Point(XMAX, YMAX)
    pnt4 = arcpy.Point(XMAX, YMIN)
    array = arcpy.Array()
    array.add(pnt1)
    array.add(pnt2)
    array.add(pnt3)
    array.add(pnt4)
    array.add(pnt1)
    polygon = arcpy.Polygon(array)
    ShapeFile = outDir+"\\temp_poly"
    arcpy.CopyFeatures_management(polygon, ShapeFile)

    #print Name
### Set local variables
    in_features = inFile
    clip_features = ShapeFile
    out_feature_class = outDir+"\\"+Name
    xy_tolerance = "0.22"

    # Execute Clip

    try:
        arcpy.Clip_analysis(in_features, clip_features, out_feature_class, xy_tolerance)
        print "Completed: "+str(Name)
    except:
        error = arcpy.GetMessages()
        print "Failed on: "+str(Name)+" due to "+str(error)

2
No necesita escribir la función de clip en el disco, solo use el polígono en memoria, por ejemplo: polygon = arcpy.Polygon (array) arcpy.Clip_analysis (in_features, polygon, out_feature_class, xy_tolerance)
user2856

tks. ¿Alguna idea de cómo puedo exportar la fila a un nuevo archivo de forma para que se use, en lugar de solo la extensión de la fila? Esto es para que pueda manejar clips no rectangulares también.
GeorgeC

1
Bueno, si solo desea recortar por esa característica, en el mismo script, simplemente use el objeto de la característica. Nuevamente, no es necesario exportar a un archivo de formas, por ejemplo: arcpy.Clip_analysis (in_features, feat, out_feature_class, xy_tolerance)
user2856

¿Para un shapefile o para cada polígono en un shapefile? Parece que estás hablando de dos cosas separadas aquí.
Rayner

¿hay solo un objeto poligonal en tu shapefile? si no, use for loop para la extensión de sus objetos.
Aragón

Respuestas:


26

Obtenga el objeto de forma en su cursor y acceda a su propiedad de extensión. Consulte la Ayuda de ArcGIS Trabajar con geometría en Python :

shapeName = arcpy.Describe(inFeatures).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    extent = feat.extent
    print extent.XMin,extent.YMin,extent.XMax,extent.YMax

1
Gracias Luke Esto funcionó muy bien. Editaré mi pregunta para que tenga el nuevo código de trabajo si alguien quiere usar una herramienta que: utiliza el conjunto de herramientas Recortar de manera iterativa para recortar regiones rectangulares de una clase de entidad grande. Emula la funcionalidad de la herramienta de información de arco dividido sin fallar con conjuntos de datos de hasta 10GB FGDB y 100 millones de registros.
GeorgeC

Una cosa: tuve que codificar el nombre de la columna para obtener el equivalente de Name = row.Name_1 probando el atributo name como; NameField = "Name_1"; Nombre = row.NameField; o Nombre = fila + "." + NameField donde NameField = arcpy.GetParameterAsText (2) y el Nombre se mantiene en la columna Nombre_1. ¿Algunas ideas? Nota I; he usado ";" para denotar una nueva línea.
GeorgeC

1
deduje lo anterior - row.GetValue (xxx) de gis.stackexchange.com/questions/16586/…
GeorgeC

7

El conjunto de herramientas Bounding Container hace exactamente lo que quieres. Si solo desea fragmentos de código, examine las funciones dentro de los scripts, uno trata explícitamente con la extensión.

EDITAR

Debo agregar que el script agregará valores a un campo Izquierdo, Derecho, Superior e Inferior en el archivo de salida creado que puede usarse para el procesamiento posterior


Gracias. Lo comprobaré Espero poder usar el código dentro de mis scripts / modelos de Python.
GeorgeC

2

Acabo de probar la geometría de límite mínimo (envolvente) (en gestión de datos) en ArcGIS 10 y parece hacer exactamente lo mismo para todos los campos.


1

Otra forma sería hacer un SearchCursor () en el archivo de forma, luego puede usar row.shape.extent:

rows = arcpy.SearchCursor(shapefileName)

for row in rows:
   extent = row.shape.extent
   ...
   ...

1

Como se cubre en Extraer coordenadas de vértices de polígono en ArcMap? puede obtener los vértices de un polígono y luego agregar las coordenadas x e y de cada vértice como campos en la tabla de atributos. Esto tiene la limitación de no asociar las coordenadas máximas / mínimas directamente a cada polígono, pero esto se puede lograr de varias maneras.

El método con el que estoy más familiarizado es leer los campos xey en las listas de python usando el módulo pyshp , que luego se puede ordenar para encontrar valores máximos y mínimos para cada polígono. Pyshp se puede usar para abrir una clase de escritor para agregar nuevos campos a los polígonos originales y escribir estos valores máximo y mínimo en el polígono correcto.

Creo que esto se puede hacer usando el arcpy, pero tuve muchos problemas al escribir en shapefiles en 9.3 usando el geoprocesador, así que prefiero el método pyshp, sin embargo, no estoy seguro de si el módulo arcpy ha resuelto estos problemas.


0

¿Intentaste poner en mayúscula la "M" en "XMax"? Creo que se supone que es:

print desc.extent.XMax

en lugar de

print desc.extent.Xmax

De acuerdo a la documentación . Por supuesto, eso me hace preguntarme cómo funcionó su primer fragmento de código. De cualquier manera, ¡pruébalo!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.