¿Crear líneas a partir de coordenadas de pares de puntos con ArcPy?

11

Tengo algunas coordenadas de pares de puntos (puntos inicial y final) que tengo que transformar en líneas. Hasta ahora, utilicé un anexo de ambas coordenadas en a pippo.Point(), a pippo.CalculateGeometry()para definir la geometría de cada piont e pippo.append(defined geometry)identificar el par de puntos, y luego PointsToLine para obtener mi línea. Esto es bastante costoso para cientos de líneas.

¿Hay una forma más corta de hacer esto?

Por ejemplo, coloque el punto inicial y final de cada línea en diferentes campos de una sola tabla e importe líneas directamente sin pasar por la geometría de los puntos.

Annalisa Minelli
fuente

Respuestas:

8

Esto lee una tabla (hoja de Excel en este caso, pero podría ser cualquier tipo de tabla) que se ve así:

ingrese la descripción de la imagen aquí

S_X es el punto X inicial, el punto X final E_X, lo mismo para Y's. Realizamos iteraciones a través de la tabla de entrada, luego para cada fila, establecemos las X / Y iniciales / finales en un punto, agregamos ese punto a una matriz y luego creamos una polilínea a partir de la matriz de dos puntos. Luego inserte en la clase de características. Enjuague y repita.

import arcpy

in_rows = arcpy.SearchCursor(r"D:\Temp\Lines.xls\Sheet1$")

point = arcpy.Point()
array = arcpy.Array()

featureList = []
cursor = arcpy.InsertCursor(r"D:\Temp\Lines.shp")
feat = cursor.newRow()

for in_row in in_rows:
    # Set X and Y for start and end points
    point.X = in_row.S_X
    point.Y = in_row.S_Y
    array.add(point)
    point.X = in_row.E_X
    point.Y = in_row.E_Y
    array.add(point)   
    # Create a Polyline object based on the array of points
    polyline = arcpy.Polyline(array)
    # Clear the array for future use
    array.removeAll()
    # Append to the list of Polyline objects
    featureList.append(polyline)
    # Insert the feature
    feat.shape = polyline
    cursor.insertRow(feat)
del feat
del cursor

Y obtienes tus líneas:

ingrese la descripción de la imagen aquí

Chad Cooper
fuente
Gracias, intentaré estimar la duración de mi análisis ... fue exactamente lo que estaba tratando de hacer :-)
Annalisa Minelli
Para la línea point.X = in_row.S_X devuelve un error que dice que el valor de entrada no es numérico. Traté de hacerlo int o float o incluso numérico, pero no funciona porque el campo no es un número es Nonetype. ¿Alguna ayuda?
Federico Gómez
5

Creé un script de Python la semana pasada (sin usar ArcPy), que toma puntos que crean la geometría de las líneas de bus (un punto shp) según un campo de número secuencial ("SEQ"). Puede ajustarlo fácilmente para tomar la coordenada de un campo de la misma entidad (usando el valor del campo en lugar de la geometría).

# -*- coding: utf-8 -*-
###############################################################################
from sys import argv
import osgeo.ogr
import os, os.path
###############################################################################

script, srcSHP = argv

#-- Open source shapefile
shapefile = osgeo.ogr.Open(srcSHP)
layer = shapefile.GetLayer(0)
spatialRef = layer.GetSpatialRef()

#-- Output directory
outDir = os.path.dirname(srcSHP)
outDirName = os.path.basename(outDir)

driver = osgeo.ogr.GetDriverByName("ESRI Shapefile")
outFile = driver.CreateDataSource(os.path.join(outDir,outDirName + "_lines.shp"))
outLayer = outFile.CreateLayer("layer", spatialRef)

#-- Adding fields to the output shapefile
fieldDef = osgeo.ogr.FieldDefn("line_no", osgeo.ogr.OFTString)
fieldDef.SetWidth(12)
outLayer.CreateField(fieldDef)

fieldDef = osgeo.ogr.FieldDefn("From_SEQ", osgeo.ogr.OFTReal)
outLayer.CreateField(fieldDef)

fieldDef = osgeo.ogr.FieldDefn("To_SEQ", osgeo.ogr.OFTReal)
outLayer.CreateField(fieldDef)

#-- Going through each feature, one by one
#-- The last point is the end of the line so I don't want to iterate through that one
for i in range(layer.GetFeatureCount()-1):
    lString = osgeo.ogr.Geometry(osgeo.ogr.wkbLineString)  

    feature1 = layer.GetFeature(i)
    feature2 = layer.GetFeature(i+1)

    # When it's a new line, the sequential number restart to 1, so we don't want that line
    if feature1.GetField("SEQ") < feature2.GetField("SEQ"):
        geom1 = feature1.GetGeometryRef()
        geom2 = feature2.GetGeometryRef()

        geom1x = geom1.GetX()
        geom1y = geom1.GetY()
        geom2x = geom2.GetX()
        geom2y = geom2.GetY()

        lString.AddPoint(geom1x, geom1y)
        lString.AddPoint(geom2x, geom2y)     # Adding the destination point

        #-- Adding the information from the source file to the output
        feat = osgeo.ogr.Feature(outLayer.GetLayerDefn())
        feat.SetGeometry(lString)
        feat.SetField("line_no", feature1.GetField("line_no"))
        feat.SetField("From_SEQ", feature1.GetField("SEQ"))
        feat.SetField("To_SEQ", feature2.GetField("SEQ"))
        outLayer.CreateFeature(feat)

print "The End"

Cada par de puntos creará una sola línea. Puede haber una forma más elegante de hacer esto, pero creó 3900 líneas en aproximadamente 15 segundos, así que funciona para mí ...

fgcartographix
fuente
Gracias, parece exactamente una elaboración masiva ... eso debería ser realmente útil para mí. Lo intentaré y luego retroalimentaré. gracias por ahora
Annalisa Minelli
3

puede usar estas dos herramientas para crear una capa de evento XY y puntos a línea , al ver los parámetros necesarios en puntos a línea (campo de línea, puntos de clasificación) y actualizar los datos de la tabla de entrada, la tarea podría ser más simple

geogeek
fuente
1

esto es solo una actualización de la respuesta de @ ChadCooper, porque los cursores "da" ahora están reemplazando ventajosamente los cursores anteriores:

with arcpy.da.SearchCursor(input_table,[orig_namefield,x1,y1,x2,y2] ) as in_rows:
    with arcpy.da.InsertCursor(output_lines,["SHAPE@",name_field]) as cursor:
        for row in in_rows:
            # build array for line segment
            array = arcpy.Array([arcpy.Point(row[1],row[2]),arcpy.Point(row[3],row[4])])
            # Create a Polyline object based on the array of points
            polyline = arcpy.Polyline(array)
            # Insert the feature
            cursor.insertRow([polyline,row[0]])
radouxju
fuente