| name | c3d-alignments |
| description | Alignments — creation, entities, stations, design speeds, superelevation |
Civil 3D Alignments
Use this skill when creating, modifying, or querying alignments, working with stations, or configuring superelevation.
Alignment Collections
ObjectIdCollection allAlignments = doc.GetAlignmentIds();
ObjectIdCollection sitelessAlignments = doc.GetSitelessAlignmentIds();
Creating Alignments
Empty Alignment (no geometry)
ObjectId alignId = Alignment.Create(doc, "New Alignment",
"",
"0",
"Basic",
"AllLabels"
);
ObjectId alignId = Alignment.Create(doc, "New Alignment",
ObjectId.Null,
layerId,
styleId,
labelSetId
);
ObjectId alignId = Alignment.Create(doc, "New Alignment",
ObjectId.Null, layerId, styleId, labelSetId,
AlignmentType.Centerline
);
From Polyline
PromptEntityOptions opt = new PromptEntityOptions("\nSelect a polyline");
opt.SetRejectMessage("\nObject must be a polyline.");
opt.AddAllowedClass(typeof(Polyline), false);
PromptEntityResult res = ed.GetEntity(opt);
PolylineOptions plops = new PolylineOptions();
plops.AddCurvesBetweenTangents = true;
plops.EraseExistingEntities = true;
plops.PlineId = res.ObjectId;
ObjectId alignId = Alignment.Create(doc, plops,
"New Alignment", "MySite", "0", "Standard", "Standard");
ObjectId alignId = Alignment.Create(doc, plops,
"New Alignment", siteId, layerId, styleId, labelSetId);
From Corridor Feature Line
ObjectId alignId = Alignment.Create(corridorFeatureLine,
"FL Alignment", siteId, layerId, styleId, labelSetId,
AlignmentType.Centerline);
Offset Alignment (static methods)
The instance method CreateOffsetAlignment(double) is deprecated since Civil 3D 2010. Use the static overloads instead:
ObjectId offsetId = Alignment.CreateOffsetAlignment(db,
"Offset Align",
"Parent Alignment",
10.0,
"Standard"
);
ObjectId offsetId = Alignment.CreateOffsetAlignment(db,
"Offset Align", "Parent Alignment", 10.0, "Standard",
100.0, 500.0
);
ObjectId offsetId = Alignment.CreateOffsetAlignment(
"Offset Align", parentAlignId, 10.0, styleId);
ObjectId offsetId = Alignment.CreateOffsetAlignment(
"Offset Align", parentAlignId, 10.0, styleId, 100.0, 500.0);
Connected Alignment
ObjectId connectedId = Alignment.CreateConnectedAlignment(
"Connected Align", siteId, layerId, styleId, labelSetId,
connectedAlignmentParams);
bool isConnected = align.IsConnectedAlignment;
ConnectedAlignmentInfo info = align.ConnectedAlignmentInfo;
Site Operations
align.CopyToSite("MySite");
align.CopyToSite(siteId);
align.CopyToSameSite();
Alignment Entities
Entities are lines, curves, and spirals that form the alignment path. The collection supports fixed, floating, and free constraint types.
Iterating Entities
AlignmentEntityCollection entities = align.Entities;
foreach (AlignmentEntity ae in align.Entities)
{
switch (ae.EntityType)
{
case AlignmentEntityType.Arc:
AlignmentArc myArc = ae as AlignmentArc;
ed.WriteMessage("Arc R={0}, L={1}\n", myArc.Radius, myArc.Length);
break;
case AlignmentEntityType.Line:
AlignmentLine myLine = ae as AlignmentLine;
ed.WriteMessage("Line dir={0}\n", myLine.Direction);
break;
case AlignmentEntityType.Spiral:
AlignmentSpiral mySpiral = ae as AlignmentSpiral;
ed.WriteMessage("Spiral A={0}\n", mySpiral.A);
break;
}
}
Accessing Entities
AlignmentEntity entity = entities.EntityAtId(entityId);
AlignmentEntity entity = entities.GetEntityByOrder(index);
AlignmentEntity entity = entities.EntityAtStation(rawStation);
int first = entities.FirstEntity;
int last = entities.LastEntity;
Adding Fixed Entities (defined by coordinates)
AlignmentLine line = entities.AddFixedLine(startPoint, endPoint);
AlignmentLine line = entities.AddFixedLine(prevEntityId, startPoint, endPoint);
AlignmentLine line = entities.AddFixedLine(prevEntityId, distance);
AlignmentArc arc = entities.AddFixedCurve(prevEntityId, startPt, midPt, endPt);
AlignmentArc arc = entities.AddFixedCurve(pt1, pt2, radius, isClockwise);
AlignmentArc arc = entities.AddFixedCurve(centerPt, passThroughPt, isClockwise);
AlignmentArc arc = entities.AddFixedCurve(centerPt, radius, isClockwise);
AlignmentArc arc = entities.AddFixedCurve(pt1, dirAtPt1, radius, isClockwise);
AlignmentArc arc = entities.AddFixedCurve(pt1, dirAtPt1, pt2);
AlignmentArc arc = entities.AddFixedCurve(pt1, pt2, dirAtPt2);
AlignmentSpiral sp = entities.AddFixedSpiral(prevId, startRadius, endRadius, length, spiralDef);
AlignmentSpiral sp = entities.AddFixedSpiral(prevId, radius, length, spiralCurveType, spiralDef);
AlignmentSpiral sp = entities.AddFixedSpiral(prevId, startPt, piPt, endPt, spiralDef);
Adding Floating Entities (attached to one neighbor)
AlignmentLine line = entities.AddFloatingLine(prevEntityId, length);
AlignmentLine line = entities.AddFloatingLine(prevEntityId, passThroughPt);
AlignmentLine line = entities.AddFloatingLine(length, nextEntityId);
AlignmentArc arc = entities.AddFloatingCurve(prevEntityId, passThroughPt);
AlignmentArc arc = entities.AddFloatingCurve(prevEntityId, radius, paramValue,
paramType, isClockwise);
Adding Free Entities (constrained to two neighbors)
AlignmentLine line = entities.AddFreeLine(prevEntityId, nextEntityId);
AlignmentArc arc = entities.AddFreeCurve(prevEntityId, nextEntityId,
passThroughPt);
AlignmentArc arc = entities.AddFreeCurve(prevEntityId, nextEntityId,
paramValue, paramType, isGreaterThan180, curveType);
AlignmentSCS scs = entities.AddFreeSCS(prevEntityId, nextEntityId,
sp1Param, sp2Param, spType, radius, isGreaterThan180, spiralDef);
Removing Entities
entities.Remove(entity);
entities.RemoveAt(index);
entities.Clear();
Stations
Station Equations
StationEquation eq = align.StationEquations.Add(
80,
0,
StationEquationType.Increasing
);
Station Sets
StationTypes is a flags enum (note the plural). Common values: All, Major, Minor, GeometryPoint, Equation, SuperTransPoint.
Station[] stations = align.GetStationSet(StationTypes.All, 100, 20);
foreach (Station s in stations)
{
ed.WriteMessage("Station {0}, Type: {1}, Location: ({2},{3})\n",
s.RawStation, s.StationType, s.Location.X, s.Location.Y);
}
Station[] majors = align.GetStationSet(StationTypes.Major, 100);
Station[] geoPts = align.GetStationSet(StationTypes.GeometryPoint);
Station[] ranged = align.GetStationSet(StationTypes.All, 50, 10, 100.0, 500.0);
Point Location from Station
double easting, northing;
align.PointLocation(station, offset, ref easting, ref northing);
double bearing;
align.PointLocation(station, offset, tolerance,
ref easting, ref northing, ref bearing);
Tolerance note: Determines which entity the point is on. A large tolerance may place the point on an earlier entity. Note parameter order is easting, northing (X, Y).
Station/Offset from Point (inverse of PointLocation)
double station, offset;
align.StationOffset(easting, northing, ref station, ref offset);
align.StationOffset(easting, northing, tolerance, ref station, ref offset);
bool outOfRange;
align.StationOffsetAcceptOutOfRange(easting, northing,
ref station, ref offset, ref outOfRange);
align.StationOffsetAcceptOutOfRange(easting, northing, tolerance,
ref station, ref offset, ref outOfRange);
Instantaneous Radius at Station
double radius = align.GetInstantaneousRadius(rawStation);
Reverse Alignment Direction
align.Reverse();
Distance to Another Alignment
double distToOther, stationOnOther;
align.DistanceToAlignment(stationOnThis, otherAlignment,
ref distToOther, ref stationOnOther);
align.DistanceToAlignment(stationOnThis, otherAlignment,
AlignmentSide.Left, ref distToOther, ref stationOnOther);
Design Speeds
DesignSpeed ds = align.DesignSpeeds.Add(0, 45);
ds.Comment = "Straightaway";
ds = align.DesignSpeeds.Add(430, 30);
ds.Comment = "Start of curve";
align.UseDesignSpeed = true;
Note: GetDesignSpeed() requires a "raw" station value (without station equation modifications).
Superelevation
Superelevation is divided into curves, each containing transition regions with critical stations.
if (align.SuperelevationCurves.Count < 1)
{
ed.WriteMessage("Must calculate superelevation data first.\n");
return;
}
foreach (SuperelevationCurve sec in align.SuperelevationCurves)
{
ed.WriteMessage("Curve: {0}, Start: {1}, End: {2}\n",
sec.Name, sec.StartStation, sec.EndStation);
foreach (SuperelevationCriticalStation sest in sec.CriticalStations)
{
ed.WriteMessage(" Station: {0}, Type: {1}, Region: {2}\n",
sest.Station, sest.StationType, sest.TransitionRegionType);
foreach (int i in Enum.GetValues(typeof(SuperelevationCrossSegmentType)))
{
try
{
double slope = sest.GetSlope(
(SuperelevationCrossSegmentType)i);
ed.WriteMessage(" Slope: {0}, Segment: {1}\n", slope,
Enum.GetName(typeof(SuperelevationCrossSegmentType), i));
}
catch (InvalidOperationException) { }
}
}
}
Key properties:
Alignment.SuperelevationCurves - collection of SE curves
Alignment.SuperelevationCriticalStations - all critical stations across all curves
SuperelevationCriticalStationCollection.GetCriticalStationAt() - access individual stations
API Change Note (Civil 3D 2013+): SuperelevationData property and SuperElevationAtStation() method were removed. Use SuperelevationCurves and SuperelevationCriticalStations instead.
Alignment Styles
ObjectId styleId = doc.Styles.AlignmentStyles.Add("My Alignment Style");
AlignmentStyle style = ts.GetObject(styleId, OpenMode.ForWrite) as AlignmentStyle;
style.GetDisplayStylePlan(AlignmentDisplayStyleType.Arrow).Visible = false;
style.GetDisplayStylePlan(AlignmentDisplayStyleType.Curve).Color =
Color.FromColorIndex(ColorMethod.ByAci, 200);
style.GetDisplayStylePlan(AlignmentDisplayStyleType.Line).Color =
Color.FromColorIndex(ColorMethod.ByAci, 160);
align.StyleId = style.Id;
Alignment Label Styles
Labels are set via LabelSet when creating an alignment, or through LabelSetStyles:
var labelSetStyles = doc.Styles.LabelSetStyles.AlignmentLabelSetStyles;
Alignment Label Property Fields
Major/minor stations:
<[Station Value(Uft|FS|P0|RN|AP|Sn|TP|B2|EN|W0|OF)]>
<[Northing(Uft|P4|RN|AP|Sn|OF)]>
<[Design Speed(P3|RN|AP|Sn|OF)]>
<[Alignment Name(CP)]>
Additional fields for specific label types:
- Minor stations:
<[Offset From Major Station(...)]>
- Geometry points:
<[Geometry Point Text(CP)]>, <[Geometry Point Entity Before/After Data(CP)]>
- Design speeds:
<[Design Speed Before(...)]>
- Station equations:
<[Station Ahead(...)]>, <[Station Back(...)]>, <[Increase/Decrease(CP)]>
Related Queries
ObjectIdCollection pvIds = align.GetProfileViewIds();
ObjectIdCollection slgIds = align.GetSampleLineGroupIds();
ObjectIdCollection profileIds = align.GetProfileIds();
ObjectIdCollection seViewIds = align.GetSuperelevationViewIds();
ObjectIdCollection offsetIds = align.GetChildOffsetAlignmentIds();
ObjectIdCollection dynamicOnly = align.GetChildOffsetAlignmentIds(true);
ObjectIdCollection labelGroupIds = align.GetAlignmentLabelGroupIds();
ObjectIdCollection labelIds = align.GetAlignmentLabelIds();
ObjectId plineId = align.GetPolyline();
align.ImportLabelSet("My Label Set");
align.ImportLabelSet(labelSetStyleId);
string stationStr = align.GetStationStringWithEquations(rawStation);
string uniqueName = Alignment.GetNextUniqueName("MyAlignment");
Useful Properties
double start = align.StartingStation;
double end = align.EndingStation;
double endEq = align.EndingStationWithEquations;
double length = align.Length;
Point2d refPt = align.ReferencePoint;
double refStation = align.ReferencePointStation;
string siteName = align.SiteName;
bool isSiteless = align.IsSiteless;
bool isOffset = align.IsOffsetAlignment;
OffsetAlignmentInfo oaInfo = align.OffsetAlignmentInfo;
AlignmentType aType = align.AlignmentType;
AlignmentCreationType cMode = align.CreationMode;
double slope = align.GetCrossSlopeAtStation(station,
SuperelevationCrossSegmentType.LeftInLaneCrossSlope, true);
Gotchas
Create() string overload fails if the named styles don't exist in the document
- Offset alignment does NOT inherit station labels, equations, or design speeds
- Station equations modify station values - some methods need "raw" stations (use
GetStationStringWithEquations() for display)
- Superelevation curves must be calculated before accessing (manually or via wizard)
GetSlope() throws InvalidOperationException for invalid segment types - catch silently
PointLocation and StationOffset parameter order is easting, northing (X, Y), not northing, easting
GetInstantaneousRadius() requires a raw station value
- The instance method
CreateOffsetAlignment(double) is deprecated since Civil 3D 2010; use the static overloads
StationTypes is a flags enum (plural) - use StationTypes.All, not StationType.All
Related Skills
c3d-profiles - Profiles along alignments
c3d-label-styles - General label style creation
c3d-corridors - Corridors use alignments as baselines
acad-editor-input - Selecting alignments with GetEntity and AddAllowedClass
c3d-superelevation - Detailed superelevation data access, critical stations, and cross slopes
c3d-intersections - Intersection objects at alignment crossings