About the Curve conversion add-in Sample
[C#]
CurveConversionDockWin.cs
using System; using System.Windows.Forms; using ESRI.ArcGIS.Editor; using ESRI.ArcGIS.EditorExt; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.ArcMapUI; using ESRI.ArcGIS.Framework; namespace CurveConversion { /// <summary> /// Designer class of the dockable window add-in. It contains user interfaces that /// make up the dockable window. /// </summary> public partial class CurveConversionDockWin : UserControl { private IDockableWindow _CurveDockWin; public static Double _Tolerance = 0.1; public static String _sFieldName = ""; public static IFields _MFields; public static System.Object _UpdateValue = 0; private static bool _Cancel = false; public bool _UpdateFieldIsString = false; private bool _CheckTol = false; public IEditor _Editor; public IEnvelope _InvalidEnv; internal static CurveConversionDockWin _CurveUserControl; public CurveConversionDockWin(object hook) { InitializeComponent(); this.Hook = hook; _CurveUserControl = this; } /// <summary> /// Host object of the dockable window /// </summary> private object Hook { get; set; } /// <summary> /// Implementation class of the dockable window add-in. It is responsible for /// creating and disposing the user interface class of the dockable window. /// </summary> public class AddinImpl : ESRI.ArcGIS.Desktop.AddIns.DockableWindow { private CurveConversionDockWin m_windowUI; public AddinImpl() { } protected override IntPtr OnCreateChild() { m_windowUI = new CurveConversionDockWin(this.Hook); return m_windowUI.Handle; } protected override void Dispose(bool disposing) { if (m_windowUI != null) m_windowUI.Dispose(disposing); base.Dispose(disposing); } } /// <summary> /// Populates the Fields combo box with the fields other than Shape_length and area. /// </summary> public static void UpdateFieldList() { _CurveUserControl.comboBoxField.Items.Clear(); _CurveUserControl.comboBoxField.Items.Add("<none>"); if (_MFields != null) { for (int i = 0; i < _MFields.FieldCount; i++) { if (_MFields.get_Field(i).Type == esriFieldType.esriFieldTypeDouble | _MFields.get_Field(i).Type == esriFieldType.esriFieldTypeInteger | _MFields.get_Field(i).Type == esriFieldType.esriFieldTypeSingle | _MFields.get_Field(i).Type == esriFieldType.esriFieldTypeString) { string FieldName = _MFields.get_Field(i).Name.ToUpper(); if (FieldName != "SHAPE_LENGTH" & FieldName != "SHAPE_AREA") { _CurveUserControl.comboBoxField.Items.Add(_MFields.get_Field(i).Name); } } } } //Reset the form. _Cancel = true; _CurveUserControl.checkBoxTolerance.Checked = false; _CurveUserControl.textBoxTolerance.Text = _Tolerance.ToString(); _CurveUserControl.textBoxTolerance.Enabled = false; _CurveUserControl.textBoxvalue.Text = ""; _sFieldName = ""; _CurveUserControl.comboBoxField.SelectedIndex = 0; } private void buttonOK_Click(object sender, EventArgs e) { //You may also want to check that a shapefile is not being used. //Get the editor for the dockable window. UID eUID = new UIDClass(); eUID.Value = "esriEditor.Editor"; _Editor = ArcMap.Application.FindExtensionByCLSID(eUID) as IEditor; if (CheckValues() == false) return; _Tolerance = Convert.ToDouble(textBoxTolerance.Text); System.Windows.Forms.Cursor.Current = Cursors.WaitCursor; //Run the curve update. CurveUpdate(_CheckTol); _Cancel = false; System.Windows.Forms.Cursor.Current = Cursors.Default; //cast the control to a dockable window to hide it from the user. _CurveDockWin = CurveConversionCmd.GetCurveConversionWindow; if (_CurveDockWin == null) return; _CurveDockWin.Show(false); } private void buttonCancel_Click(object sender, EventArgs e) { //hide the dockable window from the user. _CurveDockWin = CurveConversionCmd.GetCurveConversionWindow; if (_CurveDockWin == null) return; _CurveDockWin.Show(false); } private void checkBoxTolerance_CheckedChanged(object sender, EventArgs e) { if (checkBoxTolerance.Checked == false) { _CheckTol = false; textBoxTolerance.Enabled = false; } else { _CheckTol = true; textBoxTolerance.Enabled = true; } } private void comboBoxField_SelectedIndexChanged(object sender, EventArgs e) { if (comboBoxField.SelectedIndex > 0) { int lIndex = _MFields.FindField(comboBoxField.Text); if (lIndex > -1) { if (_MFields.get_Field(lIndex).Type == esriFieldType.esriFieldTypeString) { _UpdateFieldIsString = true; _sFieldName = _MFields.get_Field(lIndex).Name; } else { _UpdateFieldIsString = false; _sFieldName = _MFields.get_Field(lIndex).Name; } } else { //resets the field to none. comboBoxField.SelectedIndex = 0; } } else { _UpdateFieldIsString = false; } } private bool CheckValues() { //Check for numeric tolerance value if option is checked int i; bool isnumeric = Int32.TryParse(textBoxTolerance.Text, out i); double a; isnumeric = double.TryParse(textBoxTolerance.Text, out a); if ((checkBoxTolerance.Checked == true) & (isnumeric == false)) { MessageBox.Show("Tolerance value must be numeric!!"); return false; } //Check for numeric value if field to update is not a string field if (comboBoxField.SelectedIndex > 0) { isnumeric = int.TryParse(textBoxvalue.Text, out i); if ((isnumeric = false) & (_UpdateFieldIsString = false)) { MessageBox.Show("Update value must be numeric when the field is numeric!!!"); return false; } } return true; } private void CurveUpdate(bool checkTol) { try { //***Not sure that the progress bar is needed***// //Set up the progress bar. IStatusBar _Status = ArcMap.Application.StatusBar; IStepProgressor _StepProg = _Status.ProgressBar; _StepProg.Position = 1; _StepProg.MaxRange = _Editor.SelectionCount; _StepProg.Message = "Update progress:"; _StepProg.StepValue = 1; _StepProg.Show(); int lCount = 0; _InvalidEnv = null; //You will get an error if your feature is stored in a shapefile. //Check to make sure there is no existing edit operation, then start one. IWorkspaceEdit2 _WorkspaceEdit = (IWorkspaceEdit2)_Editor.EditWorkspace; if (!_WorkspaceEdit.IsInEditOperation) { _Editor.StartOperation(); } ICurve _Curve; ICurve _Curve2; ISegmentCollection _OrigSegs; ISegmentCollection _Polyline; IConstructCircularArc _NewLine; Boolean _bSegCheck; IPoint _MidPoint; ISegment _Seg; Double _Dist = 0, _Dist1 = 0, _Dist2 = 0; Boolean _Side = false, _Updated = false; IEnumTopologyEdge _EdgeEnum; ISegmentCollection _Path = new PathClass(); ITopologyEdge _TopoEdge; IPolyline _SomeLine; IEnumFeature _EnumFeat = _Editor.EditSelection; IFeature feat = _EnumFeat.Next(); //Check for a topology ITopologyGraph _TopoGraph = TopologyCheck(feat.Class); do { if (feat.Shape.GeometryType == esriGeometryType.esriGeometryPolyline & (!IsStraight(feat))) { //Create the new segment based on a 3pt curve through the start point, mid point and end point of the feat geometry. _Curve = feat.Shape as ICurve; _OrigSegs = _Curve as ISegmentCollection; _MidPoint = new PointClass(); _Curve.QueryPoint(esriSegmentExtension.esriNoExtension, 0.5, true, _MidPoint); _NewLine = new CircularArcClass(); _NewLine.ConstructThreePoints(_Curve.FromPoint, _MidPoint, _Curve.ToPoint, false); _Curve2 = _NewLine as ICurve; //Check that the segments are within the tolerance. _bSegCheck = false; if (checkTol) { for (int lLoop = 1; lLoop < _OrigSegs.SegmentCount; lLoop++) { _Seg = _OrigSegs.get_Segment(lLoop); _Curve2.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, _Seg.FromPoint, false, _MidPoint, ref _Dist, ref _Dist1, ref _Side); _Curve2.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, _Seg.ToPoint, false, _MidPoint, ref _Dist, ref _Dist2, ref _Side); if (_Dist1 > _Tolerance | _Dist2 > _Tolerance) { _bSegCheck = true; break; } } } if (!_bSegCheck) { //Check for a topology. if (_TopoGraph != null) { _EdgeEnum = GetParents(feat, _TopoGraph); if (_EdgeEnum == null) { //not sure what i need to add, but to get here something went wrong. } else { object Missing = Type.Missing; _Path.AddSegment(_NewLine as ISegment, ref Missing, ref Missing); switch (_EdgeEnum.Count) { case 1: _EdgeEnum.Reset(); _TopoEdge = _EdgeEnum.Next(); _Updated = UpdateEdge(_TopoGraph, _TopoEdge, _Path); if (_Updated) { UpdateField(feat, true); lCount++; } break; case 2: _EdgeEnum.Reset(); _TopoEdge = _EdgeEnum.Next(); do { _SomeLine = _TopoEdge.Geometry as IPolyline; double X1 = _Path.get_Segment(0).FromPoint.X; double Y1 = _Path.get_Segment(0).FromPoint.Y; double X2 = _Path.get_Segment(0).ToPoint.X; double Y2 = _Path.get_Segment(0).ToPoint.Y; if (X1 == _SomeLine.FromPoint.X & Y1 == _SomeLine.FromPoint.Y & X2 == _SomeLine.ToPoint.X & Y2 == _SomeLine.FromPoint.Y) { _Updated = UpdateEdge(_TopoGraph, _TopoEdge, _Path); if (_Updated) { UpdateField(feat, true); lCount++; } break; } _TopoEdge = _EdgeEnum.Next(); } while (_TopoEdge != null); break; default: break; } _EdgeEnum = null; } } else { //the current feature is not part of a topo, so just update it. _Polyline = new PolylineClass(); object Missing = Type.Missing; _Polyline.AddSegment(_NewLine as ISegment, ref Missing, ref Missing); //This code sets the polyline ZAware so it will handle Z aware features. //However you need to check that the feature is Z aware first, so you can add this code here. //IZAware zAware = _Polyline as IZAware; //zAware.ZAware = true; feat.Shape = _Polyline as IGeometry; UpdateField(feat, false); feat.Store(); lCount++; if (_InvalidEnv == null) { _InvalidEnv = feat.Shape.Envelope; } else { _InvalidEnv.Union(feat.Shape.Envelope); } } } } feat = _EnumFeat.Next(); ArcMap.Application.StatusBar.ProgressBar.Step(); } while (feat != null); if (lCount == 0) { MessageBox.Show("No features were updated."); _Editor.AbortOperation(); } else { MessageBox.Show(lCount + " feature(s) updated"); _Editor.StopOperation("Update Curves"); } if (_InvalidEnv != null) { IMxDocument _Doc = ArcMap.Application.Document as IMxDocument; _Doc.ActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewAll, null, _InvalidEnv); } ArcMap.Application.StatusBar.ProgressBar.Hide(); } catch(Exception e) { MessageBox.Show("Error in updating the Curve, make sure you are not using a shapefile." + e.Message); ArcMap.Application.StatusBar.ProgressBar.Hide(); return; } } /// <summary> /// Checks the field type and converts the update value to the correct type and updates the feature. /// </summary> /// <param name="feat"></param> /// <param name="shouldStore"></param> private void UpdateField(IFeature feat, bool shouldStore) { try { int lFieldIndex = 0; if (_sFieldName != "<none>") { lFieldIndex = feat.Fields.FindField(_sFieldName); if (lFieldIndex > -1) { _UpdateValue = textBoxvalue.Text; switch (feat.Fields.get_Field(lFieldIndex).Type) { case esriFieldType.esriFieldTypeString: feat.set_Value(lFieldIndex, _UpdateValue.ToString()); break; case esriFieldType.esriFieldTypeInteger | esriFieldType.esriFieldTypeSmallInteger: feat.set_Value(lFieldIndex, Convert.ToInt32(_UpdateValue)); break; case esriFieldType.esriFieldTypeDouble | esriFieldType.esriFieldTypeSingle: feat.set_Value(lFieldIndex, Convert.ToDouble(_UpdateValue)); break; default: break; } if (shouldStore) feat.Store(); } } } catch { return; } } private bool UpdateEdge(ITopologyGraph topoGraph, ITopologyEdge _TopoEdge, ISegmentCollection _Path) { try { ISegmentCollection _NewSegs = _TopoEdge.Geometry as ISegmentCollection; IEnvelope _Invalid = new EnvelopeClass(); int inCount = _NewSegs.SegmentCount; topoGraph.SetEdgeGeometry(_TopoEdge, _Path as IPath); topoGraph.Post(out _Invalid); if (_InvalidEnv == null) { _InvalidEnv = _Invalid; } else { _InvalidEnv.Union(_Invalid); } _NewSegs = _TopoEdge.Geometry as ISegmentCollection; if (_NewSegs.SegmentCount == 1 & inCount > 1) { return true; } else return false; } catch (Exception e) { MessageBox.Show("Error in updating the topo edge " + e.Message); return false; } } /// <summary> /// Gets an enum of the parent edges for the feature. /// </summary> /// <param name="feat"></param> /// <param name="topoGraph"></param> /// <returns></returns> private IEnumTopologyEdge GetParents(IFeature feat, ITopologyGraph topoGraph) { IFeatureClass fFC = feat.Class as IFeatureClass; IEnumTopologyEdge _EnumTopoEdge = topoGraph.GetParentEdges(fFC, feat.OID); if (_EnumTopoEdge == null) { topoGraph.SetEmpty(); topoGraph.Build(feat.Shape.Envelope, false); _EnumTopoEdge = topoGraph.GetParentEdges(fFC, feat.OID); } else { if (_EnumTopoEdge.Count > 1) { topoGraph.DeletePseudoNodesFromSelection(); } } return _EnumTopoEdge; } /// <summary> /// Check to see if the line is straight. So we do NOT convert straight lines to polycurves. /// </summary> /// <param name="feat"></param> private bool IsStraight(IFeature feat) { try { if (feat.Shape.GeometryType != esriGeometryType.esriGeometryPolyline) return true; ISpatialReference _SR = feat.Shape.SpatialReference; IPolycurve _PolyCurve = feat.ShapeCopy as IPolycurve; ISegmentCollection _SegColl = _PolyCurve as ISegmentCollection; double _x; double _y; double _units; _SR.GetFalseOriginAndUnits(out _x, out _y, out _units); _PolyCurve.Generalize(2 / _units); if (_SegColl.SegmentCount == 1) { return true; } else { return false; } } catch (Exception e) { MessageBox.Show("Error in checking straight " + e.Message); return false; } } /// <summary> /// Checks to see if the feature class is part of a gdb or map topology. /// If it is it will build the topo cache and return the topology graph. /// </summary> /// <param name="oBJClass"></param> /// <returns></returns> private ITopologyGraph TopologyCheck(IObjectClass oBJClass) { try { ITopologyClass topoClass = oBJClass as ITopologyClass; ITopologyGraph topoGraph; if (topoClass.IsInTopology) { //Check to see if the class of the selected feature is part of the a topology. if (topoClass.Topology.Cache != null) { return topoGraph = topoClass.Topology.Cache as ITopologyGraph; } else { return topoGraph = null; } } else { //Check to see if the class of the selected feature is part of a map topology. UID mUID = new UIDClass(); mUID.Value = "esriEditor.TopologyExtension"; ITopologyExtension topoExt = ArcMap.Application.FindExtensionByCLSID(mUID) as ITopologyExtension; IMapTopology mapTopo = topoExt.MapTopology; IFeatureClass featClass = oBJClass as IFeatureClass; int lID = mapTopo.FindClass(featClass); if (lID > -1) { return topoGraph = mapTopo.Cache; } else { return topoGraph = null; } } } catch (Exception e) { Console.WriteLine("Error checking topology" + e); return null; } } } }
[Visual Basic .NET]
CurveConversionDockWin.vb
Imports System.Windows.Forms Imports ESRI.ArcGIS.esriSystem Imports ESRI.ArcGIS.Geodatabase Imports ESRI.ArcGIS.EditorExt Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.ArcMapUI Imports ESRI.ArcGIS.Editor Imports ESRI.ArcGIS.Framework ''' <summary> ''' Designer class of the dockable window add-in. It contains user interfaces that ''' make up the dockable window. ''' </summary> Public Class CurveConversionDockWin Private _CurveDockwin As ESRI.ArcGIS.Framework.IDockableWindow Public Shared _MFields As IFields Dim _UpdateValue As System.Object Shared _Cancel As Boolean = False Dim _UpdateFieldIsString As Boolean = False Private _CheckTol As Boolean = False Dim _Editor As IEditor Dim _InvalidEnv As IEnvelope Shared _Tolerance As [Double] = 0.1 Shared _sFieldName As [String] = "" Shared _CurveUserControl As CurveConversionDockWin Public Sub New(ByVal hook As Object) ' This call is required by the Windows Form Designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.Hook = hook _CurveUserControl = Me End Sub Private m_hook As Object ''' <summary> ''' Host object of the dockable window ''' </summary> Public Property Hook() As Object Get Return m_hook End Get Set(ByVal value As Object) m_hook = value End Set End Property Private Sub buttonOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonOK.Click 'You may also want to check that a shapefile is not being used. 'Get a refence to the editor. Dim uidEditor As New UID uidEditor.Value = "esriEditor.Editor" _Editor = TryCast(My.ArcMap.Application.FindExtensionByCLSID(uidEditor), ESRI.ArcGIS.Editor.IEditor) If CheckValues() = False Then Return End If _Tolerance = Convert.ToDouble(textBoxTolerance.Text) System.Windows.Forms.Cursor.Current = Cursors.WaitCursor 'Run the curve update CurveUpdate(_CheckTol) _Cancel = False System.Windows.Forms.Cursor.Current = Cursors.Default 'Cast the control to a dockable window to hide it from the user _CurveDockwin = CurveConversionCmd.GetCurveConversionWindow() If _CurveDockwin Is Nothing Then Return End If _CurveDockwin.Show(False) End Sub Private Sub buttonCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonCancel.Click 'hide the dockable window from the user. _CurveDockwin = CurveConversionCmd.GetCurveConversionWindow If _CurveDockwin Is Nothing Then Return End If _CurveDockwin.Show(False) End Sub Private Function CheckValues() As Boolean CheckValues = False 'Check for numeric tolerance value if option is checked If checkBoxTolerance.Checked = True And Not IsNumeric(textBoxTolerance.Text) Then MessageBox.Show("Tolerance value must be numeric!!") Exit Function End If 'Check for numeric value if field to update is not a string field If comboBoxField.SelectedIndex > 0 Then If Not IsNumeric(textBoxvalue.Text) And Not _UpdateFieldIsString Then MessageBox.Show("Update value must be numeric when the field is numeric!!!") Exit Function End If End If CheckValues = True End Function ''' <summary> ''' Populates the Fields combo box with the fields other than Shape_length and area. ''' </summary> ''' <remarks></remarks> Shared Sub UpdateFieldList() Dim lLoop As Long _CurveUserControl.comboBoxField.Items.Clear() _CurveUserControl.comboBoxField.Items.Add("<none>") If Not _MFields Is Nothing Then For lLoop = 0 To _MFields.FieldCount - 1 If _MFields.Field(lLoop).Type = esriFieldType.esriFieldTypeDouble Or _ _MFields.Field(lLoop).Type = esriFieldType.esriFieldTypeSingle Or _ _MFields.Field(lLoop).Type = esriFieldType.esriFieldTypeInteger Or _ _MFields.Field(lLoop).Type = esriFieldType.esriFieldTypeSmallInteger Or _ _MFields.Field(lLoop).Type = esriFieldType.esriFieldTypeString Then If UCase(_MFields.Field(lLoop).Name) <> "SHAPE_LENGTH" And _ UCase(_MFields.Field(lLoop).Name) <> "SHAPE_AREA" Then _CurveUserControl.comboBoxField.Items.Add(_MFields.Field(lLoop).Name) End If End If Next lLoop End If _Cancel = True _CurveUserControl.checkBoxTolerance.Checked = False _CurveUserControl.textBoxTolerance.Text = CStr(_Tolerance) _CurveUserControl.textBoxTolerance.Enabled = False _CurveUserControl.textBoxvalue.Text = "" _sFieldName = "" _CurveUserControl.comboBoxField.SelectedIndex = 0 End Sub ''' <summary> ''' Implementation class of the dockable window add-in. It is responsible for ''' creating and disposing the user interface class for the dockable window. ''' </summary> Public Class AddinImpl Inherits ESRI.ArcGIS.Desktop.AddIns.DockableWindow Private m_windowUI As CurveConversionDockWin Protected Overrides Function OnCreateChild() As System.IntPtr m_windowUI = New CurveConversionDockWin(Me.Hook) Return m_windowUI.Handle End Function Protected Overrides Sub Dispose(ByVal Param As Boolean) If m_windowUI IsNot Nothing Then m_windowUI.Dispose(Param) End If MyBase.Dispose(Param) End Sub End Class Private Sub CurveUpdate(ByVal _CheckTol As Boolean) Try 'Set up the progress bar. Dim _Status As IStatusBar = My.ArcMap.Application.StatusBar Dim _StepProg As IStepProgressor = _Status.ProgressBar With _StepProg .Position = 1 .MaxRange = _Editor.SelectionCount .Message = "Update progress:" .StepValue = 1 .Show() End With Dim lCount As Integer = 0 _InvalidEnv = Nothing 'You will get an error if your feature is stored in a shapefile. 'Check to make sure there is no existing edit operation, then start one. Dim _WorkspaceEdit As IWorkspaceEdit2 = DirectCast(_Editor.EditWorkspace, IWorkspaceEdit2) If Not _WorkspaceEdit.IsInEditOperation Then _Editor.StartOperation() End If Dim _Curve As ICurve Dim _Curve2 As ICurve Dim _OrigSegs As ISegmentCollection Dim _Polyline As ISegmentCollection Dim _MidPoint As IPoint Dim _NewLine As IConstructCircularArc Dim _bSegCheck As [Boolean] Dim _OutPoint As IPoint = New PointClass() Dim _Seg As ISegment Dim _Dist As [Double] = 0, _Dist1 As [Double] = 0, _Dist2 As [Double] = 0 Dim _Side As [Boolean] = False, _Updated As [Boolean] = False Dim _EdgeEnum As IEnumTopologyEdge Dim _Path As ISegmentCollection = New PathClass() Dim _TopoEdge As ITopologyEdge Dim _SomeLine As IPolyline Dim _EnumFeat As IEnumFeature = _Editor.EditSelection Dim feat As IFeature = _EnumFeat.[Next]() 'Check for a topology Dim _TopoGraph As ITopologyGraph = TopologyCheck(feat.[Class]) Do If feat.Shape.GeometryType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline And (Not IsStraight(feat)) Then 'Create the new segment based on a 3pt curve through the start point, mid point and end point of the feat geometry. _Curve = TryCast(feat.Shape, ICurve) _OrigSegs = TryCast(_Curve, ISegmentCollection) _MidPoint = New PointClass() _Curve.QueryPoint(ESRI.ArcGIS.Geometry.esriSegmentExtension.esriNoExtension, 0.5, True, _MidPoint) _NewLine = New CircularArcClass() _NewLine.ConstructThreePoints(_Curve.FromPoint, _MidPoint, _Curve.ToPoint, False) _Curve2 = TryCast(_NewLine, ICurve) 'Check that the segments are within the tolerance. _bSegCheck = False If _CheckTol Then For lLoop As Integer = 1 To _OrigSegs.SegmentCount - 1 _Seg = _OrigSegs.Segment(lLoop) _Curve2.QueryPointAndDistance(ESRI.ArcGIS.Geometry.esriSegmentExtension.esriNoExtension, _Seg.FromPoint, False, _MidPoint, _Dist, _Dist1, _ _Side) _Curve2.QueryPointAndDistance(ESRI.ArcGIS.Geometry.esriSegmentExtension.esriNoExtension, _Seg.ToPoint, False, _MidPoint, _Dist, _Dist2, _ _Side) If _Dist1 > _Tolerance Or _Dist2 > _Tolerance Then _bSegCheck = True Exit For End If Next End If If Not _bSegCheck Then If _TopoGraph IsNot Nothing Then _EdgeEnum = GetParents(feat, _TopoGraph) If _EdgeEnum Is Nothing Then 'not sure what i need to add, but to get here something went wrong. Else Dim Missing As Object = Type.Missing _Path.AddSegment(TryCast(_NewLine, ISegment), Missing, Missing) Select Case _EdgeEnum.Count Case 1 _EdgeEnum.Reset() _TopoEdge = _EdgeEnum.[Next]() _Updated = UpdateEdge(_TopoGraph, _TopoEdge, _Path) If _Updated Then UpdateField(feat, True) lCount += 1 End If Exit Select Case 2 _EdgeEnum.Reset() _TopoEdge = _EdgeEnum.[Next]() Do _SomeLine = TryCast(_TopoEdge.Geometry, IPolyline) Dim X1 As Double = _Path.Segment(0).FromPoint.X Dim Y1 As Double = _Path.Segment(0).FromPoint.Y Dim X2 As Double = _Path.Segment(0).ToPoint.X Dim Y2 As Double = _Path.Segment(0).ToPoint.Y If X1 = _SomeLine.FromPoint.X And Y1 = _SomeLine.FromPoint.Y And X2 = _SomeLine.ToPoint.X And Y2 = _SomeLine.FromPoint.Y Then _Updated = UpdateEdge(_TopoGraph, _TopoEdge, _Path) If _Updated Then UpdateField(feat, True) lCount += 1 End If Exit Do End If _TopoEdge = _EdgeEnum.[Next]() Loop While _TopoEdge IsNot Nothing Exit Select Case Else Exit Select End Select _EdgeEnum = Nothing End If Else 'the current feature is not part of a topo, so just update it. _Polyline = New PolylineClass() Dim Missing As Object = Type.Missing _Polyline.AddSegment(TryCast(_NewLine, ISegment), Missing, Missing) 'This code sets the polyline ZAware so it will handle Z aware features. 'However you need to check that the feature is Z aware first, so you can add this code here. 'Dim zAware as IZAware = _Polyline as IZAware 'zAware.ZAware = true feat.Shape = TryCast(_Polyline, IGeometry) UpdateField(feat, False) feat.Store() lCount += 1 If _InvalidEnv Is Nothing Then _InvalidEnv = feat.Shape.Envelope Else _InvalidEnv.Union(feat.Shape.Envelope) End If End If End If End If feat = _EnumFeat.[Next]() My.ArcMap.Application.StatusBar.ProgressBar.[Step]() Loop While feat IsNot Nothing If lCount = 0 Then MessageBox.Show("No features were updated.") _Editor.AbortOperation() Else MessageBox.Show(lCount & " feature(s) updated") _Editor.StopOperation("Update Curves") End If If _InvalidEnv IsNot Nothing Then Dim _Doc As IMxDocument = TryCast(My.ArcMap.Application.Document, IMxDocument) _Doc.ActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewAll, Nothing, _InvalidEnv) End If My.ArcMap.Application.StatusBar.ProgressBar.Hide() Catch ex As Exception MessageBox.Show("Error in updating the Curve, make sure you are not using a shapefile." + ex.Message) My.ArcMap.Application.StatusBar.ProgressBar.Hide() Return End Try End Sub Private Sub UpdateField(ByVal feat As IFeature, ByVal shouldStore As Boolean) Try Dim lFieldIndex As Integer = 0 If Not _sFieldName Is "<none>" Then lFieldIndex = feat.Fields.FindField(_sFieldName) If lFieldIndex > -1 Then _UpdateValue = textBoxvalue.Text feat.Value(lFieldIndex) = _UpdateValue Select Case feat.Fields.Field(lFieldIndex).Type Case esriFieldType.esriFieldTypeString feat.Value(lFieldIndex) = _UpdateValue.ToString() Case esriFieldType.esriFieldTypeInteger Or esriFieldType.esriFieldTypeString feat.Value(lFieldIndex) = Convert.ToInt32(_UpdateValue) Case esriFieldType.esriFieldTypeDouble Or esriFieldType.esriFieldTypeSingle feat.Value(lFieldIndex) = Convert.ToDouble(_UpdateValue) Case Else Return End Select If shouldStore Then feat.Store() End If End If End If Catch ex As Exception Return End Try End Sub Private Function UpdateEdge(ByVal topoGraph As ITopologyGraph, ByVal _TopoEdge As ITopologyEdge, ByVal _Path As ISegmentCollection) As Boolean Try Dim _NewSegs As ISegmentCollection = TryCast(_TopoEdge.Geometry, ISegmentCollection) Dim _Invalid As IEnvelope = New EnvelopeClass() Dim inCount As Integer = _NewSegs.SegmentCount topoGraph.SetEdgeGeometry(_TopoEdge, TryCast(_Path, IPath)) topoGraph.Post(_Invalid) If _InvalidEnv Is Nothing Then _InvalidEnv = _Invalid Else _InvalidEnv.Union(_Invalid) End If _NewSegs = TryCast(_TopoEdge.Geometry, ISegmentCollection) If _NewSegs.SegmentCount = 1 And inCount > 1 Then Return True Else Return False End If Catch e As Exception MessageBox.Show("Error in updating the topo edge " & e.Message) Return False End Try End Function Private Function GetParents(ByVal feat As IFeature, ByVal _TopoGraph As ITopologyGraph) As IEnumTopologyEdge Dim fFC As IFeatureClass = TryCast(feat.[Class], IFeatureClass) Dim _EnumTopoEdge As IEnumTopologyEdge = _TopoGraph.GetParentEdges(fFC, feat.OID) If _EnumTopoEdge Is Nothing Then _TopoGraph.SetEmpty() _TopoGraph.Build(feat.Shape.Envelope, False) _EnumTopoEdge = _TopoGraph.GetParentEdges(fFC, feat.OID) Else If _EnumTopoEdge.Count > 1 Then _TopoGraph.DeletePseudoNodesFromSelection() End If End If Return _EnumTopoEdge End Function ''' <summary> ''' Check to see if the line is straight. So we do NOT convert straight lines to polycurves. ''' </summary> ''' <param name="feat"></param> ''' <returns></returns> ''' <remarks></remarks> Private Function IsStraight(ByVal feat As IFeature) As Boolean Try If feat.Shape.GeometryType <> ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline Then Return True End If Dim _SR As ISpatialReference = feat.Shape.SpatialReference Dim _PolyCurve As IPolycurve = TryCast(feat.ShapeCopy, IPolycurve) Dim _SegColl As ISegmentCollection = TryCast(_PolyCurve, ISegmentCollection) Dim _x As Double Dim _y As Double Dim _units As Double _SR.GetFalseOriginAndUnits(_x, _y, _units) _PolyCurve.Generalize(2 / _units) If _SegColl.SegmentCount = 1 Then Return True Else Return False End If Catch e As Exception MessageBox.Show("Error in checking straight " & e.Message) Return False End Try End Function ''' <summary> ''' Checks to see if the feature class is part of a gdb or map topology. ''' If it is it will build the topo cache and return the topology graph. ''' </summary> ''' <param name="oBJClass"></param> ''' <returns></returns> ''' <remarks></remarks> Private Function TopologyCheck(ByVal oBJClass As IObjectClass) As ITopologyGraph Try Dim topoClass As ITopologyClass = TryCast(oBJClass, ITopologyClass) Dim topoGraph As ITopologyGraph If topoClass.IsInTopology Then If topoClass.Topology.Cache IsNot Nothing Then topoGraph = TryCast(topoClass.Topology.Cache, ITopologyGraph) Else topoGraph = Nothing End If Else 'Check to see if the class of the selected feature is part of a map topology. Dim mUID As UID = New UIDClass() mUID.Value = "esriEditor.TopologyExtension" Dim topoExt As ITopologyExtension = TryCast(My.ArcMap.Application.FindExtensionByCLSID(mUID), ITopologyExtension) Dim mapTopo As IMapTopology = topoExt.MapTopology Dim featClass As IFeatureClass = TryCast(oBJClass, IFeatureClass) Dim lID As Integer = mapTopo.FindClass(featClass) If lID > -1 Then topoGraph = mapTopo.Cache Else topoGraph = Nothing End If End If Return topoGraph Catch e As Exception MessageBox.Show("Error checking topology: " & e.Message) Return Nothing End Try End Function Private Sub checkBoxTolerance_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles checkBoxTolerance.CheckedChanged If checkBoxTolerance.Checked = False Then _CheckTol = False textBoxTolerance.Enabled = False Else _CheckTol = True textBoxTolerance.Enabled = True End If End Sub Private Sub comboBoxField_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles comboBoxField.SelectedIndexChanged Try If comboBoxField.SelectedIndex > 0 Then Dim lIndex As Integer = _MFields.FindField(comboBoxField.Text) If lIndex > -1 Then If _MFields.Field(lIndex).Type = esriFieldType.esriFieldTypeString Then _UpdateFieldIsString = True _sFieldName = _MFields.Field(lIndex).Name Else _UpdateFieldIsString = False _sFieldName = _MFields.Field(lIndex).Name End If Else 'resets the field to none. comboBoxField.SelectedIndex = 0 End If Else _UpdateFieldIsString = False End If Catch ex As Exception Return End Try End Sub End Class