Code Red > .NET

CIVIL 3D - Get profile full contour elevation into plan view

(1/2) > >>

jcoon:
All,

I'm looking at the possibility of doing a utility to place civil points in plan view at station & increment along my alignment. Based on a profile full contour elevation. I'm not sure how I'll do it this, so, I thought check here to see if this make sense. The reason I'm looking at this, was to help our junior  engineers / interns learn hand site grading faster, I thought placing the a full contour location along the alignment might make this go faster. I thought about just using a demo corridor along the profile and then extracting the cl crown points, but that just places the profile elevation at station, where I wanted the full contour elevation location on the alignment. what I found was, many of the interns and junior engineers have never done hand grading, So, how are they going to know if something look right or wrong when they are building a model in C3D until they are done. How do you learn to warp flat grading.

getting started, I'll need to select an alignment, then pick a profile to retrieve the elevations from. The big question for me would be how  would I sample the elevations to find that full contour. would I try querying profile at some increment? or would it be better to try some kind of profile grid intersection with the profile and get the station value for the civil point at align station x,y location point from that intersection. Is there anything in C3D that can do this that I'm not aware of. I thought about the profile report tools, but couldn't find a way to export full contour elevations.

Thanks for any ideas

John





Jeff_M:
Hi John, by 'full contour' do you mean you want elevations at all locations a minor/major contour would cross if there were a surface?

Also, do your profiles have vertical Curves? If so, are they typically Circular, ParabolicSymetric, or ParabolicAsymetric?

jcoon:
Hi Jeff,

Good to see he here. Your always a great help. Yes, I'm looking for the minor/major contour locations along the alignment. As for profiles, they will be circular vertical curves. Last night I was thinking that a design profile and profile grid intersection might be the place to start. Could I or should I explode the design profile and do a polyline intersection with the grid and then see if I can then get the station and elevation value from those locations, then I'd write the points at station offset along the alignment. I know I could just insert the demo corridor contours along the alignment and just pick the locations and insert a point at those locations. But if it's not too difficult I thought I try a simple utility to do that for me.

Does the polyline intersection direction sound plausible.

Thanks
John

Jeff_M:
Exploding a profile results in a block, exploding the block results in line segments, not a polyline. While this method could work, it would be best to calculate the locations of the specific elevations. I have part of a solution that I started a while back, but it only handles tangents. I haven't been able to find/create a formula to calculate the location of a specific elevation on a vertical curve...those I have tried only return a single value, but crest/sag curves could have the same elevation at 2 locations. I can share what I have if you'd like.

Jeff_M:
I had some time to do more research and testing today John. The following code does what you need...mostly. The points on a circular curve may be slightly off, as I didn't find much in my searches for that type of VC. So I used the same formula for locating the elevation on those as I do for the parabolic curves. And, if you happen to have any asymmetric curves, those are skipped altogether...I've only used these twice in the 40 years I've been designing things, so really don't feel like researching those  ;-)

Here's a pic I took after running the command and then Projecting the points to the ProfileView:



--- Code - C#: ---//Tool to place Cogo Points along an Alignment at a Profile's even number elevations (120, 121, 122, 123, etc)// by Jeff Mishler @ Quux Software// Feb. 18, 2017 Provided as an example of how to get specific elevations of a profile.// May be freely used and/or modified, providing this header stays intactusing Autodesk.AutoCAD.ApplicationServices;using Autodesk.AutoCAD.DatabaseServices;using Autodesk.AutoCAD.EditorInput;using Autodesk.AutoCAD.Geometry;using Autodesk.AutoCAD.Runtime;using Autodesk.Civil.ApplicationServices;using Autodesk.Civil.DatabaseServices;using System;using System.Collections.Generic;using System.Linq;  namespace Civil3D_Misc_Commands.Profiles{    public static class ProfileTools    {        [CommandMethod("ProfileLevels")]        public static void profilelvelscommand()        {            Document doc = Application.DocumentManager.MdiActiveDocument;            Editor ed = doc.Editor;            Database db = doc.Database;            CivilDocument civdoc = CivilApplication.ActiveDocument;            PromptEntityOptions entOpts = new PromptEntityOptions("Select Profile:");            entOpts.SetRejectMessage("...not a Profile, try again.");            entOpts.AddAllowedClass(typeof(Profile), true);            PromptEntityResult entRes = ed.GetEntity(entOpts);            if (entRes.Status != PromptStatus.OK)                return;            using (Transaction tr = db.TransactionManager.StartTransaction())            {                var prof = (Profile)tr.GetObject(entRes.ObjectId, OpenMode.ForRead);                var minElev = Math.Floor(prof.ElevationMin) + 1;                var maxElev = Math.Floor(prof.ElevationMax);                var profEnts = prof.Entities;                var output = new List<ProfileStationElevation>();                for (double elev = minElev; elev <= maxElev; elev++)                {                    foreach (ProfileEntity ent in profEnts)                    {                        var e1 = ent.StartElevation;                        var e2 = ent.EndElevation;                        var lowpt = Math.Min(e1, e2);                        var highPt = Math.Max(e1, e2);                        var highlow = double.NaN;                        var pse = new ProfileStationElevation();                        var x1 = double.NaN;                        var x2 = double.NaN;                        var g1 = double.NaN;                        var g2 = double.NaN;                        var L = double.NaN;                         switch (ent.EntityType)                        {                            case ProfileEntityType.Tangent:                                if (!(elev > lowpt && elev < highPt))                                    continue;                                var l = (elev - e1) / prof.GradeAt(ent.StartStation + 0.01);                                pse = new ProfileStationElevation();                                pse.Elevation = elev;                                pse.Station = ent.StartStation + l;                                output.Add(pse);                                break;                            case ProfileEntityType.Circular:                                var crvEnt = (ProfileCircular)ent;                                highlow = crvEnt.HighLowPointElevation;                                lowpt = Math.Min(highlow, lowpt);                                highPt = Math.Max(highlow, highPt);                                if (!(elev > lowpt && elev < highPt))                                    continue;                                //NEED FORMULA TO CALC LOCATION OF SPECIFIC ELEVATION ON CIRCULAR CURVE, using parabolic calc for now                                g1 = crvEnt.GradeIn;                                g2 = crvEnt.GradeOut;                                L = crvEnt.Length;                                 x1 = ((g1 * L) + Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);                                x2 = ((g1 * L) - Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);                                if (x1 > 0)                                {                                    pse = new ProfileStationElevation();                                    pse.Station = crvEnt.StartStation + x1;                                    pse.Elevation = elev;                                    output.Add(pse);                                }                                if (x2 > 0)                                {                                    pse = new ProfileStationElevation();                                    pse.Station = crvEnt.StartStation + x2;                                    pse.Elevation = elev;                                    output.Add(pse);                                }                                break;                            case ProfileEntityType.ParabolaAsymmetric:                                var crvAsymEnt = (ProfileParabolaAsymmetric)ent;                                highlow = crvAsymEnt.HighLowPointElevation;                                lowpt = Math.Min(highlow, lowpt);                                highPt = Math.Max(highlow, highPt);                                if (!(elev > lowpt && elev < highPt))                                    continue;                                //NEED FORMULA TO CALC LOCATION OF SPECIFIC ELEVATION ON ASYMMETRICAL PARABOLIC CURVE                                break;                            case ProfileEntityType.ParabolaSymmetric:                                var crvSymEnt = (ProfileParabolaSymmetric)ent;                                highlow = crvSymEnt.HighLowPointElevation;                                lowpt = Math.Min(highlow, lowpt);                                highPt = Math.Max(highlow, highPt);                                if (!(elev > lowpt && elev < highPt))                                    continue;                                g1 = crvSymEnt.GradeIn;                                g2 = crvSymEnt.GradeOut;                                L = crvSymEnt.Length;                                 x1 = ((g1 * L) + Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);                                x2 = ((g1 * L) - Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);                                if (x1 > 0)                                {                                    pse = new ProfileStationElevation();                                    pse.Station = crvSymEnt.StartStation + x1;                                    pse.Elevation = elev;                                    output.Add(pse);                                }                                if (x2 > 0)                                {                                    pse = new ProfileStationElevation();                                    pse.Station = crvSymEnt.StartStation + x2;                                    pse.Elevation = elev;                                    output.Add(pse);                                }                                break;                            default:                                //SHOULDN'T GET TO HERE                                break;                        }                    }                }                output = output.OrderBy(s => s.Station).ToList();                var align = (Alignment)tr.GetObject(prof.AlignmentId, OpenMode.ForRead);                double east = 0, north = 0;                var points = CivilApplication.ActiveDocument.CogoPoints;                foreach (var pair in output)                {                    align.PointLocation(pair.Station, 0, ref east, ref north);                    var pt = points.Add(new Point3d(east, north, pair.Elevation), true);                    ed.WriteMessage("\nStation: {0}, Elev: {1}", pair.Station.ToStationString(), pair.Elevation.ToString("F2"));                }                tr.Commit();            }        }         public static string ToStationString(this double Value)        {            var civdoc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;            var stasettings = civdoc.Settings.DrawingSettings.AmbientSettings.Station;            var stationstring = Value.ToString("F" + stasettings.Precision.Value);            var symbolposition = stasettings.StationDelimiterPosition.Value;            switch (stasettings.StationDelimiterPosition.Value)            {                case Autodesk.Civil.StationDelimiterPositionType.Delimiter10:                    stationstring = stationstring.Insert(stationstring.IndexOf('.') - 1, "+");                    break;                case Autodesk.Civil.StationDelimiterPositionType.Delimiter100:                    stationstring = stationstring.Insert(stationstring.IndexOf('.') - 2, "+");                    break;                case Autodesk.Civil.StationDelimiterPositionType.Delimiter1000:                    stationstring = stationstring.Insert(stationstring.IndexOf('.') - 3, "+");                    break;                case Autodesk.Civil.StationDelimiterPositionType.Delimiter10000:                    stationstring = stationstring.Insert(stationstring.IndexOf('.') - 4, "+");                    break;                case Autodesk.Civil.StationDelimiterPositionType.Delimiter100000:                    stationstring = stationstring.Insert(stationstring.IndexOf('.') - 5, "+");                    break;            }            return stationstring;        }     }    public class ProfileStationElevation    {        public double Station = double.NaN;        public double Elevation = double.NaN;         public ProfileStationElevation()        {         }    } }  

Navigation

[0] Message Index

[#] Next page

Go to full version