Click or drag to resize

Render Modes in Detail

Verizon Connect Logo
Print this page
Learn more about Verizon Connect GeoBase.
Get information about the latest release
Overview

Render modes control when an object that implements the IMapRenderer interface is drawn on the map. This can occur in one of four passes. Objects that are drawn in a later pass may obscure objects that were drawn in previous passes.

Priority Based Rendering

When rendering occurs, four passes are made over the objects in the RendererList. The order in which objects are rendered depends on their Mode.

Objects are rendered in this order:

  1. PreMap - Renderers with this level of priority are drawn before polygons are rendered. This would be implemented, typically, for satellite imagery.
  2. PreLabelling - Renderers with this level of priority are drawn before labelling is done.
  3. Labelling - There is essentially no difference between this mode and PreLabelling, other than that PreLabelling is done first.
  4. PostLabelling - Drawn last, after labels have been rendered on the map.

The image below highlights the differences between the four modes. Each circle has been placed on the map with a different render mode, as follows:

  • red - PreMap
  • blue - PreLabelling
  • yellow - Labelling
  • green - PostLabelling
Render Modes

As you can see, the red circle has been rendered before the map; the blue and yellow circles have been rendered before the labels (note the blue circle below the yellow circle); the green circle has been rendered last.

Note Note

This example was created by modifying code that can be found on the GeoZone site. To display the PreMap renderer, a .cam file with the clear brush and render [land] polygons code lines commented out has been used.

Using multiple modes

A single object can use more than one render mode to achieve a complex layout. For example, BalloonPushPin renders the PushPin icon in PreLabelling, and then follows up by rendering the informational balloon in Labelling. This split-level rendering ensures that all PushPin icons are placed on the map before balloons are drawn, allowing the use of Test to ensure that balloons do not obscure PushPins.

RenderContexts and Labelling

In the PreLabelling and Labelling passes, it is possible to call the Test and Place methods on the RenderContext to control placement of items on the map. By passing a region to these methods you can either check to see if an area is clear of labels or can reserve an area for your Renderer to use.

Both the Test and Place methods define the area where an object appears on the map by a rectangular region, a buffer zone around that rectangle that provides a bit of visual separation from other objects, and an angle of rotation. You can specify the rectangular region using either the System.Drawing.Rectangle structure, or using four integer values (for the left edge, top edge, width, and height).

You are free to use these methods as you want. You do not have to ensure an area is free to draw in with Test before you Place a label in it. Similarly, you do not have to declare the areas you are drawing upon with Place. For example, the BalloonPushPin described above calls Place for each icon it draws, but does not Test. This ensures every icon is placed, but also allows the labelling pass to detect areas it cannot place a balloon on.

Examples

The following example shows a renderer that uses Place to prevent labels from appearing on top of an icon. It uses System.Drawing.Rectangle to define the region where the icon is rendered:

C#
public void Render(Graphics graphics, RenderContext rc) {
    if (rc.Map.Contains(Location)  && rc.RenderMode == RenderMode.PreLabelling) {
        // Convert location to pixel coordinates
        int px, py;
        rc.Map.LatLontoXY(out px, out py, mLocation);
        // Call Place( ) to prevent the Labelling pass from obscuring this icon
        rc.Place(ImageUtils.IconCache.Rectangle(Icon, px, py), 0, 0);
        // draw the icon
        ImageUtils.IconCache.DrawIcon(graphics, px, py, Icon, false);
    }
}

Note that in this method, there is no call to the Test method. That means that the icon is always drawn, even if it obscures another object that also called Place.

The following example shows a renderer that uses both the Place and Test methods. In this case, the object will not appear on the map if that would cause it to obscure any other objects that called Place in the PreLabelling pass. Further, labels placed in the Labelling pass that use the Test method will not obscure this object.

C#
public void Render(Graphics graphics, RenderContext rc) {        
    if (rc.Mode == RenderMode.Labelling && rc.Map.Contains(mLocation)) {
        int px, py;
        //Figure out pixel location
        rc.Map.LatLontoXY(out px, out py, mLocation);
        // get the size of our text
        SizeF textSize = graphics.MeasureString(Message, mFont);
        Int32 spacer = (Int32) textSize.Height / 2;
        // check that the drawing space is free
        if (rc.Test(px, py, (Int32) textSize.Width, (Int32) textSize.Height, spacer, 0) 
            // call place to prevent other labels from appearing on top    
            rc.Place(px, py, (Int32) textSize.Width, (Int32) textSize.Height, spacer, 0);
            // write the message
            System.Drawing.PointF point;
            point.x = (Single) px;
            point.y = (Single) py;
            graphics.DrawString(Message, mFont, mBrush, point);
        }
    }
}