This is a process that is best done through automation, and an advanced license helps. The basic work flow:
Divide your lines up for by their categories. For each category:
- Select lines within desired line distance of points, such as A = 400
- Dissolve selection with multipart
- Split your selected dissolve line by your points (Advanced license needed)
- Select split lines intersecting points
- Switch your selection and delete features - they don't touch your points
- Feature Vertices to Points - both ends - your remaining dissolved lines. You'll be finding their end points to determine if they need to be flipped. Each line in your dissolved line feature class needs to start at the intersect point (Advanced license needed)
- use and search cursor and geometry objects on your dissolved line feature class to determine which line features don't have their start point intersecting your intersection point feature class. These will need to be flipped with Flip Line (Standard license needed)
- Create a new line feature class. Iterate through your dissolve line feature class with a search cursor. insert new features using polyline geometry objects and
segmentAlongLine
.
Here's an example with an input line feature class, an input intersect point feature class, a distance in meters, and an output feature class:
#input point intersections feature class
inPnts = r"C:\Users\E1B8\Desktop\E1B8\Workspace\Workspace.gdb\TestPoints"
#input line feature class
inLines = r"C:\Users\E1B8\Desktop\E1B8\Workspace\Workspace.gdb\TestLines"
#distance of line from intersection in meters
distMeters = 100
#output line feature class
outFc = r"C:\Users\E1B8\Desktop\E1B8\Workspace\Workspace.gdb\OutFc"
print "importing"
import arcpy
import os
def ClipLinesByPointAndDistance (inPnts, inLines, distMeters, outFc):
print ("getting scratch workspace")
workspace = arcpy.env.scratchGDB
garbage = []
try:
print ("creating line layer")
lnLyr = "linLyr"
i = 0
while arcpy.Exists (lnLyr):
lnLyr = "linLyr{}".format (i)
i += 1
lnLyr = arcpy.MakeFeatureLayer_management (inLines, lnLyr) [0]
garbage += [lnLyr]
print ("selecting lines within {} meters of points".format (distMeters))
sel = arcpy.SelectLayerByLocation_management (lnLyr, "", inPnts,
"{} meters".format (distMeters))
print ("{} features selected".format (arcpy.GetCount_management (lnLyr) [0]))
print ("dissolving lines")
disFc = arcpy.CreateUniqueName ("dis", workspace)
disFc = arcpy.Dissolve_management (lnLyr, disFc) [0]
garbage += [disFc]
print ("splitting lines at points")
spLnFc = arcpy.CreateUniqueName ("spLn", workspace)
spLnFc = arcpy.SplitLineAtPoint_management (disFc, inPnts,
spLnFc, "1 feet") [0]
print ("creating split lines layer")
spLyr = "spLyr"
i = 0
while arcpy.Exists (spLyr):
spLyr = "spLyr{}".format (i)
i += 1
spLyr = arcpy.MakeFeatureLayer_management (spLnFc, spLyr) [0]
garbage += [spLyr]
print ("selecting lines by points")
sel = arcpy.SelectLayerByLocation_management (spLyr, "", inPnts,
"1 feet")
print ("{} features selected".format (arcpy.GetCount_management (spLyr) [0]))
print ("switching selection")
arcpy.SelectLayerByAttribute_management(spLyr, "SWITCH_SELECTION")
if arcpy.Describe (spLyr).FIDSet:
print ("deleting rows")
with arcpy.da.UpdateCursor (spLyr, "*") as curs:
for row in curs: curs.deleteRow ()
print ("clearning selection")
arcpy.SelectLayerByAttribute_management(spLyr, "CLEAR_SELECTION")
print ("line vertices to points")
l2pFc = arcpy.CreateUniqueName ("l2p", workspace)
arcpy.FeatureVerticesToPoints_management (spLyr, l2pFc, "BOTH_ENDS")
garbage += [l2pFc]
print ("creating line to point layer")
l2pLyr = "l2pLyr"
i = 0
while arcpy.Exists (l2pLyr):
l2pLyr = "l2pLyr{}".format (i)
i += 1
l2pLyr = arcpy.MakeFeatureLayer_management (l2pFc, l2pLyr) [0]
garbage += [l2pLyr]
print ("selecting vertices intersecting points")
sel = arcpy.SelectLayerByLocation_management (l2pLyr, "", inPnts,
"1 feet")
print ("{} features selected".format (arcpy.GetCount_management (l2pLyr) [0]))
print ("switching selection")
arcpy.SelectLayerByAttribute_management(l2pLyr, "SWITCH_SELECTION")
print ("getting endpoints")
endPnts = set ()
with arcpy.da.SearchCursor (l2pLyr, "SHAPE@XY") as curs:
for xy, in curs: endPnts.add (xy)
print ("{} end points".format (len (endPnts)))
print ("getting spatial reference")
sr = arcpy.Describe (spLyr).spatialReference
print ("adding lines to new feature class")
oids = set ()
with arcpy.da.SearchCursor (spLyr, ["SHAPE@", "OID@"]) as curs:
for geom, oid in curs:
lastPnt = geom.lastPoint
if not (lastPnt.X, lastPnt.Y) in endPnts:
oids.add (oid)
if oids:
print ("selecting lines to flip")
sql = "{} in {}".format (arcpy.Describe (spLyr).OIDFieldName,
tuple (oids))
sel = arcpy.SelectLayerByAttribute_management (spLyr, "", sql)
print ("{} features selected".format (arcpy.GetCount_management (spLyr) [0]))
print ("flipping lines")
arcpy.FlipLine_edit (spLyr)
print ("clearning selection")
arcpy.SelectLayerByAttribute_management(spLyr, "CLEAR_SELECTION")
print ("creating output feature class")
outPath, outName = os.path.split (outFc)
outName = arcpy.ValidateTableName (outName, outPath)
outFc = arcpy.CreateUniqueName (outName, outPath)
outName = os.path.basename (outFc)
outFc = arcpy.CreateFeatureclass_management (outPath, outName, "POLYLINE",
spatial_reference = inLines) [0]
dist = sr.metersPerUnit * distMeters
with arcpy.da.InsertCursor (outFc, "SHAPE@") as iCurs:
with arcpy.da.SearchCursor (spLyr, "SHAPE@") as sCurs:
for geom, in sCurs:
row = (geom.segmentAlongLine (0, dist),)
iCurs.insertRow (row)
print ("cleaning up")
for trash in garbage:
arcpy.Delete_management (trash)
print ("created:")
print (outFc)
except Exception as e:
print ("error!")
print ("cleaning up")
for trash in garbage:
arcpy.Delete_management (trash)
raise e
ClipLinesByPointAndDistance (inPnts, inLines, distMeters, outFc)
Results:

The rest of the process involves buffering and dissolving line outputs.