About the Angle Angle shape constructor Sample
[C#]
AngleAngleCstr.cs
using ESRI.ArcGIS.ArcMapUI; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.Editor; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Framework; using ESRI.ArcGIS.esriSystem; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace AngleAngle { class AngleAngleCstr : IShapeConstructor, IPersist { IEditor m_editor; IEditSketch3 m_edSketch; ISnappingEnvironment m_snappingEnv; IPointSnapper m_snapper; ISnappingFeedback m_snappingFeedback; // Declare 3 points IPoint m_firstPoint; IPoint m_secondPoint; IPoint m_activePoint; // Declare 2 angles double m_firstAngle; double m_secondAngle; enum ToolPhase { Inactive, SecondPoint, Intersection } ToolPhase m_etoolPhase; #region IShapeConstructor Members public void Activate() { } public bool Active { get { return true; } } public void AddPoint(IPoint point, bool Clone, bool allowUndo) { } public IPoint Anchor { get { return Anchor; } } public double AngleConstraint { get { return AngleConstraint; } set { AngleConstraint = value; } } public esriSketchConstraint Constraint { get { return Constraint; } set { Constraint = value; } } public int Cursor { get { return 0; } } public void Deactivate() { } public double DistanceConstraint { get { return DistanceConstraint; } set { DistanceConstraint = value; } } public bool Enabled { get { return true; } } public string ID { get { return ("Angle Angle Constructor"); } } public void Initialize(IEditor pEditor) { // Initialize the constructor m_editor = pEditor as IEditor; m_edSketch = pEditor as IEditSketch3; //Get the snap environment m_snappingEnv = m_editor.Parent.FindExtensionByName("ESRI Snapping") as ISnappingEnvironment; m_snapper = m_snappingEnv.PointSnapper; m_snappingFeedback = new SnappingFeedbackClass(); m_snappingFeedback.Initialize(m_editor.Parent, m_snappingEnv, true); m_firstPoint = new PointClass(); m_secondPoint = new PointClass(); m_activePoint = new PointClass(); // Set the phase to inactive so we start at the beginning m_etoolPhase = ToolPhase.Inactive; } public bool IsStreaming { get { return IsStreaming; } set { IsStreaming = value; } } public IPoint Location { get { return Location; } } public bool OnContextMenu(int X, int Y) { return true; } public void OnKeyDown(int keyState, int shift) { // If the escape key is used, throw away the calculated point if (keyState == (int)Keys.Escape) m_etoolPhase = ToolPhase.Inactive; } public void OnKeyUp(int keyState, int shift) { } public void OnMouseDown(int Button, int shift, int X, int Y) { if (Button != (int)Keys.LButton) return; switch (m_etoolPhase) { case (ToolPhase.Inactive): GetFirstPoint(); break; case (ToolPhase.SecondPoint): GetSecondPoint(); break; case (ToolPhase.Intersection): GetIntersection(); break; } } public void OnMouseMove(int Button, int shift, int X, int Y) { //Snap the mouse location if (m_etoolPhase != ToolPhase.Intersection) { m_activePoint = m_editor.Display.DisplayTransformation.ToMapPoint(X, Y); ISnappingResult snapResult = m_snapper.Snap(m_activePoint); m_snappingFeedback.Update(snapResult, 0); if (snapResult != null) m_activePoint = snapResult.Location; } } public void OnMouseUp(int Button, int shift, int X, int Y) { } public void Refresh(int hdc) { m_snappingFeedback.Refresh(hdc); } public void SketchModified() { } #endregion private void GetFirstPoint() { INumberDialog numDialog = new NumberDialogClass(); // Set first point to the active point which may have been snapped m_firstPoint = m_activePoint; // Get the angle if (numDialog.DoModal("Angle 1", 45, 2, m_editor.Display.hWnd)) { m_firstAngle = numDialog.Value * Math.PI / 180; m_etoolPhase = ToolPhase.SecondPoint; } } private void GetSecondPoint() { INumberDialog numDialog = new NumberDialogClass(); // Set the second point equal to the active point which may have been snapped m_secondPoint = m_activePoint; // Get the angle if (numDialog.DoModal("Angle 2", -45, 2, m_editor.Display.hWnd)) { m_secondAngle = numDialog.Value * Math.PI / 180; } else { m_etoolPhase = ToolPhase.Inactive; return; } // Get the intersection point IConstructPoint constructPoint = new PointClass(); constructPoint.ConstructAngleIntersection(m_firstPoint, m_firstAngle, m_secondPoint, m_secondAngle); IPoint point = constructPoint as IPoint; if (point.IsEmpty) { m_etoolPhase = ToolPhase.Inactive; MessageBox.Show("No Point Calculated"); return; } // Draw the calculated intersection point and erase previous snap feedback m_activePoint = point; m_etoolPhase = ToolPhase.Intersection; m_snappingFeedback.Update(null, 0); DrawPoint(m_activePoint); } private void GetIntersection() { IEditSketch editSketch = m_editor as IEditSketch; editSketch.AddPoint(m_activePoint, true); // Set the phase to inactive, back to beginning m_etoolPhase = ToolPhase.Inactive; } private void DrawPoint(IPoint pPoint) { //Draw a red graphic dot on the display at the given point location IRgbColor color = null; ISimpleMarkerSymbol marker = null; IAppDisplay appDisplay = m_editor.Display as IAppDisplay; //Set the symbol (red, size 8) color = new RgbColor(); color.Red = 255; color.Green = 0; color.Blue = 0; marker = new SimpleMarkerSymbol(); marker.Color = color; marker.Size = 8; //Draw the point appDisplay.StartDrawing(0, (short)esriScreenCache.esriNoScreenCache); appDisplay.SetSymbol(marker as ISymbol); appDisplay.DrawPoint(pPoint); appDisplay.FinishDrawing(); } #region IPersist Members public void GetClassID(out Guid pClassID) { //Explicitly set a guid. Used to set command.checked property pClassID = new Guid("edb83080-999d-11de-8a39-0800200c9a66"); } #endregion } }
[Visual Basic .NET]
AngleAngleCstr.vb
Imports ESRI.ArcGIS.ArcMapUI Imports ESRI.ArcGIS.Controls Imports ESRI.ArcGIS.Editor Imports ESRI.ArcGIS.Display Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.Framework Imports ESRI.ArcGIS.esriSystem Imports System.Runtime.InteropServices Imports System.Windows.Forms <ComClass(AngleAngleCstr.ClassId, AngleAngleCstr.InterfaceId, AngleAngleCstr.EventsId), _ ProgId("AngleAngleVB.AngleAngleCstr")> _ Public Class AngleAngleCstr Implements IShapeConstructor, IPersist #Region "COM GUIDs" ' These GUIDs provide the COM identity for this class ' and its COM interfaces. If you change them, existing ' clients will no longer be able to access the class. Public Const ClassId As String = "cdcbb1bf-a87d-4927-8e75-9babe1979f90" Public Const InterfaceId As String = "2bb643ed-bb80-4203-983c-16eef50d859a" Public Const EventsId As String = "48d4380d-2fdb-4163-94ad-a4c11124a308" #End Region Dim m_editor As IEditor3 Dim m_edSketch As IEditSketch3 Dim m_snappingEnv As ISnappingEnvironment Dim m_snapper As IPointSnapper Dim m_snappingFeedback As ISnappingFeedback 'Declare 3 points Dim m_firstPoint As IPoint Dim m_secondPoint As IPoint Dim m_activePoint As IPoint 'Declare 2 angles Dim m_firstAngle As Double Dim m_secondAngle As Double Dim m_etoolPhase As ToolPhase Enum ToolPhase Inactive SecondPoint Intersection End Enum ' A creatable COM class must have a Public Sub New() ' with no parameters, otherwise, the class will not be ' registered in the COM registry and cannot be created ' via CreateObject. Public Sub New() MyBase.New() End Sub #Region "IShapeConstructor implementation" Public Sub Activate() Implements IShapeConstructor.Activate End Sub Public ReadOnly Property Active() As Boolean Implements IShapeConstructor.Active Get Return True End Get End Property Public Sub AddPoint(ByVal point As IPoint, ByVal Clone As Boolean, ByVal allowUndo As Boolean) Implements IShapeConstructor.AddPoint End Sub Public ReadOnly Property Anchor() As IPoint Implements IShapeConstructor.Anchor Get Return Nothing End Get End Property Public Property AngleConstraint() As Double Implements IShapeConstructor.AngleConstraint Get Return Nothing End Get Set(ByVal value As Double) End Set End Property Public Property Constraint() As esriSketchConstraint Implements IShapeConstructor.Constraint Get Return Nothing End Get Set(ByVal value As esriSketchConstraint) End Set End Property Public ReadOnly Property Cursor() As Integer Implements IShapeConstructor.Cursor Get Return 0 End Get End Property Public Sub Deactivate() Implements IShapeConstructor.Deactivate End Sub Public Property DistanceConstraint() As Double Implements IShapeConstructor.DistanceConstraint Get Return Nothing End Get Set(ByVal value As Double) End Set End Property Public ReadOnly Property Enabled() As Boolean Implements IShapeConstructor.Enabled Get Return True End Get End Property Public ReadOnly Property ID() As String Implements IShapeConstructor.ID Get Return "" End Get End Property Public Sub Initialize(ByVal pEditor As IEditor) Implements IShapeConstructor.Initialize 'Initialize the shape constructor m_editor = pEditor m_edSketch = pEditor 'Get the snap environment m_snappingEnv = m_editor.Parent.FindExtensionByName("ESRI Snapping") m_snapper = m_snappingEnv.PointSnapper m_snappingFeedback = New SnappingFeedbackClass() m_snappingFeedback.Initialize(m_editor.Parent, m_snappingEnv, True) m_firstPoint = New PointClass() m_secondPoint = New PointClass() m_activePoint = New PointClass() 'Set the phase to inactive so we start at the beginning m_etoolPhase = ToolPhase.Inactive End Sub Public Property IsStreaming() As Boolean Implements IShapeConstructor.IsStreaming Get Return Nothing End Get Set(ByVal value As Boolean) End Set End Property Public ReadOnly Property Location() As IPoint Implements IShapeConstructor.Location Get Return Nothing End Get End Property Public Function OnContextMenu(ByVal X As Integer, ByVal Y As Integer) As Boolean Implements IShapeConstructor.OnContextMenu Return True End Function Public Sub OnKeyDown(ByVal keyState As Integer, ByVal shift As Integer) Implements IShapeConstructor.OnKeyDown 'If the escape key is used, throw away the calculated point If (keyState = Keys.Escape) Then m_etoolPhase = ToolPhase.Inactive End If End Sub Public Sub OnKeyUp(ByVal keyState As Integer, ByVal shift As Integer) Implements IShapeConstructor.OnKeyUp End Sub Public Sub OnMouseDown(ByVal Button As Integer, ByVal shift As Integer, ByVal X As Integer, ByVal Y As Integer) Implements IShapeConstructor.OnMouseDown If (Button <> Keys.LButton) Then Return End If Select Case m_etoolPhase Case (ToolPhase.Inactive) GetFirstPoint() Case (ToolPhase.SecondPoint) GetSecondPoint() Case (ToolPhase.Intersection) GetIntersection() End Select End Sub Public Sub OnMouseMove(ByVal Button As Integer, ByVal shift As Integer, ByVal X As Integer, ByVal Y As Integer) Implements IShapeConstructor.OnMouseMove 'Snap the mouse location If (m_etoolPhase <> ToolPhase.Intersection) Then m_activePoint = m_editor.Display.DisplayTransformation.ToMapPoint(X, Y) Dim snapResult As ISnappingResult = m_snapper.Snap(m_activePoint) m_snappingFeedback.Update(snapResult, 0) If (snapResult Is Nothing) Then m_activePoint = snapResult.Location End If End If End Sub Public Sub OnMouseUp(ByVal Button As Integer, ByVal shift As Integer, ByVal X As Integer, ByVal Y As Integer) Implements IShapeConstructor.OnMouseUp End Sub Public Sub Refresh(ByVal hdc As Integer) Implements IShapeConstructor.Refresh m_snappingFeedback.Refresh(hdc) End Sub Public Sub SketchModified() Implements IShapeConstructor.SketchModified End Sub #End Region Private Sub GetFirstPoint() Dim numDialog As INumberDialog = New NumberDialogClass() 'Set first point to the active point which may have been snapped m_firstPoint = m_activePoint 'Get the angle If (numDialog.DoModal("Angle 1", 45, 2, m_editor.Display.hWnd)) Then m_firstAngle = numDialog.Value * Math.PI / 180 m_etoolPhase = ToolPhase.SecondPoint End If End Sub Private Sub GetSecondPoint() Dim numDialog As INumberDialog = New NumberDialogClass() 'Set the second point equal to the active point which may have been snapped m_secondPoint = m_activePoint 'Get the angle If (numDialog.DoModal("Angle 2", -45, 2, m_editor.Display.hWnd)) Then m_secondAngle = numDialog.Value * Math.PI / 180 Else m_etoolPhase = ToolPhase.Inactive End If 'Get the intersection point Dim constructPoint As IConstructPoint = New PointClass() constructPoint.ConstructAngleIntersection(m_firstPoint, m_firstAngle, m_secondPoint, m_secondAngle) Dim point As IPoint = constructPoint If (Point.IsEmpty) Then m_etoolPhase = ToolPhase.Inactive MessageBox.Show("No Point Calculated") End If 'Draw the calculated intersection point and erase previous snap feedback m_activePoint = point m_etoolPhase = ToolPhase.Intersection m_snappingFeedback.Update(Nothing, 0) DrawPoint(m_activePoint) End Sub Private Sub GetIntersection() Dim editSketch As IEditSketch = m_editor editSketch.AddPoint(m_activePoint, True) 'Set the phase to inactive, back to beginning m_etoolPhase = ToolPhase.Inactive End Sub Private Sub DrawPoint(ByVal pPoint As IPoint) 'Draw a red graphic dot on the display at the given point location Dim color As IRgbColor Dim marker As ISimpleMarkerSymbol Dim appDisplay As IAppDisplay = m_editor.Display 'Set the symbol (red, size 8) color = New RgbColor() color.Red = 255 color.Green = 0 color.Blue = 0 marker = New SimpleMarkerSymbol() marker.Color = color marker.Size = 8 'Draw the point appDisplay.StartDrawing(0, CShort(esriScreenCache.esriNoScreenCache)) appDisplay.SetSymbol(marker) appDisplay.DrawPoint(pPoint) appDisplay.FinishDrawing() End Sub Public Sub GetClassID(ByRef pClassID As System.Guid) Implements IPersist.GetClassID 'Explicitly set a guid. Used to set command.checked property pClassID = New Guid("cdcbb1bf-a87d-4927-8e75-9babe1979f90") End Sub End Class