Line Edit Toolbar
DivideLineFeatures.cls
Option Explicit
Implements ICommand
Private m_pApp As IApplication 'used to hook the button to the application
Private m_pBitmap As IPictureDisp 'used to set button icon
Private m_bEnabled As Boolean 'used to track button-enabled state
Private m_pEditor As IEditor 'used to reference the ArcMap editor extension
Private WithEvents m_pEditorEvents As esriCore.Editor 'Editor events
Private WithEvents m_cmdOK As CommandButton
Private WithEvents m_cmdCancel As CommandButton
Private Sub Class_Initialize()
On Error GoTo ErrorHandler
Set m_pBitmap = LoadResPicture(102, 0)
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.Class_Initialize"
End Sub
Private Sub Class_Terminate()
Set m_pApp = Nothing
Set m_pBitmap = Nothing
Set m_pEditor = Nothing
Set m_pEditorEvents = Nothing
End Sub
Private Property Get ICommand_Bitmap() As esriCore.OLE_HANDLE
On Error GoTo ErrorHandler
ICommand_Bitmap = m_pBitmap
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.ICommand_Bitmap"
End Property
Private Property Get ICommand_Caption() As String
ICommand_Caption = "Divide Line Feature(s)"
End Property
Private Property Get ICommand_Category() As String
ICommand_Category = "Developer Samples"
End Property
Private Property Get ICommand_Checked() As Boolean
End Property
Private Property Get ICommand_Enabled() As Boolean
On Error GoTo ErrorHandler
If m_bEnabled = True Then
ICommand_Enabled = True
End If
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.ICommand_Enabled"
End Property
Private Property Get ICommand_HelpContextID() As Long
End Property
Private Property Get ICommand_HelpFile() As String
End Property
Private Property Get ICommand_message() As String
ICommand_message = "Divide selected line feature(s) evenly or by distance."
End Property
Private Property Get ICommand_Name() As String
ICommand_Name = "DivideLineFeatures"
End Property
Private Sub ICommand_OnClick()
On Error GoTo ErrorHandler
frmDivideLineFeatures.Show
Set m_cmdOK = frmDivideLineFeatures.cmdOK
Set m_cmdCancel = frmDivideLineFeatures.cmdCancel
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.ICommand_OnClick"
End Sub
Private Sub ICommand_OnCreate(ByVal hook As Object)
On Error GoTo ErrorHandler
Set m_pApp = hook
Dim pID As New UID
pID = "esriCore.Editor"
Set m_pEditor = m_pApp.FindExtensionByCLSID(pID)
Set m_pEditorEvents = m_pEditor
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.ICommand_OnCreate"
End Sub
Private Property Get ICommand_Tooltip() As String
ICommand_Tooltip = "Divide Line Feature(s)"
End Property
Private Sub m_pEditorEvents_OnSelectionChanged()
On Error GoTo ErrorHandler
m_bEnabled = False
Dim pEnumFeature As IEnumFeature
Dim pFeature As iFeature
If m_pEditor.SelectionCount > 0 Then
m_bEnabled = True
Set pEnumFeature = m_pEditor.EditSelection
pEnumFeature.Reset
Set pFeature = pEnumFeature.Next
Do Until pFeature Is Nothing
If Not pFeature.Shape.GeometryType = esriGeometryPolyline Then
m_bEnabled = False
Exit Do
End If
Set pFeature = pEnumFeature.Next
Loop
End If
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.m_pEditorEvents_OnSelectionChanged"
End Sub
Private Sub m_cmdOK_Click()
On Error GoTo ErrorHandler
'grab values from frmDivideLineFeatures and validate input
If frmDivideLineFeatures.OptSplitEvenly.Value = True Then
If IsNumeric(frmDivideLineFeatures.txtSplitEvenly.Text) Then
Dim iSplitEvenly As Double
iSplitEvenly = frmDivideLineFeatures.txtSplitEvenly.Text
Else
MsgBox "Invalid Value", vbOKOnly, "Error"
frmDivideLineFeatures.txtSplitEvenly.SetFocus
End If
Else 'SplitByDistance option was selected
If IsNumeric(frmDivideLineFeatures.txtSplitByDistance.Text) Then
Dim dSplitByDistance As Integer
dSplitByDistance = frmDivideLineFeatures.txtSplitByDistance.Text
'Determine orientation, if True split from Start
Dim bOrientation As Boolean
bOrientation = frmDivideLineFeatures.optFromStart.Value
Else
MsgBox "Invalid Value", vbOKOnly, "Error"
frmDivideLineFeatures.txtSplitEvenly.SetFocus
End If
End If
'Get the selected line feature(s) to divide
Dim pEnumFeature As IEnumFeature
Set pEnumFeature = m_pEditor.EditSelection
pEnumFeature.Reset
Dim pFeature As iFeature
m_pEditor.StartOperation
Dim iFeature As Integer
For iFeature = 0 To m_pEditor.SelectionCount - 1
Set pFeature = pEnumFeature.Next
'prepare to invalidate the features extent
Dim pInvalidArea As IInvalidArea
Set pInvalidArea = New InvalidArea
Set pInvalidArea.Display = m_pEditor.Display
pInvalidArea.Add pFeature
'get length of polyline
Dim pPolyline As IPolyline
Set pPolyline = pFeature.Shape
Dim dPolylineLength As Double
dPolylineLength = pPolyline.length
'Create point(s) objects used to split featue
Dim pSplitPoint As IPoint
Dim pSplitPoints As IMultipoint
Set pSplitPoints = New Multipoint
Dim pPointColl As IPointCollection
Set pPointColl = pSplitPoints
'Test to see what split option the user choose
'and create point feature to split the line feature
If frmDivideLineFeatures.OptSplitEvenly.Value = True Then
Dim dSplitPercentLength As Double
dSplitPercentLength = 1 / iSplitEvenly
Dim dAccumulativePercent As Double
dAccumulativePercent = dSplitPercentLength
Dim i As Integer
For i = 1 To iSplitEvenly - 1
Set pSplitPoint = New Point
'return splitlocation as a point feature
pPolyline.QueryPoint 0, dAccumulativePercent, True, pSplitPoint
pPointColl.AddPoint pSplitPoint
dAccumulativePercent = dAccumulativePercent + dSplitPercentLength
Next i
SplitFeature pFeature, pPointColl
Else 'Split by distance was choosen
Dim dAccumulativeLength As Double
dAccumulativeLength = dSplitByDistance
'check for orientation, if "from end", then clone and flip polyline
If frmDivideLineFeatures.optFromStart = True Then
Do While dAccumulativeLength < dPolylineLength
Set pSplitPoint = New Point
'return splitlocation as a point feature
pPolyline.QueryPoint 0, dAccumulativeLength, False, pSplitPoint
pPointColl.AddPoint pSplitPoint
dAccumulativeLength = dAccumulativeLength + dSplitByDistance
Loop
SplitFeature pFeature, pPointColl
Else
Dim pPolylineFlipped As IPolyline
Set pPolylineFlipped = pFeature.Shape
pPolylineFlipped.ReverseOrientation
Do While dAccumulativeLength < dPolylineLength
Set pSplitPoint = New Point
'return splitlocation as a point feature
pPolylineFlipped.QueryPoint 0, dAccumulativeLength, False, pSplitPoint
pPointColl.AddPoint pSplitPoint
dAccumulativeLength = dAccumulativeLength + dSplitByDistance
Loop
SplitFeature pFeature, pPointColl
End If
End If
Next iFeature
m_pEditor.StopOperation ("Divide Line Feature(s)")
'clearselection & refresh
Dim pMxDoc As IMxDocument
Set pMxDoc = m_pApp.Document
pMxDoc.FocusMap.ClearSelection
pMxDoc.ActiveView.Refresh
Unload frmDivideLineFeatures
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.m_cmdOk_Click"
End Sub
Private Sub m_cmdCancel_Click()
Unload frmDivideLineFeatures
End Sub
Private Sub SplitFeature(pFeature As iFeature, pSplitPoints As IPointCollection)
On Error GoTo ErrorHandler
Dim pEnumVertex As IEnumVertex
Dim pGeoColl As IGeometryCollection
Dim pPolyCurve As IPolycurve2
Dim pEnumSplitPoint As IEnumSplitPoint
Dim pNewFeature As iFeature
Dim PartCount As Integer
'Split the found features, each split makes a new part
Set pEnumVertex = pSplitPoints.EnumVertices
Set pPolyCurve = pFeature.Shape
Set pEnumSplitPoint = pPolyCurve.SplitAtPoints(pEnumVertex, True, True, -1)
If Not pEnumSplitPoint.SplitHappened Then Exit Sub
'Convert each part to a new feature
Set pGeoColl = pPolyCurve
Dim pFClass As IFeatureClass
Set pFClass = pFeature.Table
For PartCount = 0 To pGeoColl.GeometryCount - 1
Set pNewFeature = pFClass.CreateFeature
Set pNewFeature.Shape = BUILDPOLYLINE(pGeoColl.Geometry(PartCount))
COPYATTRIBUTES pFeature, pNewFeature
pNewFeature.Store
Next PartCount
'Delete the original feature to be archived
pFeature.Delete
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.SplitFeature"
End Sub
Private Sub COPYATTRIBUTES(pSourceFeature As iFeature, pDestinationFeature As iFeature)
Dim pField As IField
Dim pFields As IFields
Dim pRow As IRow
Dim FieldCount As Integer
On Error GoTo ErrorHandler
Set pFields = pSourceFeature.Fields
For FieldCount = 0 To pFields.FieldCount - 1
Set pField = pFields.Field(FieldCount)
If pField.Editable Then
If Not pField.Type = esriFieldTypeOID And Not pField.Type = esriFieldTypeGeometry Then
pDestinationFeature.Value(FieldCount) = pSourceFeature.Value(FieldCount)
End If
End If
Next FieldCount
Exit Sub
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.COPYATTRIBUTES"
End Sub
Private Function BUILDPOLYLINE(pSegColl As ISegmentCollection) As IPolyline
On Error GoTo ErrorHandler
Dim pPolyline As IGeometryCollection
Set pPolyline = New Polyline
pPolyline.AddGeometries 1, pSegColl
Set BUILDPOLYLINE = pPolyline
Exit Function
ErrorHandler:
MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine _
& "In " & Err.Source & " at DivideLineFeature.BUILDPOLYLINE"
End Function