Best practices for using dynamic display


Summary
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).

In this topic


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:
 
 
See the following code example for enabling the dynamic map:
[Java]
//Cast the dynamic map from the focus map.
IDynamicMap dynamicMap = (IDynamicMap)hookHelper.getFocusMap();
//Make sure to switch into dynamic mode.
if (!dynamicMap.isDynamicMapEnabled())
    dynamicMap.setDynamicMapEnabled(true);
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:
 
Drawing options
The following are the two options for drawing:
By default, OpenGL textures are enabled. It is required to disable the OpenGL 2D texture flag when drawing OpenGL primitives.

Drawing marker symbols using the dynamic display API

The following code example demonstrates drawing a marker symbol using the dynamic display application programming interface (API):
 
[Java]
IDynamicSymbolProperties dynamicSymbolProps = ...;
IDynamicGlyph markerGlyph = ...;
//Set the marker symbol.
dynamicSymbolProps.setDynamicGlyphByRef(esriDynamicSymbolType.esriDSymbolMarker,
    markerGlyph);
IDynamicDisplay dynamicDisplay = ...;
//Draw a marker symbol.
dynamicDisplay.drawMarker(point);
In the following code example, drawing is done using a compound marker symbol using the dynamic display API:
[Java]
IDynamicSymbolProperties dynamicSymbolProps = ...;
IDynamicGlyph markerGlyph = ...;
//Draw the item as a compound marker. This means that you do not have to draw the items and its
//accompanying labels separately, thus allowing you to write less code and better set
//the marker symbol.
dynamicSymbolProps.setDynamicGlyphByRef(esriDynamicSymbolType.esriDSymbolMarker,
    markerGlyph);
IDynamicCompoundMarker dynamicCompoundMarker = ...;
//Drawing a compound marker symbol using six strings.
dynamicCompoundMarker.drawCompoundMarker6(point, "TOP", "BOTTOM", "LEFT1", "LEFT2", 
    "RIGHT1", "RIGHT2");

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. See the following code example:
 
[Java]
// Tell JOGL that we are going to use our own OpenGL Context
GLContext context = GLDrawableFactory.getFactory().createExternalGLContext();
context.makeCurrent();
GL gl = context.getGL();

gl.glDisable(GL.GL_TEXTURE_2D);
gl.glPushMatrix();
gl.glLoadIdentity();

// Draw a simple point.
gl.glBegin(GL.GL_POINTS);
gl.glColor3f(1.0f, 1.0f, 0.0f); //Yellow
gl.glVertex2f((float)x, (float)y);
gl.glEnd();

gl.glPopMatrix();
gl.glEnable(GL.GL_TEXTURE_2D);
See How to draw a bitmap element using OpenGL for more information on drawing direct OpenGL using textured geometries.
 

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:
Method
Draws the layer to the specified display for the given draw phase.
Read/write property
Indicates if the dynamic layer has changed since last drawn for the specified draw phase.
Read-only property
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:
 
The following code example demonstrates drawing a dynamic layer in immediate mode:
 
[Java]
public void drawDynamicLayer(int phase, IDisplay display, IDynamicDisplay
    dynamicDisplay){
    //Make sure the current draw phase is immediate. In this example, there is no use of the
    //compiled draw phase. Use the esriDDPCompiled draw phase to draw semi-static items (items
    //whose update rate is lower than the display update rate).
    if (phase != esriDynamicDrawPhase.esriDDPImmediate)
        return ;
    //Actual drawing to take place here. 
    //Set the dirty flag to true to let the dynamic display that the layer needs to be redrawn.
    this.setDynamicLayerDirty(phase, true);
}
A layer will be recompiled (in compiled phase) when any refresh events or when the following conditions are met:
 
The layer's DrawDynamicLayer method will be called with the following:
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:

The following code example demonstrates drawing in the AfterDynamicDraw on top of the dynamic layers:
 
[Java]
map.addIDynamicMapEventsListener(new IDynamicMapEventsAdapter(){
    public void afterDynamicDraw(IDynamicMapEventsAfterDynamicDrawEvent event)throws
        IOException, AutomationException{
        //Make sure we only draw after the dynamic layers have been drawn
        if (event.getDynamicMapDrawPhase() !=
            esriDynamicMapDrawPhase.esriDMDPDynamicLayers)return ; 
        //Do the drawings in here.
    }
}

    ;

Drawing objects API

The dynamic display has the following methods for drawing into the OpenGL rendering context:
 
In these methods, the user can draw using the OpenGL API or the dynamic display draw methods.  

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
?
?
?
 
Color
?
?
?
?
Heading
?
 
?
 
Smooth
?
?
?
 
Scale
?
?
?
 
Rotational alignment
?
 
?
 
Vertical alignment
 
 
?
 
Horizontal alignment
 
 
?
 
 
Before drawing a symbol, set the DynamicSymbolProperties. Do the following to s et the DynamicSymbolProperites:
 
See the following table:
 
Read/write property
Indicates the dynamic glyph for the specified dynamic symbol.
Method
Indicates the color for the specified dynamic symbol.
Method
Scales the dynamic symbol.
Read/write property
Indicates the heading for the specified dynamic symbol. Only valid if dynamic symbol rotation alignment is a heading and for text and marker.
Read/write property
Indicates the rotation alignment for the specified dynamic symbol. Only valid for text and marker.
Method
Indicates the color for the specified dynamic symbol.
Method
Scales the dynamic symbol.
Read/write property
Indicates whether the specified dynamic symbol will be smooth. Only valid for text, line, and marker.
Read/write property
Indicates the horizontal alignment for the text dynamic symbol.
Read/write property
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:
 
See the following table:
 
Method
Creates a dynamic glyph from a symbol.
Method
Creates a dynamic glyph from a file.
Method
Deletes a dynamic glyph from a symbol.
Read-only property
Retrieves a dynamic glyph from a glyph group.
Method
Initializes the dynamic glyph factory.
Method
Loads an external dynamic glyph group from
a file.
Method
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.
 
See the following code example:
 
[Java]
private boolean doOnce = true;
private IDynamicGlyphFactory dynamicGlyphFactory = null;
private IDynamicSymbolProperties dynamicSymbolProps = null;
IDynamicCompoundMarker dynamicCompoundMarker = null;
public void drawDynamicLayer(int phase, IDisplay display, IDynamicDisplay
    dynamicDisplay){
    ... if (doOnce){
        //Cast the dynamic display into dynamic glyph factory.
        dynamicGlyphFactory = dynamicDisplay.getDynamicGlyphFactory();
        //Cast the dynamic display into dynamic symbol properties.
        dynamicSymbolProps = (IDynamicSymbolProperties)dynamicDisplay;
        //Cast the compound marker symbol.
        dynamicCompoundMarker = (IDynamicCompoundMarker)dynamicDisplay;
        //Do other initializations in here.
        doOnce = false;
    }
    ...
}

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:
 
The draw rate (actual cycle time) is between every two DynamicMapStarted events. The actual draw time is between every DynamicMapStarted and DynamicMapFinished events.
 

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.


See Also:

About dynamic display




Development licensingDeployment licensing
Engine Developer KitEngine
ArcGIS for Desktop Basic
ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced