8 votos

¿Editar los puntos finales en la polilínea usando ArcPy?

Estoy tratando de hacer una herramienta de encaje de puntos finales de polilínea en Python usando ArcGIS 10. Usando un Cursor de Búsqueda leo en los valores de un conjunto de objetos de línea (que contienen el id de característica de la línea, y dos objetos "EndPoint" -primero y último- que contienen las coordenadas X e Y de cada uno), luego proceso alguna interpolación de datos de los puntos para dar a todos los puntos sus valores correctos.

Hasta ahora, esa parte funciona perfectamente. Sin embargo, cuando intento volver y editar el archivo de formas, puedo ver los datos que estoy cambiando, pero parece que no puedo editarlo.

Aquí está el código para actualizar los campos:

# --------------------------
#
# Update the file with the new EPs
#
# --------------------------

# Create update cursor
#
rows = arcpy.UpdateCursor(outputDirectory + "\\" + trails_fc + ".shp")

# Enter for loop for each feature/row
#
i = 0
for row in rows:
    # Create the geometry object
    #
    feat = row.getValue(shapefieldname)

    partnum = 0

    if feat.getPart(partnum)[0].X != allLines[i].startEP.x:
        arcpy.AddMessage("Change: " + str(feat.getPart(partnum)[0].X) + " to " + str(allLines[i].startEP.x) )
        feat.getPart(partnum)[0].X = allLines[i].startEP.x

    rows.updateRow(row)

    arcpy.AddMessage("Now is: " + str(feat.getPart(partnum)[0].X))

    i+=1

Mi lectura consiste en declaraciones como esta:

Cambio: -105.512166832 a -105.699533165 Ahora es: -105.512166832

Por alguna razón, las filas no se actualizan. Y por mi vida, no puedo encontrar un tutorial o instrucciones sobre cómo editar un punto en particular en una polilínea. Sólo puedo encontrar cómo editar un punto como un campo en un archivo de forma de punto.

¿Alguien tiene alguna idea?

6voto

Jason Navarrete Puntos 3873

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.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X