ObjectLocationClass.vb
Dynamic display — tracking dynamic object
ObjectLocationClass.vb
' Copyright 2006 ESRI
' 
' All rights reserved under the copyright laws of the United States
' and applicable international laws, treaties, and conventions.
' 
' You may freely redistribute and use this sample code, with or
' without modification, provided you include the original copyright
' notice and use restrictions.
' 
' See the use restrictions.
' 

Imports Microsoft.VisualBasic
Imports System
Imports System.Data
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Collections.Generic
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.SystemUI

''' <summary>
''' A custom layer used in order to draw the tracked object position
''' </summary>
<Guid("73C999A1-9CCE-4b36-BC65-16D8074C5CB5"), ComVisible(True), ClassInterface(ClassInterfaceType.None), ProgId("DynamicObjectTracking.ObjectLocationClass")> _
Public NotInheritable Class ObjectLocationClass : Inherits CustomLayerBase : Implements IDynamicLayer

#Region "class members"
  Private m_trailLength As Integer = 10
  Private m_point As IPoint = Nothing
  Private m_dynamicGlyphFactory As IDynamicGlyphFactory = Nothing
  Private m_dynamicSymbolProps As IDynamicSymbolProperties = Nothing
  Private m_nDynamicRecompileRate As Integer = -1
  Private m_bIsImmediateDirty As Boolean = False
  Private m_bOnce As Boolean = True
  Private m_bDynamicGlyphsCreated As Boolean = False
  Private m_markerGlyphs As IDynamicGlyph() = Nothing
#End Region

#Region "class constructor"
  Public Sub New()
    MyBase.New()
    'set the name of the layer
    Me.m_sName = "Tracks"

    'add additional column to the table to store the navigation data
    m_table.Columns.Add("NavigationData", GetType(NavigationData)) '1

    m_point = New PointClass()

    'set an array to store the glyphs used to symbol the tracked object
    m_markerGlyphs = New IDynamicGlyph(1) {}
  End Sub
#End Region


  ''' <summary>
  ''' the ILayer.Draw method. Declared as an abstract by the base class and thus must be overriden
  ''' </summary>
  ''' <param name="drawPhase"></param>
  ''' <param name="Display"></param>
  ''' <param name="trackCancel"></param>
  Public Overrides Sub Draw(ByVal drawPhase As esriDrawPhase, ByVal Display As IDisplay, ByVal trackCancel As ITrackCancel)

  End Sub

  Public Overrides ReadOnly Property ID() As ESRI.ArcGIS.esriSystem.UID
    Get
      m_uid.Value = "DynamicObjectTracking.ObjectLocationClass"
      Return m_uid
    End Get
  End Property

  ''' <summary>
  ''' add new navigation info for the tracked object
  ''' </summary>
  ''' <param name="navigationData"></param>
  Public Sub AddNavigationData(ByVal navigationData As NavigationData)
    Try
      'create a new record in the layer's table
      Dim r As DataRow = MyBase.NewItem()
      'assign the navigation info data into the new record
      r(1) = navigationData

      'add the record to the table
      SyncLock m_table
        MyBase.AddItem(r)
      End SyncLock

      'get read of old records
      If MyBase.NumOfRecords > m_trailLength Then
        'delete the first item
        Dim oldRow As DataRow = MyBase.Item(0)
        SyncLock m_table
          oldRow.Delete()
          m_table.AcceptChanges()
        End SyncLock
      End If
    Catch ex As Exception
      System.Diagnostics.Trace.WriteLine(ex.Message)
    End Try
  End Sub
  ''' <summary>
  ''' control over the tracked item last locations trail
  ''' </summary>
  Public Property TrailLength() As Integer
    Get
      Return m_trailLength
    End Get
    Set(ByVal value As Integer)
      m_trailLength = value
    End Set
  End Property

#Region "IDynamicLayer Members"

  ''' <summary>
  ''' The dynamic layer draw method
  ''' </summary>
  ''' <param name="DynamicDrawPhase">the current drawphase of the drawing</param>
  ''' <param name="Display">the ActiveView's display</param>
  ''' <param name="DynamicDisplay">the ActiveView's dynamic display</param>
  Public Sub DrawDynamicLayer(ByVal DynamicDrawPhase As ESRI.ArcGIS.Display.esriDynamicDrawPhase, ByVal Display As ESRI.ArcGIS.Display.IDisplay, ByVal DynamicDisplay As ESRI.ArcGIS.Display.IDynamicDisplay) Implements ESRI.ArcGIS.Carto.IDynamicLayer.DrawDynamicLayer
    Try
      If Display Is Nothing OrElse (Not Me.m_visible) Then
        Return
      End If

      'make sure that the current drawphase if immediate
      If esriDynamicDrawPhase.esriDDPImmediate <> DynamicDrawPhase Then
        Return
      End If

      If m_bOnce Then
        'cast the DynamicDisplay into DynamicGlyphFactory
        m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory
        'cast the DynamicDisplay into DynamicSymbolProperties
        m_dynamicSymbolProps = TryCast(DynamicDisplay, IDynamicSymbolProperties)
        m_bOnce = False
      End If

      'create the dynamic symbols for the layer
      If (Not m_bDynamicGlyphsCreated) Then
        Me.CreateDynamicSymbols(m_dynamicGlyphFactory)

        m_bDynamicGlyphsCreated = True
      End If

      'set the symbol alignment so that it will align with towards the symbol heading
      m_dynamicSymbolProps.RotationAlignment(esriDynamicSymbolType.esriDSymbolMarker) = esriDynamicSymbolRotationAlignment.esriDSRANorth

      Dim navigationData As NavigationData
      Dim i As Integer = 0

      'iterate through the records of the dynamic object locations
      For Each r As DataRow In Me
        If Not r(1) Is DBNull.Value Then

          'set the symbol's properties
          If i = (m_trailLength - 1) Then 'in case of the current location record
            m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.3F, 1.3F)
            m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0F, 0.0F, 0.0F, 1.0F) ' RED
            m_dynamicSymbolProps.DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker) = m_markerGlyphs(0)
          Else 'for each of the trail locations record
            m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0F, 1.0F)
            m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 0.0F, 1.0F, 0.0F, 1.0F) ' GREEN
            m_dynamicSymbolProps.DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker) = m_markerGlyphs(1)
          End If
          i += 1

          'get the navigation data from the record
          navigationData = CType(r(1), NavigationData)
          'assign the coordinate to the map point
          m_point.PutCoords(navigationData.X, navigationData.Y)

          'set the heading of the current symbol
          m_dynamicSymbolProps.Heading(esriDynamicSymbolType.esriDSymbolMarker) = CSng(navigationData.Azimuth)

          'draw the current location
          DynamicDisplay.DrawMarker(m_point)
        End If
      Next r
    Catch ex As Exception
      System.Diagnostics.Trace.WriteLine(ex.Message)
    End Try
  End Sub

  ''' <summary>
  ''' set the dirty flag of the layer
  ''' </summary>
  ''' <param name="DynamicDrawPhase"></param>
  Public Property DynamicLayerDirty(ByVal DynamicDrawPhase As ESRI.ArcGIS.Display.esriDynamicDrawPhase) As Boolean Implements ESRI.ArcGIS.Carto.IDynamicLayer.DynamicLayerDirty
    Get
      If DynamicDrawPhase = esriDynamicDrawPhase.esriDDPImmediate Then
        Return m_bIsImmediateDirty
      End If
    End Get
    Set(ByVal value As Boolean)
      If DynamicDrawPhase = esriDynamicDrawPhase.esriDDPImmediate Then
        m_bIsImmediateDirty = value
      End If
    End Set
  End Property

  ''' <summary>
  ''' Return the rate in which display lists gets recompiled. This is only relevant
  ''' for items that gets drawn using the 'esriDynamicDrawPhase.esriDDPCompiled' drawphase.
  ''' </summary>
  Public ReadOnly Property DynamicRecompileRate() As Integer Implements ESRI.ArcGIS.Carto.IDynamicLayer.DynamicRecompileRate
    Get
      Return m_nDynamicRecompileRate
    End Get
  End Property

#End Region


  ''' <summary>
  ''' create the layer's glyphs used to set the symbol of the tracked object
  ''' </summary>
  ''' <param name="pDynamicGlyphFactory"></param>
  Private Sub CreateDynamicSymbols(ByVal pDynamicGlyphFactory As IDynamicGlyphFactory)
    Try
      ' Sets the transparency color
      Dim tranparencyColor As IRgbColor = New RgbColorClass()
      tranparencyColor.Red = 0
      tranparencyColor.Green = 0
      tranparencyColor.Blue = 0

      Dim color As IRgbColor = New RgbColorClass()
      color.Red = 255
      color.Green = 255
      color.Blue = 255


      ' Create Character Marker Symbols
      ' -------------------------------
      Dim fontEsri As stdole.IFont
      fontEsri = New stdole.StdFontClass()
      fontEsri.Name = "ESRI Default Marker"
      fontEsri.Size = 32
      Dim characterMarkerSymbol As ICharacterMarkerSymbol = New CharacterMarkerSymbolClass()
      characterMarkerSymbol.Color = TryCast(color, IColor)
      characterMarkerSymbol.Font = TryCast(fontEsri, stdole.IFontDisp)
      characterMarkerSymbol.Size = 40
      characterMarkerSymbol.Angle = 0
      characterMarkerSymbol.CharacterIndex = 73

      'create the glyph from the marker symbol
      m_markerGlyphs(0) = pDynamicGlyphFactory.CreateDynamicGlyph(TryCast(characterMarkerSymbol, ISymbol))

      characterMarkerSymbol.Size = 32
      characterMarkerSymbol.CharacterIndex = 72

      'create the glyph from the marker symbol
      m_markerGlyphs(1) = pDynamicGlyphFactory.CreateDynamicGlyph(TryCast(characterMarkerSymbol, ISymbol))
    Catch ex As Exception
      System.Diagnostics.Trace.WriteLine(ex.Message)
    End Try
  End Sub
End Class