Infelizmente, você não pode atribuir novos valores diretamente à geometria existente de um recurso - é necessário criar um novo objeto de geometria e atualizar o campo de forma do recurso com esse novo objeto. Felizmente, os objetos da matriz têm um replace
método. Portanto, em vez de tentar modificar diretamente a coordenada X do ponto dentro da matriz, você precisa:
- Crie um novo
arcpy.Point
objeto com as coordenadas corretas (parece que você já deve ter feito isso)
- Obter uma cópia do objeto da matriz armazenada no campo Forma da linha
- Use o
replace
método para definir o ponto desejado em sua matriz com o ponto modificado
- Crie um novo objeto Polyline com essa matriz
- Use o
setValue
método do objeto de linha para atualizar o campo Shape com sua nova e polilinha correta
- Use o
updateRow
método do objeto cursor para inserir a linha alterada no conjunto de dados.
Concretamente:
for r in cur:
ary = r.getValue("SHAPE").getPart(0)
ary.replace(0,correct_point_object) # first arg 0 replaces the first point in the line
newLine = arcpy.Polyline(ary)
r.setValue("SHAPE",newLine)
cur.updateRow(r)
Observe que o replace
método utiliza um índice e um valor. Infelizmente, ele não aceita, por exemplo, -1 como um índice até o último ponto da matriz. No entanto, você pode dizer my_array[my_array.count]
.
Parece que você está pré-computando as coordenadas X em outro lugar e as recuperando mais tarde. Se for esse o caso, eu provavelmente faria o trabalho todo e criaria novos objetos Polilinha com os pontos corretos para cada linha enquanto você calcula as coordenadas corretas. Isso provavelmente será mais fácil e limpo. Dessa forma, seu código pode ser mais parecido com
row_num = 0
for r in cur:
r.setValue(shapeField,correct_geometry_list[row_num])
cur.updateRow(r)
row_num += 1
O que, pelo menos para mim, é um pouco mais claro ... mas isso é estilístico!
Edite para adicionar:
Eu não poderia encaixar isso em um comentário. Sem ver seu código, é difícil dizer onde ele pode estar caindo. Aqui está um script testado completo que funciona para mim. Espero que sirva de referência. Observe que aqui estou calculando a nova geometria diretamente da antiga, em vez de fazer duas passagens; isso pode ou não ser possível, dependendo de como você está fazendo seus cálculos de posição de snap. Desta vez, também estou construindo um novo array baseado no antigo, em vez de usar o replace
método, caso necessário.
import arcpy
def offsetPoint(old_point,X_distance,Y_distance):
"""Trivial function to offset a point - replace with what you're
actually doing."""
new_point = arcpy.Point(old_point.X+X_distance,
old_point.Y+Y_distance)
return new_point
def offsetFirstPointInLine(line_geom,X_distance,Y_distance):
"""Takes a Polyline geometry object and returns a new Polyline with
the first point of the first part offset by the distance given."""
array = line_geom.getPart(0)
first_point = array[0]
new_point = offsetPoint(first_point,X_distance,Y_distance)
# Build a new array with your new point in the 0th position, and
# the rest of the points from the old array.
new_array = arcpy.Array([new_point]+
[array.getObject(x) for x in range(1,array.count)])
# Then make a new Polyline object with that array.
new_line = arcpy.Polyline(new_array)
return new_line
fc = r"C:\Users\student\Documents\ArcGIS\Default.gdb\SomeStorms"
cur = arcpy.UpdateCursor(fc)
for r in cur:
geom = r.getValue("SHAPE")
r.setValue("SHAPE",offsetFirstPointInLine(geom,-45000,-5000))
cur.updateRow(r)
del r,cur
Espero que isso ajude a esclarecer.