Automating line adjustment to a point or a series of points in ArcGIS Suite?
I would approach this by reconstructing the line manually. Use a cursor to extract the start and end points from the line, sort the list of point coordinates by proximity to the start of the line, and reconstruct the new line geometry.
# assumes one line in in_line
in_line = r'\scratch.gdb\sample_line'
in_points = r'\scratch.gdb\sample_points'
# get line start and end points
with arcpy.da.SearchCursor(in_line, ["SHAPE@"]) as cur:
for row in cur:
geom = row[0]
point_first = geom.firstPoint
coord_first = [point_first.X, point_first.Y]
point_last = geom.lastPoint
coord_last = [point_last.X, point_last.Y]
# get point coords as list
with arcpy.da.SearchCursor(in_points, ["SHAPE@"]) as cur:
points = [[row[0].centroid.X, row[0].centroid.Y] for row in cur]
# define a function used to sort points based on proximity to point_first
def coord_dif(coord_x):
x_dif = abs(coord_first[0] - coord_x[0])
y_dif = abs(coord_first[1] - coord_x[1])
return (x_dif + y_dif)
# sort points
points = sorted(points, key=coord_dif)
all_points = [coord_first] + points + [coord_last]
# construct geometry
line_geom = arcpy.Polyline(
arcpy.Array(
[arcpy.Point(pt[0], pt[1]) for pt in all_points]
)
)
# update with new line goemetry
with arcpy.da.UpdateCursor(in_line, ["SHAPE@"]) as cur:
for row in cur:
cur.updateRow([line_geom])
Append end points of your lines to snap points and run near tool on appended set of points. Add field type "Double" to their table:
Rename original lines in table of content to "original" and use field calculator:
g = arcpy.Geometry()
geometryList=arcpy.CopyFeatures_management("original",g)
def getChainage(lineFID,point):
line=geometryList[lineFID]
return line.measureOnLine(point.firstPoint)
#------------
getChainage( !NEAR_FID!, !Shape! )
To populate new field in points table:
Points to line tool will do the rest:
arcpy.PointsToLine_management("points", "../SNAPPED.shp", "NEAR_FID", sort_Field="CHAINAGE")
Solution valid for shapefiles, it is a bit more complicated for other storage options. Note that you can use linear referencing to compute distances of points along original lines if you'd like to avoid field calculator used here.