This begins hopefully a long running series of how to use the .Net API for Civil 3D. The series will run as long as there are suggestions and ideas for what to write. For example, the exercise below is based upon Mike Robertson’s suggestion (hope I understood it right Mike).
All exercises will be based upon the assumption that you have read the Civil 3D .Net API 101 Series located here:
Ok to the exercise
Alignment Station Labels
When working in Civil 3D, you realize that alignment labels are split into labels that are applied to a specific point (i.e., Station Offset) and labels that are applied along a station range of the alignment (i.e. Station labels).
For our exercise, we want to get all the label style objects that are applied to the selected alignment. So let’s create a new command called GetAlignmentStationLabelStyles. So we create a class for this, add the imports that we will use (the key import for the command is the Autodesk.AutoCAD.Runtime Import). The class so far will look like this:
Public Class Commands
Public Sub Initialize() Implements IExtensionApplication.Initialize
DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & _
"Loading " & My.Application.Info.AssemblyName)
Public Sub Terminate() Implements IExtensionApplication.Terminate
Public Sub cmdGetStationLabelStyles()
Now we need to first get the alignment object. Since both the API 101 Series and my AU class cover how to have the user select the alignment from a dialog box and/or graphically we are just going to grab the alignment object graphically. To interact with the user graphically we will need the current drawing’s editor. We get this with the following:
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Now that we have the editor, we can send an entity selection prompt to the editor for the user to be prompted with. Before we send the prompt, we need to set up the options of the prompt. We do this with a PromptEntityOptions object with is in the editor class.
Dim entSelOpts As New PromptEntityOptions(vbLf & _
"Select alignment object or <exit>: ")
So we have a new object called “entSelOpts” which will prompt the user to select an alignment object. Let’s add a few additional options to our new object.
‘This will return none but if none is returned we will just exit the command
.AllowNone = True
‘Since we are not manipulating the alignment we will allow objects on locked layer
.AllowObjectOnLockedLayer = True
‘We have to set the message for a rejected object before we can define acceptable objects
.SetRejectMessage(vbLf & "Object selected is not an aligment")
‘We want to only allow the user to select an alignment object
Okay, so we have our prompt setup. Let’s use it to prompt the user. To get the prompt results, we use another object called a PromptEntityResult object. We use it in the following:
Dim entSelRes As PromptEntityResult = ed.GetEntity(entSelOpts)
If entSelRes.Status <> PromptStatus.OK Then Exit Sub
So the value of “entSelRes” is the result of prompting the user for an entity using the options we setup previously. Since this is a simple prompt, if anything besides Ok is returned we just exit our command.
Ok, we should have our alignment object now. Let’s query it and get the alignment group labels. We have to use a transaction to get to this. To make sure I always properly dispose of my transactions, I create it with the “USING” function and then wrap the interior of the USING in a TRY…CATCH…END TRY for additional security. The alignment object is retrieved with the following:
Using db As Database = HostApplicationServices.WorkingDatabase
Using trans As Transaction = db.TransactionManager.StartTransaction
Dim align As Autodesk.Civil.Land.DatabaseServices.Alignment
align = trans.GetObject(entSelRes.ObjectId, OpenMode.ForRead)
Inside the alignment object, is a method called “GetLabelGroupIds” which returns an ObjectIdCollection of all the label groups applied to this alignment. The ObjectId is actually NOT for the label style but for an object that represents the group settings for the label. For example, when you apply a label style that is a group label type, you also specify the range, increment (for station labels), geometry (for point type labels), etc. What is returned is this group object. Of course, each label type returns a different group type. So we need to track which label group type the ObjectId represents without crashing. We do this with the following:
Dim lblStaGroup As _
Dim dbObj As DBObject
For Each lblId As ObjectId In lblIdCol
dbObj = trans.GetObject(lblId, OpenMode.ForRead)
If TypeOf (dbObj) Is _
lblStaGroup = DirectCast(dbObj, _
Notice that we first take the ObjectId and apply it to a general database object. If the database object is the correct type (the AlignmentStationLabelGroup type) then we can go to work and cast the general object to the correct object type. Otherwise, just keep looping.
Next, let’s get the label style applied. We do this by finding the ObjectId for the label in the lblStaGroup object variable.
Dim lblStyle As Autodesk.Civil.DatabaseServices.Styles.LabelStyle
lblStyle = trans.GetObject(lblStaGroup.StyleId, OpenMode.ForRead)
Finally, we will write all this data out to the command line
ed.WriteMessage(vbLf & _
lblStaGroup.LabelType.ToString & " From Station: " & _
align.GetStationStringWithEquations(lblStaGroup.RangeStart) & _
" to Station: " & align.GetStationStringWithEquations(lblStaGroup.RangeEnd) & _
" | Style is " & lblStyle.Name)
We write it out to the command line using the method from the editor called WRITEMESSAGE. We write the label type (whether it is minor or major). Then we write the station range and we use a method built into the alignment object to provide us with a station formatted string of the station double. Lastly, we write out the label style’s name.
You can download the entire project source code here.
Feedback!! Was this exercise too simple? Too complex and hard?
What do you want to learn regarding Civil 3D .Net API?