Criar linhas a partir de pontos emparelha coordenadas com o ArcPy?

11

Eu tenho algumas coordenadas de pares de pontos (pontos inicial e final) que tenho que transformar em linhas. Até agora, usei um acréscimo de ambas as coordenadas em a pippo.Point(), a pippo.CalculateGeometry()para definir a geometria de cada ponto inicial, pippo.append(defined geometry)identificar o par de pontos e, em seguida, PointsToLine para obter minha linha. É bastante caro fazer isso por centenas de linhas.

Existe uma maneira mais curta de fazer isso?

Por exemplo, coloque o ponto inicial e final de cada linha em campos diferentes de uma única tabela e importe as linhas diretamente sem passar pela geometria dos pontos.

Annalisa Minelli
fonte

Respostas:

8

Isso lê uma tabela (planilha do Excel, neste caso, mas pode ser qualquer tipo de tabela) com a seguinte aparência:

insira a descrição da imagem aqui

S_X é o ponto X inicial, E_X eo ponto X final, o mesmo para os Y's. Nós iteramos na tabela de entrada e, em cada linha, definimos os X / Ys de início / fim em um ponto, adicionamos esse ponto a uma matriz e criamos uma polilinha a partir da matriz de dois pontos. Em seguida, insira na classe de recurso. Enxague e 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

E você obtém suas linhas:

insira a descrição da imagem aqui

Chad Cooper
fonte
Obrigado, vou tentar estimar a duração da minha análise .. era exatamente o que eu estava tentando fazer :-)
Annalisa Minelli
Para o ponto de linha.X = in_row.S_X, retorna um erro dizendo que o valor de entrada não é numérico. Eu tentei fazê-lo int ou float ou mesmo numérico, mas não funciona porque campo não é um número é Nonetype. Qualquer ajuda?
Federico Gómez
5

Eu criei um script python na semana passada (embora não use o ArcPy), que pega pontos que estão criando a geometria das linhas de ônibus (um shp de ponto) de acordo com um campo numérico seqüencial ("SEQ"). Você pode facilmente ajustá-lo para obter a coordenada de um campo do mesmo recurso (usando o valor do campo em vez da geometria).

# -*- 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 pontos criará uma única linha. Pode haver uma maneira mais elegante de fazer isso, mas ele criou 3900 linhas em cerca de 15 segundos, para que funcione para mim ...

fgcartographix
fonte
Obrigado, parece exatamente uma elaboração maciça .. isso deve ser realmente útil para mim. Vou tentar e depois feedback. Obrigado por ora.
Annalisa Minelli
3

você pode usar essas duas ferramentas para criar a camada de eventos XY e pontos a linha , vendo os parâmetros necessários em pontos a linha (campo de linha, pontos de classificação) e atualizar os dados da tabela de entrada; a tarefa pode ser mais simples

geogeek
fonte
1

esta é apenas uma atualização da resposta de @ ChadCooper, porque os cursores "da" agora estão substituindo com vantagem os 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
fonte