12 votos

Creación de líneas a partir de coordenadas de pares de puntos con ArcPy?

Tengo unas coordenadas de pares de puntos (puntos iniciales y finales) que tengo que transformar en líneas. Hasta ahora, he utilizado un apéndice de ambas coordenadas en un pippo.Point() , a pippo.CalculateGeometry() para definir la geometría de cada pión, y pippo.append(defined geometry) para identificar el par de puntos, y luego PointsToLine para obtener mi línea. Esto es bastante costoso en tiempo para hacer cientos de líneas.

¿Hay una forma más corta de hacerlo?

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

8voto

Arda Xi Puntos 1099

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

enter image description here

S_X es el punto X inicial, E_X el punto X final, lo mismo para los Y. Recorremos la tabla de entrada y, para cada fila, establecemos los puntos X/Y iniciales y finales en un punto, añadimos ese punto a una matriz y creamos una polilínea a partir de la matriz de dos puntos. A continuación, insertar en la featureclass. Aclarar y repetir.

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 tienes tus líneas:

enter image description here

0 votos

Gracias, intentaré estimar la duración de mi análisis.. era exactamente lo que intentaba hacer :-)

0 votos

Para la línea point.X = in_row.S_X devuelve un error diciendo que el valor de entrada no es numérico. He intentado hacerlo int o float o incluso numérico pero no funciona porque el campo no es un número es Nonetype. ¿Alguna ayuda?

5voto

user7116 Puntos 166

He creado un python script la semana pasada (no usando ArcPy sin embargo), que toma los puntos que están creando la geometría de las líneas de autobús (un punto shp) de acuerdo un campo de número secuencial ("SEQ"). Usted podría fácilmente ajustar para tomar la coordenada de un campo de la misma característica (utilizando 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 unos 15 segundos, así que me funciona...

0 votos

Gracias, parece que la elaboración masiva .. que debe ser realmente útil para mí. Voy a tratar y luego la retroalimentación. gracias por ahora.

3voto

kwutchak Puntos 232

Puede utilizar estas dos herramientas hacer capa de eventos XY y Señala la línea Al ver los parámetros necesarios en los puntos de la línea (campo de la línea, ordenar los puntos) y actualizar los datos de la tabla de entrada, la tarea podría ser más simple

2voto

xenny Puntos 670

Esto es sólo una actualización de la respuesta de @ChadCooper, ya que los cursores "da" sustituyen ventajosamente a los 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]])

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