Obtendo a extensão de cada polígono no shapefile usando o ArcPy?


20

No ArcGIS 10 e Python, quero obter as informações de extensão (xmax, ymax, xmin, ymin) de cada um dos polígonos em um shapefile.

Eu posso obter a extensão de todo o shapefile usando

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

394551.52085039532

Mas não consigo descobrir como obter as mesmas informações para cada linha no conjunto de dados.

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

imprime as 31 linhas no conjunto de dados, mas

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

dá um erro.

Erro de tempo de execução: Objeto: Descrever o valor de entrada não é um tipo válido

Eu estava pensando em adicionar os valores de extensão à tabela usando "calcular geometria", mas isso apenas fornece o centróide. Então eu acho que podemos usar algo como row.GetValue ("xmax").

Dito isto, sei que podemos criar o X / Y, max / min usando a função http://www.ian-ko.com/free/free_arcgis.htm, mas seria melhor se pudéssemos evitar adicionar campos, especialmente se o ArcPy puder obter esses valores.

Basicamente, preciso obter as extensões para alimentar a ferramenta de recorte para recortar 30 áreas de dados (de acordo com as folhas de mapa 1: 100.000) para geoprocessamento, pois a ferramenta Dividir falha devido ao grande tamanho do conjunto de dados (consulte Por que o Intersect fornece ERRO 999999: Erro ao executar a função Topologia inválida [muitos pontos de extremidade da linha de linha]? ). Eu quero automatizar isso, pois é repetido em vários conjuntos de dados.

=== script de trabalho ===

# 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
Você não precisa escrever o recurso de clipe para o disco, basta usar o no polígono de memória, por exemplo: polígono = arcpy.Polygon (array) arcpy.Clip_analysis (in_features, polígono, out_feature_class, xy_tolerance)
— user2856

tks. Alguma idéia de como posso exportar a linha para um novo arquivo de forma, para que ela seja usada, em vez de apenas a extensão da linha? Isso é para que ele também possa lidar com clipes não retangulares.
— GeorgeC

1
Bem, se você deseja apenas recortar por esse recurso, no mesmo script, basta usar o objeto de recurso. Novamente, não há necessidade de exportar para o arquivo de forma, por exemplo: arcpy.Clip_analysis (in_features, feat, out_feature_class, xy_tolerance)
— user2856

Para um shapefile ou para cada polígono em um shapefile? Parece que você está falando sobre duas coisas separadas aqui.
— 22412 Rayner

existe apenas um objeto de polígono no seu shapefile? caso contrário, use o loop for para a extensão dos objetos.
— Aragão

Respostas:


26

Obtenha o objeto de forma no seu cursor e acesse sua propriedade de extensão. Consulte a Ajuda do ArcGIS Trabalhando com geometria no 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
Obrigado Luke. Isso funcionou muito bem. Editarei minha pergunta para ter o novo código de trabalho se alguém quiser usar uma ferramenta que - Usa o conjunto de ferramentas Clipe de forma iterativa para recortar regiões retangulares de uma grande classe de recurso. Emula a funcionalidade da ferramenta Split de informações do arco sem travar com conjuntos de dados de até 10 GB de FGDB e 100 milhões de registros.
— 7117 GeorgeC

Uma coisa: eu tive que codificar o nome da coluna para obter o equivalente a Name = row.Name_1, tentando o atributo name como; NameField = "Name_1"; Nome = row.NameField; ou Name = row + "." + NameField em que NameField = arcpy.GetParameterAsText (2) e o Name são mantidos na coluna Name_1. Alguma ideia? Nota I; usei ";" para denotar uma nova linha.
— 7114 GeorgeC

1
figurado o acima - row.GetValue (xxx) a partir gis.stackexchange.com/questions/16586/...
— GeorgeC

7

O conjunto de ferramentas Contêiner delimitador faz exatamente o que você deseja. Se você quiser apenas trechos de código, examine as funções nos scripts, uma delas lida explicitamente com a extensão.

EDITAR

Devo acrescentar que o script adicionará valores aos campos Esquerdo, Direito, Superior e Inferior no arquivo de saída criado, que pode ser usado para processamento subsequente


obrigado. Irá verificar. Espero que eu possa usar o código nos meus scripts / modelos python.
— GeorgeC

2

Eu apenas tentei a geometria mínima de delimitação (Envelope) (em Gerenciamento de dados) no ArcGIS 10 e parece fazer exatamente o mesmo, para todos os campos.


1

Outra maneira seria fazer um SearchCursor () no shapefile, então você pode usar row.shape.extent:

rows = arcpy.SearchCursor(shapefileName)

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

1

Como abordado em Extraindo coordenadas de vértices poligonais no ArcMap? você pode obter os vértices de um polígono e adicionar as coordenadas xey de cada vértice como campos na tabela de atributos. Isso tem a limitação de não anexar as coordenadas max / min diretamente a cada polígono, mas isso pode ser alcançado de algumas maneiras.

O método com o qual estou mais familiarizado é ler os campos xey nas listas python usando o módulo pyshp , que pode ser classificado para encontrar valores máximos e mínimos para cada polígono. O Pyshp pode ser usado para abrir uma classe de gravador para adicionar novos campos aos polígonos originais e gravar esses valores máximo e mínimo no polígono correto.

Acredito que isso possa ser feito usando o arcpy, mas tive muitos problemas ao escrever para shapefiles na 9.3 usando o geoprocessador, então prefiro o método pyshp, no entanto, não tenho certeza se o módulo arcpy resolveu esses problemas.


0

Você tentou capitalizar o "M" no "XMax"? Eu acho que deveria ser:

print desc.extent.XMax

ao invés de

print desc.extent.Xmax

de acordo com a documentação . Claro que isso me faz pensar em como o seu primeiro trecho de código funcionou. De qualquer maneira, tente!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.