Best practices for using dynamic display


This topic presents the best practices when using dynamic display in the ArcGIS framework. It introduces current usages and requirements, demonstrates several different approaches to the dynamic display of information in a geographic information system (GIS), and uses several references available in the ArcObjects Software Development Kit (SDK).

Using the dynamic display to enable the dynamic map

It is recommended to enable the dynamic map using the IDynamicMap interface that is implemented by the Map class. Use IDynamicMap to enable or disable the dynamic map (the dynamic display). See the following illustration:

When enabled, the dynamic display is creating an OpenGL rendering context to draw the basic map layers and on top of the base layers, draws the dynamic layers. When the dynamic map is enabled, this is considered as being in dynamic drawing mode.

Drawing in dynamic mode

The following are the two methods to draw in dynamic mode:
  • Implementation of IDynamicLayer using IDynamicLayer.DrawDynamicLayer
  • Listen to dynamic display events:
    • IDynamicMapEvents.BeforeDynamicDraw
    • IDynamicMapEvents.AfterDynamicDraw

Drawing options

The following are the two options for drawing:
  • Using dynamic display application programming interface (API)
  • Direct OpenGL API
By default, OpenGL textures are enabled. It is required to disable the OpenGL 2D texture flag when drawing OpenGL primitives.

Direct OpenGL API

If using the direct OpenGL API, the coordinate system's origin is the center of the window while the width and height are identical to the device frame dimensions.

Dynamic layers

A dynamic layer is a custom layer. To implement a custom layer, you need to, at a minimum, implement the ILayer interface. Implementing the ILayer interface enables the layer to be added to the map and the table of contents. To implement a dynamic layer, the custom layer needs to implement IDyamicLayer. The custom dynamic layer needs to implement the following:
DrawDynamicLayer
Draws the layer to the specified display for the given draw phase.
DynamicLayerDirty
Indicates if the dynamic layer has changed since last drawn for the specified draw phase.
DynamicRecompileRate
Indicates if the dynamic layer has changed since last drawn for the specified draw phase.
The dynamic display is an active display. This means that it has a fixed drawing cycle. During every drawing cycle, the dynamic display checks each dynamic layer's dirty property. If at least one of the dynamic layers is dirty, the dynamic display redraws all dynamic layers.

Drawing a dynamic layer

A dynamic layer has two primary draw phases: immediate and compiled. The compiled draw phase stores draw commands in a list. Dynamic display uses this list to draw the commands. The list is recreated when the dirty flag has been set. The immediate draw phase does not store draw commands. The draw commands of the immediate draw phase are immediately drawn.
When redrawing the display, the dynamic display iterates through the dynamic layers and does the following for each:
  • Checks if recompile is needed by checking the DynamicLayerDirty with the immediate phase. If any dynamic layer has set the dirty flag for the immediate phase, all dynamic layers DrawDynamicLayer method will be called with the immediate draw phase.
  • Draws the immediate phase and calls the DrawDynamicLayer method with the immediate phase.
  • Checks if recompile is needed by checking the DynamicLayerDirty (with the compiled phase) and the DynamicRecompileRate property.
  • If needed, recompile the dynamic layer by calling the DrawDynamicLayer method with the compiled phase.
  • Draw the compiled phase, by drawing the display list.
A layer will be recompiled (in compiled phase) when any refresh events or when the following conditions are met:
  • DynamicLayerDirty property is set to true
  • DynamicRecompileRate time from the previous recompile time has elapsed
The layer's DrawDynamicLayer method will be called with the following:
  • Compiled phase—When the layer needs to be recompiled
  • Immediate phase—When the layer needs to be redrawn
When redrawing the compiled phase of a dynamic layer, it is not necessary to call its DrawDynamicLayer method but only redraw the already compiled list. The DrawDynamicLayer method (of the compiled phase) is only called when needed to recompile. On the other hand, when redrawing the immediate phase of a layer, the DrawDynamicLayer method (of the immediate phase) is being called.

Draw cycle sequence (including DynamicMapEvents)

There are two DynamicMapEvents methods that can be used to draw objects. The two draw phases are esriDMDPLayers and esriDMDPDynamicLayers. During every draw cycle, the layers are being drawn and the dynamic map events are being fired in the following sequence:
  1. BeforeDynamicDraw(esriDMDPLayers) event is being fired
  2. Layers are drawn; these are the layers that do not support IDynamicLayers (static layers)
  3. AfterDynamicDraw(esriDMDPLayers) event is being fired
  4. BeforeDynamicDraw(esriDMDPDynamicLayers) event is being fired
  5. Dynamic layers are drawn
  6. Immediate phase (esriDDPImmediate)
  7. Compiled phase (esriDDPCompiled)
  8. AfterDynamicDraw(esriDMDPDynamicLayers) event is being fired
See the following illustration:

Drawing objects API

The dynamic display has the following methods for drawing into the OpenGL rendering context:
  • IDynamicLayer.DrawDynamicLayer
  • IDynamicMapEvents.BeforeDynamicDraw
  • IDynamicMapEvents.AfterDynamicDraw
In these methods, the user can draw using the OpenGL API or the dynamic display draw methods.
  • Use the IDynamicDisplay interface to draw objects in map coordintates. Use the IDynamicCompoundMarkerSymbol interface as an additional option for drawing character marker symbols with surrounding attribute text.
  • Use the IDynamicScreenDisplay interface to draw objects in screen coordinates. This origin uses the DisplayTransformation.DeviceFrame. In this case, it uses the upper-left of the screen.
  • Use the IDynamicGlyphFactory interface to create and delete dynamic glyphs. To get the interface to IDynamicGlyphFactory, use IDynamicDisplay.
  • Use the IDynamicSymbolProperties interface to control the dynamic symbols properties (dynamic marker, line, text, and fill).
  • Use the IDynamicGlyph interface to access properties of dynamic glyphs. A dynamic glyph is a handle to a resource.
  • Use the IDynamicMap interface to set the IDynamicMap.UseSubPixelRendering property.

Working with dynamic symbols

Dynamic symbols are used to draw objects that update dynamically. Dynamic symbols consist of marker, line, text, and fill properties that can be managed using the IDyanmicSymbolsProperties interface. The following table indicates the properties of each symbol component:
 
Marker
Line
Text
Fill
DynamicGlyph
v
v
v
 
Color
v
v
v
v
Heading
v
 
v
 
Smooth
v
v
v
 
Scale
v
v
v
 
Rotational alignment
v
 
v
 
Vertical alignment
 
 
v
 
Horizontal alignment
 
 
v
 
  • Symbol is a state of drawing:
    • Controls the symbol through IDynamicSymbolProperties
  • Needs to be synthesized through DynamicGlyph:
    • DynamicGlyph provides resource for symbol
  • DynamicSymbol types:
    • esriDSymbolMarker
    • esriDSymbolLine
    • esriDSymbolText
    • esriDSymbolFill
  • DynamicGlyph types:
    • esriDGlyphMarker
    • esriDGlyphLine
    • esriDGlyphText
Before drawing a symbol, set the DynamicSymbolProperties. Do the following to s et the DynamicSymbolProperites:
  • Get IDynamicGlyphFactory from the DynamicDisplay
  • Create marker
  • Load from bitmap (BMP)
  • PictureMarker.CreateFromFile
  • Create line
  • Create text
See the following table:
DynamicGlyph
Indicates the dynamic glyph for the specified dynamic symbol.
GetColor
Indicates the color for the specified dynamic symbol.
GetScale
Scales the dynamic symbol.
Heading
Indicates the heading for the specified dynamic symbol. Only valid if dynamic symbol rotation alignment is a heading and for text and marker.
RotationAlignment
Indicates the rotation alignment for the specified dynamic symbol. Only valid for text and marker.
SetColor
Indicates the color for the specified dynamic symbol.
SetScale
Scales the dynamic symbol.
Smooth
Indicates whether the specified dynamic symbol will be smooth. Only valid for text, line, and marker.
TextHorizontalAlignment
Indicates the horizontal alignment for the text dynamic symbol.
TextVerticalAlignment
Indicates the vertical alignment for the text dynamic symbol.

Dynamic glyph factory

The DynamicGlyphFactory is the engine used to create and delete glyphs used by the DynamicDisplaySymbol. The following are the definitions of a glyph:
  • Image of a typographical sign
  • Image used in the visual representation of characters; how a character looks. A font is a set of glyphs
  • A single unit of display in a font (Microsoft). It can be defined by the following:
    • An outline (in OpenType)
    • A bitmap
    • A set of graphic commands
  • DynamicGlyph:
    • Glyph using in the dynamic display environment
  • A handle of the resource for rendering dynamic symbols
See the following table:
CreateDynamicGlyph
Creates a dynamic glyph from a symbol.
CreateDynamicGlyphFromFile
Creates a dynamic glyph from a file.
DeleteDynamicGlyph
Deletes a dynamic glyph from a symbol.
DynamicGlyph
Retrieves a dynamic glyph from a glyph group.
Init
Initializes the dynamic glyph factory.
LoadDynamicGlyphsGroup
Loads an external dynamic glyph group from a file.
UnloadDynamicGlyphsGroup
Unloads an external dynamic glyph group from a file.

General guidelines for drawing dynamic layers

Using the compiled phase is recommended for drawing most layers. In the compiled phase it is not recommended to create dynamic glyphs or textures. Use the immediate phase to create dynamic glyphs and textures, for example, if you have one layer with many features that update every 20 seconds. In this case, it is recommended to redraw this in the compiled phase. If you have a layer you need to update at subsecond rates, draw it in the immediate phase.
When creating a dynamic glyph from text or a dynamic marker, keep in mind that when dynamic display is enabled, what was once white will become the color you choose. If created with a color, that color will become darker when enabled. However, black will remain black.
When drawing the dynamic layer using the DrawDynamicLayer method or when listening to DynamicMapEvents, it is recommended to initially cache (keep it as a class member) the DynamicGlyphFactory, the DynamicSymbolProperties, and the DynamicCompoundMarker. This is an efficient method considering the repetition of draw cycle sequences.

Draw rates

The default draw cycle is the actual draw time plus the draw rate. This means that the draw rate is the lag time between each two cycles. In this mode, you can consider the draw rate as sleep time between two draw cycles.
The following are the two types of DynamicMap events:
  • DynamicMapStarted and DynamicMapFinished—Fired on start and end of each dynamic map heart bit
  • BeforeDynamicDraw and AfterDynamicDraw—Fired on before and after the dynamic display drawing
The draw rate (actual cycle time) is between every two DynamicMapStarted events. The actual draw time is between every DynamicMapStarted and DynamicMapFinished events.

Improving performance when using dynamic display

There are several tips and tricks to keep in mind to improve performance when using dynamic display. To improve the dynamic display experience follow the tips below to obtain the best performance in dynamic display.
  • Remove unused layers—Check the table of contents to ensure that your map document is clear of layers that are unrelated to the map's purpose.
  • Set scale-dependentrendering for data layers—Use scale-dependentrendering to ensure that unneeded layers do not draw when the map is zoomed out. Data-intensive or detailed layers may be more appropriate only when the map is zoomed in to a larger scale.
  • Use consolidated group layers—Using consolidated group layers will display quicker faster than layers that are not consolidated.
  • Use annotation instead of labels—Since labels require the computer to make placement decisions, it's generally faster to use an annotation layer.
  • Set scale-dependentrendering for labels—When a map is zoomed out, more labels need to be drawn, which takes time. Examine your map document and determine if some labels do not need to be shown at smaller scales.
  • Use the most appropriate draw phase—The dynamic display has two draw phases, compiled and immediate (esriDDPCompiled and esriDDPImmediate respectively). The immediate draw phase should be used when data is highly dynamic and changes need to take place immediately. Compiled draw phase should be used when data are less dynamic by nature. In order to optimize the layer drawing, make sure to draw in the appropriate drawing phase for the layer. For example, if the layer is set to draw in an immediate mode, the input drawing phase should be inspected and only draw if enum esriDynamicDrawPhase is set to esriDDPImmediate. Otherwise, it will be drawing twice in each drawing cycle.
  • Check to see if dynamic symbols have already been created—When loading a new glyph within DrawDynamicLayer method, a flag should be set to indicate if dynamic glyphs have been created. This will ensure that dynamic glyphs are created only once. See code below.

In conclusion

Dynamic display has been an integral part of the map display pipeline since the ArcGIS 9.2 release. It provides an ArcObjects API for developers to leverage accelerated graphics technology when required. The dynamic display operates as another display mode. This means most other standard ArcGIS tools continue to work. Developers can define dynamic symbols that can be moved, oriented, scaled, or even animated in real-time.