Linear reference should do the job, but can be bulky. This is why I am using this script:
# Import arcpy module
import arcpy, os, traceback, sys,time
from arcpy import env
env.overwriteOutput = True
infc = arcpy.GetParameterAsText(0)
routeid = arcpy.GetParameterAsText(1)
outfc=arcpy.GetParameterAsText(2)
fields = [f for f in arcpy.ListFields(infc)]
fieldNames = [f.name for f in arcpy.ListFields(infc)]
# define number of lines
result=arcpy.GetCount_management(infc)
nF=int(result.getOutput(0))
d=arcpy.Describe(outfc)
SR_p=d.spatialReference
d=arcpy.Describe(infc)
SR=d.spatialReference
if SR_p.name<>SR.name:
arcpy.AddError("\nDifferent projections. Quit\n")
raise SystemExit('Quit...')
## initial point layer clean-up
fieldsP = [f for f in arcpy.ListFields(outfc)]
fieldNamesP = [f.name for f in arcpy.ListFields(outfc)]
dToLine,dAlong="D_TO_LINE","D_ALONG"
for ent in [routeid,dToLine,dAlong]:
if ent in fieldNamesP:
arcpy.DeleteField_management(outfc, ent)
outFolder, theFile="in_memory","intLines"
env.workspace = outFolder
try:
def showPyMessage():
arcpy.AddMessage(str(time.ctime()) + " - " + message)
def CalcChainage():
pC,lineID,dToLine,Chainage=theRow
shp=dictFeatures[lineID]
theRow[2]=pC.distanceTo(shp)
theRow[3]=shp.measureOnLine(pC)
return
with arcpy.da.SearchCursor(infc, ("SHAPE@",routeid)) as rows:
dictFeatures = {}
for feat,theID in rows:
dictFeatures[theID]=(feat)
del rows
arcpy.SpatialJoin_analysis(outfc, infc, "theJoin", "JOIN_ONE_TO_ONE", "KEEP_ALL", "", "CLOSEST","",dToLine)
arcpy.AddField_management("theJoin", dAlong, "DOUBLE")
## calculate chainage
result=arcpy.GetCount_management("theJoin")
nF=int(result.getOutput(0))
arcpy.AddMessage("\nComputing chainage...")
arcpy.SetProgressor("step", "", 0, nF,1)
with arcpy.da.UpdateCursor("theJoin", ("SHAPE@",routeid,dToLine,dAlong)) as rows:
for theRow in rows:
CalcChainage()
rows.updateRow(theRow)
arcpy.SetProgressorPosition()
del rows
##defining the type of route id field
n=fieldNames.index(routeid)
fType=fields[n].type
fLength=fields[n].length
try:
if fType=="String":
arcpy.AddField_management(outfc, routeid, "TEXT","","",fLength)
if fType=="Integer":
arcpy.AddField_management(outfc, routeid, "LONG")
if fType=="SmallInteger":
arcpy.AddField_management(outfc, routeid, "SHORT")
except: pass
try:
arcpy.AddField_management(outfc, dToLine, "DOUBLE")
arcpy.AddField_management(outfc, dAlong, "DOUBLE")
except: pass
arcpy.AddMessage("Transferring calcs to points...\n")
vFT=arcpy.da.TableToNumPyArray("theJoin",(routeid,dToLine,dAlong))
arcpy.SetProgressor("step", "", 0, nF,1)
with arcpy.da.UpdateCursor(outfc,(routeid,dToLine,dAlong )) as rows:
n=0
for theRow in rows:
theRow=vFT[n]
rows.updateRow(theRow)
arcpy.SetProgressorPosition()
n+=1
del vFT, rows
except NameError, theMessage:
arcpy.AddMessage (theMessage)
except:
message = "\n*** PYTHON ERRORS *** "; showPyMessage()
message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
message = "Python Error Info: " + str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()
Script expects these parameters:
To get this:
Perhaps you'd like to merge (dissolve) your polylines into single line. Make sure it won't create multipart shape, i.e. ends of segments must be snapped.
Script tested on shapefiles.
Best Answer
Have you followed the instructions in the tool's help file? If the tool is grayed out, then you probably have not taken the first two critical steps.
First, you must start an edit session. If your new points should be in the same database/file, then Editor > Start Editing will suffice. Otherwise you need to create a new database/file to hold your new points, start editing, and select the appropriate file.
Second, you must hit the Create Feature button (9 to the right of the DD tool, pencil/checklist icon), then click on your point feature in the box that appears.
Once you are both in an edit session and actively creating features, the construction tools will become available. You can refer to the help file linked above for specifics on how to enter a precise direction and distance with the tool.