Select to view content in your preferred language

# Aligning random Address Points to a straight line.

572
1
07-19-2023 11:42 AM
New Contributor

I have a bunch of address points that all over the place and not in a line.    I want to be able to clean these up and put them in a straight line.     I want to be able to highlight the address points I want to straighten and snap them to a line or just put them in a straight line.

Things I have tried -

I have snaping them to a street line then moving them.  But that will not keep them evenly separated.

I have tried using the Disperse tool, but some address points are to far out of the search area when setting minimum spacing.

I have tried the Align Features tool, but that doesn't seem to work.

Suggestions?

MVP Frequent Contributor

Here's one way to do it:

• Copy/paste the script into your ArcGIS Pro Python Window and execute. This will define a function 'straighten_points'.
import numpy

def straighten_points(layer, fit_degree=1):
"""Snaps all (selected) points in a layer to a regression line. This edits the input layer!

layer: layer name (str) or layer object (arcpy.mp.Layer)
fit_degree (int): degree of the polynomal fit, defaults to 1 (linear regression)
"""
sr = arcpy.Describe(layer).spatialReference
# extract point coordinates
points = [r[0].firstPoint for r in arcpy.da.SearchCursor(layer, ["SHAPE@"])]
x = [p.X for p in points]
y = [p.Y for p in points]
# polynomial fit
coef = numpy.polyfit(x, y, fit_degree)
polynom = numpy.poly1d(coef)
# construct fit line geometry
fit_xy = [
[x_, polynom(x_)]
for x_ in numpy.linspace(min(x) - 1000, max(x) + 1000, 100)
]
fit_points = [arcpy.Point(fx, fy) for fx, fy in fit_xy]
line = arcpy.Polyline(arcpy.Array(fit_points), spatial_reference=sr)
# snap points to regression line geometry and update layer
with arcpy.da.UpdateCursor(layer, ["SHAPE@"]) as cursor:
for  p, in cursor:
new_p = line.snapToLine(p)
cursor.updateRow([new_p])

• Select the points you want to straighten

• Run the function. Using 1 does a linear regression, which should be fine for straight road segments. For curves, you could try 2 or higher degrees, but remember that using this function will edit the layer, so make a backup.
straighten_points("NameOfYourLayer", 1)

Before: