# Adding vertex to line at point location using ArcPy?

I have a `line` layer and `point` layer on my ArcGIS project. The points are on the lines. I want to create vertex on lines at this point coordinates.

``````import arcpy

point_rows = arcpy.da.SearchCursor("D:\Test.gdb\MyPoints", ['OID@', 'SHAPE'])

rows = arcpy.UpdateCursor("D:\Test.gdb\MyLines")

for row in rows:
geom = row.SHAPE
for part in geom.getPart():
for pnt in point_rows:
row.X = pnt.X
row.Y = pnt.Y
rows.updateRow(row)
``````

I could not add vertex on points, if point is on the line. How can I do this using arcpy?

• Related 1: gis.stackexchange.com/questions/250263/… Commented Aug 2, 2018 at 9:24
• Related 2: gis.stackexchange.com/questions/81777/… Commented Aug 2, 2018 at 9:25
• Can you clarify the what your data really consists of? You say The points are on the lines. Are you saying you have multiple points on a single line or each line has a corresponding single point? If they are single points, do their row order correspond to the row order of the polyline? Do these points ever occur at the ends? Are these polylines joined at their ends such as in a road network? Do they overlap? Looking at the suggested code below people are making assumptions (not unreasonable) about the row order relationship. You need to describe your data if you want a robust solution. Commented Aug 3, 2018 at 14:30
• What should I do when someone answers my question?
– Bera
Commented Nov 8, 2023 at 13:22

Below is some python code that will take an un-ordered set of polylines with zero or more intersecting points and insert a vertex into the polyline at the point position.

Sample data

This code is designed to be dropped into the Python console in ArcMap, simply change `lineLayer` and `pointLayer`.

``````import arcpy

# Layers in MXD
lineLayer = "fcLine"
pointLayer = "fcPoint"

with arcpy.da.UpdateCursor(lineLayer,['SHAPE@']) as lineCursor:
for row in lineCursor:
geom = row[0]

# Get selected points along line, this could be zero, 1 or more
arcpy.SelectLayerByLocation_management(pointLayer,"INTERSECT",geom,"#","NEW_SELECTION")
res = arcpy.GetCount_management(pointLayer)
n = int(res.getOutput(0))
if n > 0:
# We have at least 1 point intersecting line
# Store selected point(s) in list for further processing
pointList = []
with arcpy.da.SearchCursor(pointLayer,['SHAPE@']) as pointCursor:
for pointRow in pointCursor:
pointList.append(pointRow[0])
print(str(len(pointList)) + " intersect current line.")

# Convert polyline to points
# Assumes line is simple geometry, i,e a single part
lineArr = geom.getPart(0) # Returns an array
for p in lineArr:
pointList.append(arcpy.PointGeometry(p))

# PointList is a list of PointGeometries composed of points on the line and points from the line itself
# Now need to work out position of points along the line
posDict = {}
for p in pointList:
pos = geom.measureOnLine(p,True)
posDict[pos] = p

# Reconstruct polyline by using sorted keys in posDict
newArray = arcpy.Array()
for key in sorted(posDict.iterkeys()):
newArray.add(posDict[key].centroid) # Array takes points not PointGeometry, hence using centroid property
newLine = arcpy.Polyline(newArray)

# Insert updated geometry line back into dataset
row[0] = newLine
lineCursor.updateRow(row)
``````
• Thanks, your script worked as expected. Is there anyway to improve performance? It took about 5 minutes to add a point to 1100 lines. Commented Nov 29, 2018 at 16:43
• @GreyHippo Don't think so, it's already using the faster cursor type and the logic excludes lines that do not have any intersecting points. You could try moving the layers into an IN_MEMORY workspace to see if performance is improved or if your source datasets are shapefiles make sure they have a spatial index. Commented Nov 29, 2018 at 16:57
• Also after I run the command it takes a long time to save the MXD. Would your script cause something like that Commented Nov 29, 2018 at 18:11
• If you perform this script on a 10 lines the MXD saves normally but if I perform the script on 200 lines then it takes a few minutes to save the MXD. Commented Nov 29, 2018 at 18:35
• I just checked the MXD filesize and it is 64 mb after doing the script on 200 lines Commented Nov 29, 2018 at 18:36

I think I have a solution! I ve checked the following code and it works.

1) This example creates a Point Feature of the Vertices of your line with the help of Numpy Arrays (Numpy Needs to be installed)

2) Then it merges These Vertices as Points together with your 'points' on the line -> Theres one drawback: On the Output Pointfile of this merge you Need to create a new field and sort the Points in the right order (1-9 in this example) Otherwise the final line would look like a 'grinding by numbers' (but Ive found also examples to automate this too..

3) Finally a new line is created including the original line and the Points on the line

Feel free to ask me, in case you've got questions or some parts of the code dont work on your system

``````import arcpy, numpy, os

sr = arcpy.SpatialReference(25832)

### The Input: Your Points on the line (PointsLTW) // The line feature itself (InFcLine)

PointsLTW = r"C:\lineVerts\PointsLTW.shp"
InFcLine  = r"C:\\lineVerts\LineLTW.shp" # input feature class

OutFcLine = r"C:\lineVerts\LineLTW_out2.shp" # output feature class

print "Inputs accepted.."

# Creates a Point Array of your Line

arrayLine = arcpy.da.FeatureClassToNumPyArray(InFcLine,["SHAPE@XY"], "", sr, explode_to_points=True)

print "Numpy Array created.."

# ..in case no Array was created

if arrayLine.size == 0:
arcpy.AddError(InFcLine + " contains no features!")

# From Array to Point Feature of your Input Line
else:
arcpy.da.NumPyArrayToFeatureClass(arrayLine, OutFcLine, ['SHAPE@XY'], sr)
print "New Multipoint Feature (LineToVertPoints) from Numpy Array.."

# Now you just merge your original PointsLTW with your original Line, now written as a Point Feature out of the lines Vertices

arcpy.Merge_management(inputs="PointsLTW;LineLTW_out2",output="C:/lineVerts/FinalPointsxx.shp",field_mappings="""Id "Id" true true false 6 Long 0 6 ,First,#,PointsLTW,Id,-1,-1,LineLTW_out2,Id,-1,-1""")

# Finally you create a line out of the merged points, the only drawback is that you need the Points to be sorted after the line Direction (From East to West or VV), I did this with a new field sorting the points by hand

arcpy.PointsToLine_management(r"C:/lineVerts/FinalPointsxx.shp" , r"D:\FinalLinexx.shp", "","sortedLTW")
``````

As the easiest way (not too much coding, but questionable performance) you might try to do this (ArcGIS Desktop Advanced license required):

1. Use Split Line at Point tool to split the lines.
2. Use Unsplit Line tool to merge the lines back.

As described in the description of the tool:

If Search Radius (search_radius in Python) is unspecified, the nearest point will be used to split the line feature. If a Search Radius is specified, all points within the search radius are used to split the line.

So by default `Split Line at Point` only works for ONE point per line. Other points on the line are ignored. But if you set huge `Search Radius` all points will split the line.

________Before_____________________ Splitted_____________________ UNsplitted

_________ _________

This code should do the job (not tested):

``````import arcpy

points = r"D:\Test.gdb\MyPoints"
lines = r"D:\Test.gdb\MyLines"
splitted = r"D:\Test.gdb\MySplittedLines"
unsplitted = r"D:\Test.gdb\MyUnSplittedLines"

arcpy.UnsplitLine_management(splitted, unsplitted)
``````
• But Split and Unsplit does not create verticies on line. Commented Aug 2, 2018 at 10:58
• aplit and unsplid operations recreates objects and changes the objectid's Commented Aug 2, 2018 at 14:16
• @barteloma You can copy ID's to a new field before the operation. Commented Aug 3, 2018 at 4:09
• I have an error: 'The tool is not licensed. Failed to execute' So I need using update. Commented Aug 3, 2018 at 5:41

I think you had your geometry token for your points wrong. It should have come as "Shape@".

The code can be written as :

``````    Import arcpy
# Setting path
arcpy.env.workspace = "path"
# This line of code returns x, and y as tuple.
with arcpy.da.searchCursor("Feature/Table",['OID@','Shape@']) as /
point_cursor
for row in point_cursor:
pnt.X,pnt.Y = row[1]
print('{},{}'.format(pnt.X,pnt.Y))
## The first code reads the x,y of the point layer
### The next code is to write the point x,y on the line
with arcpy.InsertCursor('Feature/Table',"Shape@") as line_cursor
array = arcpy.array([pnt.X,pnt.Y])
Line_ = arcpy.polyline(array)
line_cursor.insertRow([Line_])
``````
• This code appears not to insert the point into the line, in fact as I read it, it INSERTS not UPDATES a polyline and actually fails by inserting a line consisting of 1 vertex which makes no sense. Commented Aug 3, 2018 at 15:55
• You answer has multiple syntax errors
– Bera
Commented Nov 8, 2023 at 13:24