Rendering dynamic content using IDynamicLayer


Summary The dynamic display is an active display, which means it is capable of redrawing the dynamic layer in every draw cycle. The frequency of the draw cycle by default is 30ms and can be modified using the IDynamicMap.setDrawRate() method. Every custom dynamic layer in a dynamic map has an associated dirty property. During every draw cycle, the dynamic display framework checks every dynamic layer's dirty property. If the dynamic layers are dirty, the dynamic display renders the dynamic layers. This sequence of events can be manipulated to visualize object tracking, displaying real time or other feeds, and playbacks recorded feeds in a dynamic map. This topic provides information on rendering dynamic content by implementing dynamic layers.

In this topic


Creating dynamic layers

 
Custom dynamic layers at a minimum, must implement the ILayer, IDynamicLayer, and IGeoDataset interfaces. Implementing the ILayer interface enables the custom layer to be added to the map and table of contents (TOC) and hence, can be interleaved between other non-dynamic layers, and also be turned on or off like any other layer. 
The following table shows the most important methods that determine the characteristics of a dynamic layer:
 
Method
This method renders dynamic items of a dynamic layer to the specified display.
Read/write property
This property indicates if the dynamic layer needs to be redrawn.
When the dynamic map is enabled and the DynamicLayerDirty property of the custom dynamic layer is set to true, the IDynamicLayer.drawDynamicLayer() method of the corresponding dynamic layer is called by the dynamic display framework to redraw the layer. 
The drawing commands to draw dynamic items on the dynamic layer are implemented in the IDynamicLayer.drawDynamicLayer() method. When the drawDynamicLayer() method is executed, a new set of draw commands are rendered with current and updated information for every dynamic item in the dynamic layer; therefore, the dynamic display framework enables rendering up-to-date information on a dynamic map. If the dynamic map is not enabled, ILayer.draw() method is called. 
The drawing commands to render dynamic layers can be defined by the dynamic display drawing application programming interfaces (APIs) or the OpenGL API. When implementing the ILayer.draw() method, use the standard drawing commands (for example, ISymbol.Draw) or GDI/GDI+ API. Since the dynamic layers are custom created, the underlying data structure of the layers, such as the layer drawing (implemented in the drawDynamicLayer() method), selection of features, identification, and so on, also needs to be custom implemented.
The following code example describes the essential steps in creating a dynamic layer, that is, the implementation of the drawDynamicLayer() method and managing the DynamicLayerDirty property of the dynamic layer using a simple thread:
The DynamicLayerDirty property can be managed (set to true) by using threads, timer events, or other methods invoked by the external feeds depending on your application.
[Java]
public class MyDynamicLayer implements Runnable, IDynamicLayer, ILayer, IGeoDataset{

    //This class is not complete.
    //It needs to implement other methods.
    //Refer to the walkthrough on creating dynamic layers.


    //A simple thread to manage the DynamicLayerDirty property.
    public void run(){
        try{
            while (true){
                //Set the dirty property to true and force the dynamic display (DD) framework 
                //to render the layer every 30ms.
                this.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate,
                    true);
                Thread.sleep(30);
            }
        }
        catch (Exception e){
            // TODO: Auto-generated catch block.
            e.printStackTrace();
        }

    }



    public void drawDynamicLayer(int phase, IDisplay display, IDynamicDisplay
        dynamicDisplay)throws IOException, AutomationException{
        try{
            //Step 1: Get the current information for the dynamic items.
            Point point = new Point();
            point.putCoords(......)

            //Step 2: Draw dynamic symbols using OpenGL or dynamic display APIs.
            drawDynamicSymbols(dynamicDisplay, point);

            //Step 3: Set the dirty property to false to prevent layers from redrawing in every 
            //draw cycle.
            this.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate, false);
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

Two drawing phases of a dynamic layer

Dynamic layers can be drawn in two drawing phases—immediate(esriDDPImmediate) or compiled(esriDDPCompiled). The phase a dynamic layer needs to be drawn in can be specified by the IDynamicLayer.setDynamicLayerDirty(int phase, Boolean layerDirty) method. See the following:
  • If the layer needs to be drawn in the immediate phase—IDynamicLayer.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPImmediate, true)
  • If the layer needs to be drawn in the compiled phase—IDynamicLayer.setDynamicLayerDirty(esriDynamicDrawPhase.esriDDPCompiled, true)
Accordingly, the DD framework invokes the drawDynamicLayer(int phase, IDisplay display, IDynamicDisplay, dynamicDisplay) method in the immediate or compiled phase depending on the scenario. See the following:
  • If the layer is dirty in the immediate phase, the drawDynamicLayer() method is invoked in the immediate phase and the layer draws immediately.
  • If the layer is dirty in the compiled phase, the DD framework checks the layer's RecompileRate interval specified by the IDynamicLayer.getDynamicRecompileRate() method.
    • If it has elapsed, the new draw commands are generated by invoking the drawDynamicLayer() method in the compiled phase. The generated draw commands are stored as a display list.
    • If the RecompileRate interval has not elapsed, the drawDynamicLayer() method is not invoked to generate new draw commands; rather, the layer is drawn using the already stored draw commands.
Any change in nondynamic layers, such as map navigation, map refresh, and so on, or when one of the dynamic layers is dirty, the dynamic display renders all dynamic layers. In this scenario, by default, the DD framework invokes all dynamic layers drawDynamicLayer() method in the immediate phase, but may not invoke the drawDynamicLayer() method in the compiled phase for all dynamic layers.
The drawDynamicLayer() method of the dynamic layers are called in the compiled phase when the dynamicRecompileRate interval has elapsed and the dynamic layer's dynamicLayerDirty property is true in the esriDDPCompiled phase.
By default, the dynamicRecompileRate for a dynamic layer is set to –1.
Immediate vs. compiled phase
  • It is recommended that any dynamic layer be drawn only in one of the draw phases, not in both.
  • As a rule of thumb, it is preferable to use the compiled phase, since using it minimizes the central processing unit (CPU) usage and the bus traffic to the graphic card, by minimizing the frequency in which the dynamic layer draw commands are regenerated (layer items are iterated and the draw commands are called). If the layer items are updated frequently and the compiled phase display list needs to be recompiled frequently, it is preferable to render the layer items in the immediate phase, instead of in the compiled phase.
  • Another advantage of the compiled phase versus the immediate phase is when using the immediate phase, every change in the layers (or any reason that causes a repaint of the display), causes the other layers that use the immediate phase to regenerate their drawing code, even when there was no reason (no change) for them to do so.


See Also:

Dynamic drawing APIs to create dynamic content
WalkThrough: Rendering dynamic content using IDynamicLayer
Sample: Rendering dynamic content with dynamic layers




Development licensing Deployment licensing
Engine Developer Kit Engine Runtime