12

I've got some points pair coordinates (start and end points) which I have to transform into lines. Until now, I used an append of both the coordinates in a pippo.Point(), a pippo.CalculateGeometry() to define the geometry of each piont, and pippo.append(defined geometry) to identify the pair of points, and then PointsToLine to obtain my line. This is quite time expensive to do for hundreds of lines.

Is there a shorter way to do this?

For example, place starting and ending point of each line in different fields of a single table and import lines directly without passing for points geometry.

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Oct 1, 2012 at 13:20

4 Answers 4

9

This reads a table (Excel sheet in this case, but could be any table type) that looks like so:

enter image description here

S_X is start X point, E_X end X point, same for Y's. We iterate through the input table, then for each row, set the start/end X/Ys into a point, add that point to an array, then create a polyline from the array of two points. Then insert into the featureclass. Rinse and repeat.

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

And you get your lines:

enter image description here

answered Oct 1, 2012 at 14:19
2
  • Thank you, I'll try and estimate duration of my analysis.. it was exactly what I was trying to do :-) Commented Oct 1, 2012 at 15:09
  • For the line point.X = in_row.S_X it returns an error saying that the input value is not numeric. I tried to make it int or float or even numeric but doesnt work because field is not a number is Nonetype. Any help? Commented Feb 21, 2019 at 15:31
5

I created a python script last week (not using ArcPy though), that takes points that are creating the geometry of bus lines (a point shp) according a sequential number field ("SEQ"). You could easily tweak it to take the coordinate from a field of the same feature (using field value instead of geometry).

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

Each pair of point will create a single line. There may be a more elegant way to do this, but it created 3900 lines in about 15 seconds so it works for me...

answered Oct 1, 2012 at 14:02
1
  • Thanks, looks exactly like massive elaboration.. that should be really useful to me. I'll try and then feedback. thanks for now. Commented Oct 1, 2012 at 15:08
3

you can use these these two tools make XY event layer and Points to line, by seeing the paramaters needed in points to line ( line field , sort points) and update input table data, the task could be simpler

answered Oct 1, 2012 at 13:32
2

this is just an update of @ChadCooper's answer, because "da" cursors are now advantageously replacing the previous cursors:

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]])
answered Sep 24, 2019 at 6:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.