How to draw polygon buffers


This sample responds to the focus map's OnSelectionChanged event where it creates, and draws on the display, a new polygon representing a buffer region around the feature selection. To persist the drawing on the display, the sample draws the polygon in the Map's AfterItemDraw event.

How to use

  1. Open the VBA editor in ArcMap and paste the code into ThisDocument.
  2. Modify the buffer distance, currently it is set to 0.1.
  3. Execute the InitEvents routine to setup the event listener.
  4. Select one or more features - a new buffered polygon should be drawn around them.
  5. When you pan the map or zoom in/out, the polygon buffer redraws itself.
[VBA]
Option Explicit

Private WithEvents ActiveViewEvents As Map

Private m_pMxDoc As IMxDocument
Private m_pBufferPolygon As IPolygon
Private m_pLastBufferedExtent As IEnvelope
Private m_pFillSymbol As ISimpleFillSymbol

Public Sub InitEvents()
    Dim pViewManager As IViewManager
    Dim pRgbColor As IRgbColor
    
    Set m_pMxDoc = Application.Document
    Set pViewManager = m_pMxDoc.FocusMap
    pViewManager.VerboseEvents = True
    Set ActiveViewEvents = m_pMxDoc.FocusMap
    
    'Create a fill symbol
    Set m_pFillSymbol = New SimpleFillSymbol
    Set pRgbColor = New RgbColor
    pRgbColor.Red = 255
    m_pFillSymbol.Style = esriSFSForwardDiagonal
    m_pFillSymbol.Color = pRgbColor
End Sub

Private Sub ActiveViewEvents_AfterItemDraw(ByVal Index As Integer, ByVal display As IDisplay, ByVal phase As esriDrawPhase)
    
    'Only draw in the geography phase
    If Not phase = esriDPGeography Then Exit Sub
    'Draw the buffered polygon
    If m_pBufferPolygon Is Nothing Then Exit Sub
    With display
        .SetSymbol m_pFillSymbol
        .DrawPolygon m_pBufferPolygon
    End With
    
End Sub

Private Sub ActiveViewEvents_SelectionChanged()
    Dim pActiveView As IActiveView
    Dim pEnumFeature As IEnumFeature
    Dim pFeature As IFeature
    Dim pPolygon As IPolygon
    Dim pTopoOperator As ITopologicalOperator
    Dim pGeometryBag As IGeometryCollection
    
    Set pActiveView = m_pMxDoc.FocusMap
    Set pGeometryBag = New GeometryBag
    
    'Flag last buffered region for invalidation
    If Not m_pLastBufferedExtent Is Nothing Then
        pActiveView.PartialRefresh esriViewGeography, Nothing, m_pLastBufferedExtent
    End If
    
    If m_pMxDoc.FocusMap.SelectionCount = 0 Then
        'Nothing selected; don't draw anything; bail
        Set m_pBufferPolygon = Nothing
        Exit Sub
    End If
    
    'Buffer each selected feature
    Set pEnumFeature = m_pMxDoc.FocusMap.FeatureSelection
    pEnumFeature.Reset
    Set pFeature = pEnumFeature.Next
    Do While Not pFeature Is Nothing
        Set pTopoOperator = pFeature.Shape
        Set pPolygon = pTopoOperator.Buffer(0.1)
        pGeometryBag.AddGeometry pPolygon
        'Get next feature
        Set pFeature = pEnumFeature.Next
    Loop
    
    'Union all the buffers into one polygon
    Set m_pBufferPolygon = New Polygon
    Set pTopoOperator = m_pBufferPolygon 'QI
    pTopoOperator.ConstructUnion pGeometryBag
    
    Set m_pLastBufferedExtent = m_pBufferPolygon.Envelope
    
    'Flag new buffered region for invalidation
    pActiveView.PartialRefresh esriViewGeography, Nothing, m_pBufferPolygon.Envelope
    
End Sub