StationOffset tool

StationOffset tool

ebo134
Advocate Advocate
2,754 Views
11 Replies
Message 1 of 12

StationOffset tool

ebo134
Advocate
Advocate

Hi, everyone

I want to use in my plugin StationOffset marker like the Autocad Civil 3D command (CREATEPOINTSTATIONOFFSET)

in c#

anyone can help?

and here is an image of it:

0 Likes
Accepted solutions (2)
2,755 Views
11 Replies
Replies (11)
Message 2 of 12

Anonymous
Not applicable

Hi ebo134,  

 

I am not very clear about your need.

Did you check the following .NET API ?

 

Alignment.PointLocation Method (Double, Double, Double, Double) -> Returns the easting and northing of a point on an Alignment given a station and an offset for the Alignment.

 

Alignment.StationOffset Method (Double, Double, Double, Double) -> Returns the station and offset on an Alignment at given easting and northing values.

 

Thanks,

0 Likes
Message 3 of 12

ebo134
Advocate
Advocate

what I need to do is :

when the user is prompted to select an alignment , a red marker with a line is attached to the selected alignment for specifying the station and offset as its clear in the attached picture,I need to know how to use this technique(red marker)

in my code when user be prompted to select an alignment and specifying a station with offset.

 

thanks

0 Likes
Message 4 of 12

Jeff_M
Consultant
Consultant

You can create your own using PointMonitor and TransientGraphics. 

Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 5 of 12

ebo134
Advocate
Advocate

thank you jeff

but can you show me a sample code (c sharp) of this.

 

 

 

thanks

 

0 Likes
Message 6 of 12

Jeff_M
Consultant
Consultant
Accepted solution

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();
        }
    }
}

 

Jeff_M, also a frequent Swamper
EESignature
Message 7 of 12

ebo134
Advocate
Advocate
Accepted solution

Thank you So much.

0 Likes
Message 8 of 12

quangpt.tric
Advocate
Advocate

Hi @Jeff_M ,

how can I make it in Profileview?

0 Likes
Message 9 of 12

Jeff_M
Consultant
Consultant

@quangpt.tric pretty much the same way, just select a ProfileView instead of an alignment, use the ProfileView's FindStationAndElevationAtXY method

Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 10 of 12

quangpt.tric
Advocate
Advocate

Hi @Jeff_M , thank you for reply me.

Here is the code I make but it not success.

 private static void StaOffPointMonitor1(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();
            double station = 0;
            double ele = 0;
            profileView_0.FindStationAndElevationAtXY(curPt.X, curPt.Y,ref station,ref ele);
            pt2 = new Point3d(profileView_0.StartPoint.X + station, profileView_0.StartPoint.Y, profileView_0.StartPoint.Z);
            showLine_and_X(curPt, pt2, scale);
        }

Can you show me what I am wrong? 

Thank you!

0 Likes
Message 11 of 12

Jeff_M
Consultant
Consultant
Ok, I'm guessing you want to track the station/elevation on a Profile in the ProfileView? That is a bit more complicated. The gist of it is: Select the Profile, get the Alignment from it, check the ProfileViews property, if more than one, determine which one the cursor is in, get the station of the cursor location, get the elevation from the profile at that station, get the use the ProfileView's FindXYAtStationAndElevation method, and that will give you the pt2 XY.
Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 12 of 12

Jeff_M
Consultant
Consultant

@quangpt.tric Here is working code to track the station/elevation of a profile on the first ProfileView for an alignment. You will want to add some error traps for when the cursor moves out of the ProfileView extents.

        Profile prof;
        ProfileView pview;

        [CommandMethod("jmmStaElevTest")]
        public void staelevtestcommand()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            ed = doc.Editor;
            Database db = doc.Database;
            CivilDocument civdoc = CivilApplication.ActiveDocument;
            PromptEntityOptions entOpts = new PromptEntityOptions("Select profile:");
            entOpts.SetRejectMessage("...not a Profile object, try again.");
            entOpts.AddAllowedClass(typeof(Profile), true);
            PromptEntityResult entRes = ed.GetEntity(entOpts);
            if (entRes.Status != PromptStatus.OK)
                return;
            using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
            {
                prof = (Profile)entRes.ObjectId.GetObject(OpenMode.ForRead);
                align = (Alignment)prof.AlignmentId.GetObject(OpenMode.ForRead);
                pview = (ProfileView)align.GetProfileViewIds()[0].GetObject(OpenMode.ForRead);
                var intxPts = new Point3dCollection();
                //align.IntersectWith(align2, Intersect.ExtendArgument, intxPts, IntPtr.Zero, IntPtr.Zero);
                var txttbl = (TextStyleTable)tr.GetObject(db.TextStyleTableId, OpenMode.ForRead);
                styleid = txttbl["Standard"];

                ed.PointMonitor += new PointMonitorEventHandler(StaElevPointMonitor);
                PromptPointOptions ptPrmpt = new PromptPointOptions("\nSelect point to get Station & Elev of:");
                ptPrmpt.AllowNone = true;
                PromptPointResult ptResult;
                while (true) //with the PointMonitor running it will update until user picks a point
                {
                    ptPrmpt.Message = "\nMove along profile to track the Station & Elev:";
                    ptResult = ed.GetPoint(ptPrmpt);
                    if (ptResult.Status != PromptStatus.Other)
                        break;
                }
                ed.PointMonitor -= new PointMonitorEventHandler(StaElevPointMonitor);
                ClearMarkers();
                tr.Commit();
                align = null;
            }
        }

        private void StaElevPointMonitor(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();
            
            double station = 0, elev = 0;
            double x = 0, y = 0;
            pview.FindStationAndElevationAtXY(curPt.X, curPt.Y, ref station, ref elev);
            elev = prof.ElevationAt(station);
            pview.FindXYAtStationAndElevation(station, elev, ref x, ref y);
            pt2 = new Point3d(x, y, 0);
            var stastring = align.GetStationStringWithEquations(station) + "  Elev: " + elev.ToString("F3") ;
            showLine_and_X(curPt, pt2, scale, stastring);
        }

Jeff_M, also a frequent Swamper
EESignature