Membuat garis dari koordinat pasangan poin dengan ArcPy?


11

Saya punya beberapa koordinat pasangan poin (titik awal dan akhir) yang harus saya ubah menjadi garis. Sampai sekarang, saya menggunakan append dari kedua koordinat dalam a pippo.Point(), a pippo.CalculateGeometry()untuk menentukan geometri setiap piont, dan pippo.append(defined geometry)untuk mengidentifikasi pasangan poin, dan kemudian PointsToLine untuk mendapatkan garis saya. Ini cukup mahal untuk dilakukan untuk ratusan baris.

Apakah ada cara yang lebih pendek untuk melakukan ini?

Misalnya, tempatkan titik awal dan akhir setiap baris dalam bidang yang berbeda dari satu tabel dan impor garis secara langsung tanpa melewati geometri poin.

Jawaban:


8

Ini membaca tabel (lembar Excel dalam kasus ini, tetapi bisa berupa tipe tabel apa pun) yang terlihat seperti ini:

masukkan deskripsi gambar di sini

S_X adalah titik awal X, titik akhir E_X, sama dengan Y. Kita beralih melalui tabel input, lalu untuk setiap baris, atur awal / akhir X / Ys menjadi sebuah titik, tambahkan titik itu ke array, lalu buat polyline dari array dua titik. Kemudian masukkan ke dalam FeatureClass. Bilas dan ulangi.

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

Dan Anda mendapatkan garis Anda:

masukkan deskripsi gambar di sini


Terima kasih, saya akan mencoba dan memperkirakan durasi analisis saya .. itu persis apa yang saya coba lakukan :-)
Annalisa Minelli

Untuk point line.X = in_row.S_X ia mengembalikan kesalahan yang mengatakan bahwa nilai input tidak numerik. Saya mencoba membuatnya int atau mengapung atau bahkan numerik tetapi tidak berfungsi karena bidang bukan angka bukan tipe. Ada bantuan?
Federico Gómez

5

Saya membuat skrip python minggu lalu (tidak menggunakan ArcPy), yang mengambil titik yang membuat geometri garis bus (titik shp) menurut bidang nomor urut ("SEQ"). Anda bisa dengan mudah mengubah itu untuk mengambil koordinat dari bidang fitur yang sama (menggunakan nilai bidang, bukan geometri).

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

Setiap pasangan titik akan membuat satu baris. Mungkin ada cara yang lebih elegan untuk melakukan ini, tetapi itu menciptakan 3900 baris dalam waktu sekitar 15 detik sehingga itu bekerja untuk saya ...


Terima kasih, terlihat persis seperti elaborasi besar .. yang seharusnya sangat berguna bagi saya. Saya akan mencoba umpan balik. terima kasih untuk sekarang.
Annalisa Minelli


1

ini hanya pembaruan dari jawaban @ ChadCooper, karena kursor "da" sekarang secara menguntungkan menggantikan kursor sebelumnya:

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]])
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.