Erstellen von Linien aus Punktpaarkoordinaten mit ArcPy?


11

Ich habe einige Punktepaarkoordinaten (Start- und Endpunkte), die ich in Linien umwandeln muss. Bisher habe ich beide Anhängen in a pippo.Point(), a pippo.CalculateGeometry()angehängt, um die Geometrie jedes Pionts zu definieren und das Punktepaar pippo.append(defined geometry)zu identifizieren, und dann PointsToLine, um meine Linie zu erhalten. Dies ist für Hunderte von Leitungen ziemlich zeitaufwändig.

Gibt es einen kürzeren Weg, dies zu tun?

Platzieren Sie beispielsweise den Start- und Endpunkt jeder Linie in verschiedenen Feldern einer einzelnen Tabelle und importieren Sie Linien direkt, ohne die Punktgeometrie zu übergeben.

Antworten:


8

Dies liest eine Tabelle (in diesem Fall eine Excel-Tabelle, kann aber ein beliebiger Tabellentyp sein), die folgendermaßen aussieht:

Geben Sie hier die Bildbeschreibung ein

S_X ist Start-X-Punkt, E_X-End-X-Punkt, dasselbe gilt für Ys. Wir durchlaufen die Eingabetabelle, setzen dann für jede Zeile die Start- / End-X / Ys in einen Punkt, fügen diesen Punkt einem Array hinzu und erstellen dann eine Polylinie aus dem Array von zwei Punkten. Dann in die Feature-Class einfügen. Spülen und wiederholen.

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

Und Sie bekommen Ihre Zeilen:

Geben Sie hier die Bildbeschreibung ein


Vielen Dank, ich werde versuchen, die Dauer meiner Analyse zu schätzen. Es war genau das, was ich versucht habe :-)
Annalisa Minelli

Für die Linie point.X = in_row.S_X wird ein Fehler zurückgegeben, der besagt, dass der Eingabewert nicht numerisch ist. Ich habe versucht, es int oder float oder sogar numerisch zu machen, aber es funktioniert nicht, weil das Feld keine Zahl vom Typ Nonetype ist. Irgendeine Hilfe?
Federico Gómez

5

Ich habe letzte Woche ein Python-Skript erstellt (allerdings ohne ArcPy), das Punkte verwendet, die die Geometrie von Buslinien (ein Punkt shp) gemäß einem fortlaufenden Nummernfeld ("SEQ") erstellen. Sie können es leicht anpassen, um die Koordinate aus einem Feld desselben Features zu übernehmen (unter Verwendung des Feldwerts anstelle der Geometrie).

# -*- 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"

Jedes Punktpaar erzeugt eine einzelne Linie. Es mag einen eleganteren Weg geben, dies zu tun, aber es wurden 3900 Zeilen in ungefähr 15 Sekunden erstellt, so dass es für mich funktioniert ...


Danke, sieht genauso aus wie eine massive Ausarbeitung. Das sollte mir wirklich nützlich sein. Ich werde versuchen und dann Feedback. danke fürs jetzt.
Annalisa Minelli

3

Sie können diese diese beiden Tools verwenden XY - Ereignis - Schicht und weist auf Linie , indem Sie die Paramater in Punkten (Linie Feld, sortieren Punkte) und Aktualisierung Eingangstabellendaten erforderlich zu sehen, könnte die Aufgabe einfacher sein


1

Dies ist nur eine Aktualisierung der Antwort von @ ChadCooper, da "da" -Cursor jetzt vorteilhafterweise die vorherigen Cursor ersetzen:

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]])
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.