Hi Daniel Walters,
I saw your question and thought, let's give it a try...
Based on this input:
Is creates this output:
Using this code:
import math
def main():
import arcpy
fc_in = r"D:\Xander\GeoNet\Nueva carpeta\test.gdb\lines"
fc_out = r"D:\Xander\GeoNet\Nueva carpeta\test.gdb\lines_out"
tolerance = 150 # max distance to snap to a node
# create dicts
dct_lines = getPolylineDict(fc_in)
dct_from, dct_to = getFromAndToNodes(dct_lines)
# loop through polylines
for oid, polyline in dct_lines.items():
# search candidates from point
pnt_from = dct_from[oid]
dist_min = tolerance + 0.01
pnt_found = None
for oid_from, pnt in dct_from.items():
if oid_from != oid:
dist = calcDistance(pnt_from, pnt)
if dist < dist_min:
dist_min = dist
pnt_found = arcpy.Point(pnt.X, pnt.Y)
for oid_to, pnt in dct_to.items():
if oid_to != oid:
dist = calcDistance(pnt_from, pnt)
if dist < dist_min:
dist_min = dist
pnt_found = arcpy.Point(pnt.X, pnt.Y)
# change line from point
if pnt_found != None:
polyline = insertPointAtStart(polyline, pnt_found)
dct_lines[oid] = polyline
dct_from, dct_to = getFromAndToNodes(dct_lines)
# search candidates to points
pnt_to = dct_to[oid]
dist_min = tolerance + 0.01
pnt_found = None
for oid_from, pnt in dct_from.items():
if oid_from != oid:
dist = calcDistance(pnt_to, pnt)
if dist < dist_min:
dist_min = dist
pnt_found = arcpy.Point(pnt.X, pnt.Y)
for oid_to, pnt in dct_to.items():
if oid_to != oid:
dist = calcDistance(pnt_to, pnt)
if dist < dist_min:
dist_min = dist
pnt_found = arcpy.Point(pnt.X, pnt.Y)
# change line end point
if pnt_found != None:
polyline = addPointAtEnd(polyline, pnt_found)
dct_lines[oid] = polyline
dct_from, dct_to = getFromAndToNodes(dct_lines)
# create list of polylines
lst_polylines = dct_lines.values()
arcpy.CopyFeatures_management(lst_polylines, fc_out)
def getPolylineDict(fc_in):
dct = {}
flds = ("OID@", "SHAPE@")
with arcpy.da.SearchCursor(fc_in, flds) as curs:
for row in curs:
dct[row[0]] = row[1]
del row, curs
return dct
def getFromAndToNodes(dct):
dct_from = {}
dct_to = {}
for oid, polyline in dct.items():
dct_from[oid] = polyline.firstPoint
dct_to[oid] = polyline.lastPoint
return dct_from, dct_to
def insertPointAtStart(polyline, pnt_found):
sr = polyline.spatialReference
lst_pnts = [pnt_found]
for part in polyline:
for pnt in part:
lst_pnts.append(pnt)
return arcpy.Polyline(arcpy.Array(lst_pnts), sr)
def addPointAtEnd(polyline, pnt_found):
sr = polyline.spatialReference
lst_pnts = []
for part in polyline:
for pnt in part:
lst_pnts.append(pnt)
lst_pnts.append(pnt_found)
return arcpy.Polyline(arcpy.Array(lst_pnts), sr)
def calcDistance(pnt_to, pnt):
return math.hypot(pnt_to.X - pnt.X, pnt_to.Y - pnt.Y)
if __name__ == '__main__':
main()
If you have any questions, just let me know...
Kind regards, Xander