ArcObjects Library Reference  

AngleAngleCstr

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