Desafortunadamente no se pueden asignar directamente nuevos valores a la geometría existente de una característica, sino que hay que crear un nuevo objeto de geometría y actualizar el campo de forma de la característica con ese nuevo objeto. Afortunadamente, los objetos de la matriz tienen un replace
método. Así que en lugar de intentar modificar directamente la coordenada X del punto dentro de la matriz, es necesario:
- Crear un nuevo
arcpy.Point
objeto con las coordenadas correctas (parece que ya lo habrías hecho)
- Consigue una copia del objeto de la matriz almacenado en el campo Shape de la fila
- Use el
replace
método para establecer el punto deseado en su matriz con su punto modificado
- Hacer un nuevo objeto de Polyline con esa matriz
- Usar el objeto de la fila
setValue
método para actualizar el campo de la forma con su nueva y correcta polilínea
- Usar el objeto del cursor
updateRow
método para insertar la fila cambiada en el conjunto de datos.
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)
Note el replace
El método toma un índice y un valor. Desafortunadamente no acepta, por ejemplo, -1 como índice hasta el último punto de la matriz. Sin embargo, puedes decir my_array[my_array.count]
.
Parece que estás precomputando las coordenadas X en otro lugar y las recuperas después. Si este es el caso, probablemente iría a todo el cerdo y crearía nuevos objetos de Polilínea con los puntos correctos para cada línea mientras estás computando las coordenadas correctas. Esto probablemente será más fácil y limpio. De esa manera tu código podría ser más como
row_num = 0
for r in cur:
r.setValue(shapeField,correct_geometry_list[row_num])
cur.updateRow(r)
row_num += 1
Lo cual, al menos para mí, es un poco más claro... ¡pero eso es estilístico!
Editar para añadir:
No podría encajar esto en un comentario. Sin ver tu código es difícil saber dónde puede estar cayendo. Aquí hay un completo guión probado que funciona para mí. Espero que sirva como referencia. Tengan en cuenta que aquí estoy calculando la nueva geometría directamente a partir de la antigua, en lugar de hacer dos pasadas; eso puede o no ser posible dependiendo de cómo estén haciendo sus cálculos de posición de encaje. También esta vez estoy construyendo una nueva matriz basada en la antigua, en lugar de usar la replace
método, en caso de que sea necesario.
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
Esperemos que eso ayude a aclararlo.