Czy tworzysz linie ze współrzędnych punktów parujących z ArcPy?


11

Mam współrzędne pary punktów (punkty początkowe i końcowe), które muszę przekształcić w linie. Do tej pory użyłem dodatku obu współrzędnych w a pippo.Point(), a, pippo.CalculateGeometry()aby zdefiniować geometrię każdego pionu i pippo.append(defined geometry)zidentyfikować parę punktów, a następnie PointsToLine w celu uzyskania mojej linii. Jest to dość kosztowne w przypadku setek linii.

Czy jest na to krótszy sposób?

Na przykład umieść punkt początkowy i końcowy każdej linii w różnych polach pojedynczej tabeli i importuj linie bezpośrednio, nie przechodząc do geometrii punktów.

Odpowiedzi:


8

Odczytuje tabelę (w tym przypadku arkusz Excela, ale może to być dowolny typ tabeli), który wygląda tak:

wprowadź opis zdjęcia tutaj

S_X jest początkowym punktem X, E_X końcowym punktem X, to samo dla Y. Iterujemy przez tabelę wejściową, a następnie dla każdego wiersza ustawiamy początkowy / końcowy X / Y w punkcie, dodajemy ten punkt do tablicy, a następnie tworzymy polilinię z tablicy dwóch punktów. Następnie wstaw do klasy obiektów. Wypłukać i powtórzyć.

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

I dostajesz swoje linie:

wprowadź opis zdjęcia tutaj


Dziękuję, postaram się oszacować czas trwania mojej analizy. Dokładnie to starałem się zrobić :-)
Annalisa Minelli,

Dla punktu linii.X = in_row.S_X zwraca błąd informujący, że wartość wejściowa nie jest liczbą. Próbowałem ustawić go jako int, float, a nawet numeryczny, ale nie działa, ponieważ pole nie jest liczbą to Nonetype. Jakaś pomoc?
Federico Gómez

5

W zeszłym tygodniu utworzyłem skrypt Pythona (jednak nie korzystam z ArcPy), który pobiera punkty tworzące geometrię linii magistrali (punkt shp) zgodnie z polem numeru sekwencyjnego („SEQ”). Można go łatwo dostosować, aby pobrać współrzędną z pola o tej samej operacji (używając wartości pola zamiast geometrii).

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

Każda para punktów utworzy jedną linię. Może to być bardziej elegancki sposób, ale stworzył 3900 linii w około 15 sekund, więc działa dla mnie ...


Dzięki, wygląda dokładnie jak ogromne opracowanie ... które powinno być dla mnie naprawdę przydatne. Spróbuję, a następnie opinie. dzięki za teraz.
Annalisa Minelli,


1

to tylko aktualizacja odpowiedzi @ ChadCooper, ponieważ kursory „da” zastępują teraz poprzednie kursory:

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]])
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.