5 votos

ArcGIS - Python - Extender la línea XY a valor Z

Mucho tiempo lector, por primera vez póster. Así que aquí está mi objetivo:

Trabajo en ArcGIS, tratando de trabajar con el creador de modelos y secuencias de comandos de Python.

Tengo una serie de líneas y una sola trama DEM.

Me gustaría extender mi segmentos de línea hasta su componente Z ha cambiado por al menos 20 metros. Mis primeros pensamientos sobre esto fueron:

  1. Escribir Z_Min y Z_Max para la línea de

  2. Calcular Z_Diff = Z_Max - Z_Min, para un chequeo

  3. Si no, extender la línea de 30m (número aleatorio), de verificación, si no, extender, verificar, etc.

Me las he arreglado para conseguir algo de código que se ejecutará a través del proceso, pero sólo se detiene una vez que TODAS las funciones están satisfechos (no individualmente). Me gustaría recorrer cada característica y hacer el check (o de verificación de todo, ampliar aquellos que no satisfacen, etc.)

Mis intentos en la consulta de los conjuntos de datos a través de una instrucción where dentro de UpdateCursor función de la declaración fueron incorrectas - estoy bastante seguro de que yo estaba jugando con el creado tuplas de coordenadas (la tupla de la OID@ y la FORMA@XY) pero no estoy seguro.

Actual Código de bucles a través de una sola vez y a pesar de mis mejores esfuerzos - más o menos se asemeja a algunas secuencias de comandos de ejemplo ya publicado. Si alguien tiene sugerencias/muestras, que sería MUY apreciada.

Es este un simple Bucle "while"?

#Code from <http://gis.stackexchange.com/questions/71645/a-tool-or-way-to-extend-line-by-specified-distance> by Paul.

from math import hypot
import collections
from operator import add
import arcpy

# Check out any necessary licenses
arcpy.CheckOutExtension("3D")

#Local variables:
DEM = "DEM"

#Need to set these as imported Script for ArcGIS
layer = arcpy.GetParameterAsText(0)
distance = float(arcpy.GetParameterAsText(1))

# Process: Add Surface Information
arcpy.AddSurfaceInformation_3d(layer, EnfDEM_Bird, "Z_MIN;Z_MAX;SURFACE_LENGTH", "BILINEAR", "", "1", "0", "NO_FILTER")
# Process: Calculate Field
arcpy.CalculateField_management(layer, "Z_Diff", "[Z_Max] - [Z_Min]", "VB", "")

#Computes new coordinates x3,y3 at a specified distance
#along the prolongation of the line from x1,y1 to x2,y2
def newcoord(coords, dist):
    (x1,y1),(x2,y2) = coords
    dx = x2 - x1
    dy = y2 - y1
    linelen = hypot(dx, dy)

    x3 = x2 + dx/linelen * dist
    y3 = y2 + dy/linelen * dist    
    return x3, y3

#accumulate([1,2,3,4,5]) --> 1 3 6 10 15
#Equivalent to itertools.accumulate() which isn't present in Python 2.7
def accumulate(iterable):    
    it = iter(iterable)
    total = next(it)
    yield total
    for element in it:
        total = add(total, element)
        yield total

#OID is needed to determine how to break up flat list of data by feature.
coordinates = [[row[0], row[1]] for row in
           arcpy.da.SearchCursor(layer, ["OID@", "SHAPE@XY"], explode_to_points=True)]

oid,vert = zip(*coordinates)

#Construct list of numbers that mark the start of a new feature class.
#This is created by counting OIDS and then accumulating the values.
vertcounts = list(accumulate(collections.Counter(oid).values()))

#Grab the last two vertices of each feature
lastpoint = [point for x,point in enumerate(vert) if x+1 in vertcounts or x+2 in vertcounts]

#Convert flat list of tuples to list of lists of tuples.
#Obtain list of tuples of new end coordinates.
newvert = [newcoord(y, distance) for y in zip(*[iter(lastpoint)]*2)]    

j = 0

with arcpy.da.UpdateCursor(layer, ["SHAPE@XY"], explode_to_points=True) as rows:
    for i,row in enumerate(rows):
        if i+1 in vertcounts:    
            row[0] = newvert[j]
            j+=1
            rows.updateRow(row)
            # Process: Add Surface Information
            arcpy.AddSurfaceInformation_3d(layer, EnfDEM_Bird, "Z_MIN;Z_MAX;SURFACE_LENGTH", "BILINEAR", "", "1", "0", "NO_FILTER")
            # Process: Calculate Field
            arcpy.CalculateField_management(layer, "Z_Diff", "[Z_Max] - [Z_Min]", "VB", "")

1voto

houbysoft Puntos 222

Disculpas por no entender todo lo que en su código, pero te sugiero un método diferente en general. En su mayoría es para uso GetCellValue_management. Sólo una especie de aleteo de esto, así que estoy seguro de que habrá algunos problemas de trabajo. Yo estaba teniendo un momento difícil con el formato de la pseudo código, demasiado...

No voy a hacer todo desde que tomaría demasiado tiempo en mi final.

  1. consigue 2 xy pares para cada línea. Supongo inicio y final de los nodos, pero puede tener líneas curvas o alguna otra base. Usted también tendrá que definir la dirección que desea ir. Podría utilizar un SearchCursor() a extraer estos valores para una agradable y simple de la matriz.
  2. averiguar el incremento desea extender por (usted dijo 30m) y convertirlo en el ajuste de incrementos para el "x" y "y" dimensiones. Supongo que usted querrá averiguar la pendiente de la línea definida por los dos pares de coordenadas XY. Tienda en otra matriz o lista.
  3. uso GetCellValue_management encontrar de inicio y final de elevaciones para todas las líneas
  4. probablemente desee izip las elevaciones con el fin de coordenadas para la iteración. digamos que los campos son lineEnd_x, LineEnd_y, "inicio" elevación "final" de la elevación. También podría incluir los factores de ajuste en lo que se está cerrando juntos por conveniencia. Vamos a llamar a este lines.
  5. algunos pseudo código:

    for line in lines: 
        if line[2] - line[3] < threshold: # 20 meters or whatever, also might want abs()
          continue
        else: # enclosing your while loop.
            while (line[2] - line[3]) < threshold:
                line[0] = line[0] + xadj
                line[1] = line[1] + yadj
                line[3] = arcpy.GetCellValue_management(dem, arcpy.Point(line[0], line[1]))  
    
  6. iterar sobre actualizado lines matriz para extender las líneas. Puede hacerlo de varias maneras, desde la creación de un nuevo conjunto de vectores a la ampliación de los viejos con algo como ExtendLine_edit (habría que comparar nuevos XY coords con la inicial final XY coords para obtener la distancia de desplazamiento).

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