Intersection objects, curb returns, corridor geometry, approach roads, labels
Use this skill when querying intersection objects, curb returns, corridor intersection geometry, or intersection labels.
Intersection creation in Civil 3D is wizard-driven — there is no Intersection.Create() in the managed .NET API. The Intersection Wizard in the UI handles creation, including curb return generation, corridor region splitting, and approach road configuration. The .NET API provides read access to existing intersection objects and their properties.
Intersections are accessed through CivilDocument. Each intersection is an Intersection entity in the drawing database.
CivilDocument doc = CivilApplication.ActiveDocument;
using (Transaction ts = db.TransactionManager.StartTransaction())
{
ObjectIdCollection intIds = doc.GetIntersectionIds();
foreach (ObjectId intId in intIds)
{
Intersection ix = ts.GetObject(intId, OpenMode.ForRead) as Intersection;
ed.WriteMessage("Intersection: {0}, Location: ({1:F2}, {2:F2})\n",
ix.Name, ix.Location.X, ix.Location.Y);
}
ts.Commit();
}
Intersection ix = ts.GetObject(intId, OpenMode.ForRead) as Intersection;
// Identity
string name = ix.Name;
ObjectId styleId = ix.StyleId;
// Location — the 2D point where alignments cross
Point2d location = ix.Location;
// Road references
ObjectId mainRoadId = ix.RoadwayAlignmentId;
ObjectIdCollection approachIds = ix.GetApproachIds();
ObjectIdCollection curbReturnIds = ix.GetCurbReturnIds();
// Corridor reference
ObjectId corridorId = ix.CorridorId;
Intersection ix = ts.GetObject(intId, OpenMode.ForWrite) as Intersection;
ix.Name = "Main St & 1st Ave";
ix.Description = "Signalized 4-way intersection";
ix.StyleId = newStyleId;
Intersection creation is not available through the managed .NET API. Use the Intersection Wizard via SendStringToExecute:
// Opens the interactive Intersection Wizard
Document acadDoc = Application.DocumentManager.MdiActiveDocument;
acadDoc.SendStringToExecute("CREATEINTERSECTION ", true, false, false);
The wizard requires:
To compute where two alignments cross (useful for pre-validation):
Alignment mainAlign = ts.GetObject(mainAlignId, OpenMode.ForRead) as Alignment;
Alignment approachAlign = ts.GetObject(approachAlignId, OpenMode.ForRead) as Alignment;
// Entity.IntersectWith works on the visual representation
Point3dCollection crossingPts = new Point3dCollection();
mainAlign.IntersectWith(approachAlign,
Intersect.OnBothOperands, crossingPts,
IntPtr.Zero, IntPtr.Zero);
if (crossingPts.Count > 0)
{
Point2d crossPt = new Point2d(crossingPts[0].X, crossingPts[0].Y);
ed.WriteMessage("Crossing at: ({0:F2}, {1:F2})\n", crossPt.X, crossPt.Y);
}
Note:
Entity.IntersectWithworks on the visual representation and may not account for vertical geometry. UseAlignment.GetStationAtPointto verify the result.
Curb returns are the fillet arcs connecting the edge of pavement between the main road and approach road at an intersection. They are child objects created by the Intersection Wizard.
Intersection ix = ts.GetObject(intId, OpenMode.ForRead) as Intersection;
ObjectIdCollection curbReturnIds = ix.GetCurbReturnIds();
foreach (ObjectId crId in curbReturnIds)
{
CurbReturn cr = ts.GetObject(crId, OpenMode.ForRead) as CurbReturn;
ed.WriteMessage("Curb return: {0}\n", cr.Name);
}
CurbReturn cr = ts.GetObject(crId, OpenMode.ForRead) as CurbReturn;
ObjectId crAlignmentId = cr.AlignmentId;
ObjectId crProfileId = cr.ProfileId;
// Access the curb return as an alignment
Alignment crAlign = ts.GetObject(crAlignmentId, OpenMode.ForRead) as Alignment;
ed.WriteMessage("Curb return alignment: {0}, Length: {1:F2}\n",
crAlign.Name, crAlign.Length);
Note: Curb return alignments are child objects of the intersection. They do not appear in the main alignment collection and cannot be independently reparented.
Intersections and corridors are tightly linked. When an intersection is created within a corridor, Civil 3D automatically generates curb return alignments/profiles and corridor regions for the intersection area.
Corridor corridor = ts.GetObject(corridorId, OpenMode.ForRead) as Corridor;
foreach (Baseline bl in corridor.Baselines)
{
foreach (BaselineRegion region in bl.BaselineRegions)
{
// Intersection regions are typically named with the intersection name
ed.WriteMessage("Region: {0}, Start: {1:F2}, End: {2:F2}\n",
region.Name, region.StartStation, region.EndStation);
ObjectId assemblyId = region.AssemblyId;
}
}
Corridor corridor = ts.GetObject(corridorId, OpenMode.ForWrite) as Corridor;
corridor.Rebuild();
Intersection corridors contribute to the overall corridor surface:
Corridor corridor = ts.GetObject(corridorId, OpenMode.ForRead) as Corridor;
foreach (CorridorSurface cSurf in corridor.CorridorSurfaces)
{
ed.WriteMessage("Corridor surface: {0}\n", cSurf.Name);
ObjectId surfId = cSurf.SurfaceId;
}
Approach roads are the alignments connecting to the main road. An intersection can have multiple approaches (e.g., a 4-way intersection has one main road plus three approaches, or two roads crossing creates a main road plus one approach).
Intersection ix = ts.GetObject(intId, OpenMode.ForRead) as Intersection;
// Main road
Alignment mainRoad = ts.GetObject(ix.RoadwayAlignmentId, OpenMode.ForRead) as Alignment;
ed.WriteMessage("Main road: {0}\n", mainRoad.Name);
// Approach roads
ObjectIdCollection approachIds = ix.GetApproachIds();
foreach (ObjectId appId in approachIds)
{
Alignment approach = ts.GetObject(appId, OpenMode.ForRead) as Alignment;
ed.WriteMessage(" Approach: {0}\n", approach.Name);
}
Note:
GetApproachIds()returns only approach alignments. The main road is accessed viaRoadwayAlignmentId— it is not included in the approach collection.
// Assign a style to an intersection
Intersection ix = ts.GetObject(intId, OpenMode.ForWrite) as Intersection;
ix.StyleId = doc.Styles.IntersectionStyles["Standard"];
Intersection labels display name, station on roads, coordinates, and angles between roads.
// Set the label style on the intersection
Intersection ix = ts.GetObject(intId, OpenMode.ForWrite) as Intersection;
ix.LabelStyleId = labelStyleId;
| Property Field | Description |
|---|---|
| Intersection Name | Name of the intersection object |
| Main Road Name | Name of the main road alignment |
| Main Road Station | Station on the main road at the crossing |
| Approach Road Name | Name of the approach alignment |
| Approach Road Station | Station on the approach road at the crossing |
| Intersection Easting | X coordinate of the intersection point |
| Intersection Northing | Y coordinate of the intersection point |
| Intersection Angle | Angle between the two alignments |
CREATEINTERSECTION wizard command or SendStringToExecute. This is confirmed by Autodesk community forums.RoadwayAlignmentId, not from the approach collection.StyleId or LabelStyleId outside a transaction or on a read-only object throws.c3d-alignments — main and approach road alignmentsc3d-corridors — corridor integration with intersectionsc3d-profiles — profile views at intersectionsc3d-label-styles — general label style configurationc3d-root-objects — CivilDocument access and transaction patterns