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