Here ya go. This does not display the station and offset, I leave that to you...Hint, you will need to use a small form and display that form near where the cursor point is.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using aGi = Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil;
namespace Civil3D_Misc_Commands.AlignmentTools
{
public class StationOffsetDisplay
{
private IntegerCollection intColl = new IntegerCollection();
private DBObjectCollection m_mrkers = new DBObjectCollection();
private Editor ed;
private Point3d curPt;
private Alignment align = null;
[CommandMethod("StaOffTest")]
public void staoffcommand()
{
if (CivilApplication.ActiveDocument.GetAlignmentIds().Count > 0)
runcommand();
}
private void runcommand()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
ed = doc.Editor;
Database db = doc.Database;
CivilDocument civdoc = CivilApplication.ActiveDocument;
PromptEntityOptions entOpts = new PromptEntityOptions("Select alignment:");
entOpts.SetRejectMessage("...not an ALignment object, try again.");
entOpts.AddAllowedClass(typeof(Alignment), true);
PromptEntityResult entRes = ed.GetEntity(entOpts);
if (entRes.Status != PromptStatus.OK)
return;
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
align = (Alignment)entRes.ObjectId.GetObject(OpenMode.ForRead);
ed.PointMonitor += new PointMonitorEventHandler(StaOffPointMonitor);
PromptPointOptions ptPrmpt = new PromptPointOptions("\nSelect point to get Station & Offset of:");
ptPrmpt.AllowNone = true;
PromptPointResult ptResult;
while (true) //with the PointMonitor running it will update until user picks a point
{
ptPrmpt.Message = "\nMove along alignment to track the Station & Offset:";
ptResult = ed.GetPoint(ptPrmpt);
if (ptResult.Status != PromptStatus.Other)
break;
}
ed.PointMonitor -= new PointMonitorEventHandler(StaOffPointMonitor);
ClearMarkers();
tr.Commit();
}
}
private void StaOffPointMonitor(object sender, PointMonitorEventArgs e)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
curPt = e.Context.RawPoint;
double scale = 5; // This needs to have code to get it to scale up/down as the view is zoomed out/in
Point3d pt2 = new Point3d();
pt2 = align.GetClosestPointTo(curPt, false);
showLine_and_X(curPt, pt2, scale);
}
private void showLine_and_X(Point3d curPt, Point3d pt3, double scale)
{
ClearMarkers();
Line line1 = new Line(curPt, pt3);
Line line2 = new Line(Utility.PolarPoint(pt3, line1.Angle + (Math.PI * 0.25), 0.15 * scale), Utility.PolarPoint(pt3, line1.Angle + (Math.PI * 1.25), 0.15 * scale));
Line line3 = new Line();
line3.StartPoint = line2.StartPoint;
line3.EndPoint = line2.EndPoint;
line3.TransformBy(Matrix3d.Rotation(Math.PI * 0.5, Vector3d.ZAxis, pt3));
line1.ColorIndex = 1;
line2.ColorIndex = 3;
line3.ColorIndex = 3;
aGi.TransientManager.CurrentTransientManager.AddTransient(line1, aGi.TransientDrawingMode.DirectShortTerm, 128, intColl);
aGi.TransientManager.CurrentTransientManager.AddTransient(line2, aGi.TransientDrawingMode.DirectShortTerm, 128, intColl);
aGi.TransientManager.CurrentTransientManager.AddTransient(line3, aGi.TransientDrawingMode.DirectShortTerm, 128, intColl);
m_mrkers.Add(line1);
m_mrkers.Add(line2);
m_mrkers.Add(line3);
}
private void ClearMarkers()
{
for (int i = 0; i < m_mrkers.Count; i++)
{
aGi.TransientManager.CurrentTransientManager.EraseTransient(m_mrkers[i], intColl);
m_mrkers[i].Dispose();
}
m_mrkers.Clear();
}
}
}