Estou tentando calcular a área de um polígono dentro do meu script Python. Crio um novo polígono a partir da mesclagem de dois e gostaria de adicionar a área do polígono resultante a um campo no arquivo de saída. O polígono é armazenado em um arquivo de forma regular e é projetado. Área preferencialmente em unidades de mapa.
Eu pensaria que essa é uma tarefa bastante comum e simples, mas apesar de muito Googleing, não consegui encontrar soluções funcionais até agora.
Eu estava pensando em usar arcpy.updateCursor
para inserir o valor uma vez calculado (há apenas um recurso no FC neste estágio), então é mais fácil se ele pode ser retornado como uma variável. Qualquer solução alternativa que realize a mesma tarefa (colocar o valor da área no campo correto) também funcionará.
Eu também tentei a calculadora de campo do Python. Modificado nas páginas de ajuda, pensei que o seguinte funcionaria, mas até agora não houve sorte.
arcpy.AddField_management(tempPgs, "Shape_area", 'DOUBLE')
exp = "float(!SHAPE.AREA!.split())"
arcpy.CalculateField_management(tempPgs, "Shape_area", exp)
Executando o ArcGIS Basic 10.1 SP1 com Python 2.7 no Windows 7.
Partes relevantes do meu código atual são assim:
#/.../
arcpy.Copy_management(inpgs, outpgs)
arcpy.AddField_management(outpgs, 'Shape_area', 'LONG')
fields = AM.FieldLst(outpgs)
#/.../
# Identify and search for shapes smaller than minimum area
where1 = '"' + 'Shape_Area' + '" < ' + str(msz)
polyrows = arcpy.SearchCursor(inpgs, where1)
for prow in polyrows:
grd1 = prow.GridID # GridID on the current polygon
grd2 = nDD.get(grd1) # GridID on the polygon downstream
# Update features
if grd2
geometry1 = prow.Shape
geometry2 = geometryDictionary[grd2]
# Update temporary features
arcpy.Merge_management([geometry1, geometry2], tempMerged)
arcpy.Dissolve_management(tempMerged, tempPgs)
fds = AM.FieldLst(tempPgs)
for field in fields[2:]:
arcpy.AddField_management(tempPgs, field, 'DOUBLE')
for fd in fds[2:]:
arcpy.DeleteField_management(tempPgs, fd)
exp = "float(!SHAPE.AREA!.split())"
arcpy.CalculateField_management(tempPgs, "Shape_area", exp)
# Append them to output FC
try:
arcpy.Append_management(tempPgs, outpgs, "TEST")
except arcgisscripting.ExecuteError:
arcpy.Append_management(tempPgs, outpgs, "NO_TEST")
elif ...
else ...
fonte
SHAPE@AREA
como parte do seu cursor para ler a área; mas a estrutura do código depende se sua área está nas mesmas unidades que você deseja escrever.Respostas:
Existem três maneiras diferentes de encontrar e armazenar a área de polígono em uma classe de recurso com arcpy: 1) calculadora de campo, 2) cursores arcpy "clássicos" e 3)
arcpy.da
cursores. Parte disso é emprestada da minha resposta anterior sobre o uso do SearchCursor .1. Calculadora de campo
Ao usar a calculadora de campo, existem três tipos de expressão diferentes que usam analisadores de expressão diferentes. Isso é especificado no terceiro parâmetro da ferramenta de geoprocessamento Calculate Field . Ao acessar as propriedades do objeto Geometry usando like in
!shape.area!
, você deve usar o analisador Python 9.3.A expressão que você tinha antes executou um
split()
comando no resultado de!SHAPE.AREA!
. Isso retorna umlist
objeto Python , que não pode ser convertido em umfloat
objeto.Na sua expressão, você pode especificar a unidade da área retornada usando o
@SQUAREKILOMETERS
sinalizador, substituindoSQUAREKILOMETERS
pelas unidades na página de ajuda Calcular Campo .Aqui está o código Python que eu usaria para este método:
2. Arco 10.0 - cursores "clássicos"
Ao usar cursores clássicos (ou seja
arcpy.UpdateCursor
), o objeto cursor é um objeto iterável que contémrow
objetos. Você precisa usar os métodosgetValue
esetValue
para obter a geometria da linha (como um objeto de geometria e definir o valor da árearow
como flutuador.Sua linha de saída é armazenada em um espaço temporário temporário até você chamar o
updateRow
método no cursor. Isso salva os novos dados no conjunto de dados real.Aqui está o código Python que eu usaria para este método:
3. Arco 10.1 - cursores do arcpy.da
Ao usar os novos cursores no módulo de acesso a dados (ou seja
arcpy.da.UpdateCursor
), é necessário passar uma lista de nomes de campos como o segundo parâmetro no construtor do cursor. Isso requer mais trabalho inicial, mas osrow
objetos resultantes são listas Python, o que facilita a leitura e gravação de dados ao percorrer as linhas do cursor.arcpy.da.UpdateCursor
também tem melhor desempenho do quearcpy.UpdateCursor
, em parte porque ignora campos sem importância, principalmente geometria.Ao ler a geometria, você pode escolher um de uma série de tokens de geometria, por exemplo
SHAPE@TRUECENTROID
,SHAPE@AREA
ouSHAPE@
. O uso de um token "mais simples" melhora muito o desempenho em comparação com oSHAPE@
que contém todas as informações de geometria. A lista completa de tokens está naarcpy.da.UpdateCursor
página de ajuda.Como antes, sua linha de saída é armazenada em um espaço temporário temporário até você chamar o
updateRow
método no cursor. Isso salva os novos dados no conjunto de dados real.Aqui está o código Python que eu usaria para este método:
fonte
row[1] = row[0]
como não há mais umarea
atributo. Você também pode usar o cursor como gerenciador de contexto em umawith
instrução e não precisa se preocupar em excluir nada.