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.