This document is archived and information here might be outdated.  Recommended version.


How to use symbol level drawing (ArcObjects .NET 10.4 SDK)

How to use symbol level drawing


Summary
Symbol level drawing is useful when creating large scale maps with intersecting and overlapping line features. For example, on a large scale reference map with intersecting highways and streets, symbol level drawing helps you create high-quality representations of street and highway street intersections.

In this topic


About using symbol level drawing

You can use symbol level drawing to alter the draw order of features within feature layers. By using symbol level drawing, you can control the draw order of features on a symbol-by-symbol basis. This means features do not have to be drawn in the same order as feature layers that appear in ArcMap's table of contents (TOC). With symbol level drawing, you can control when a feature draws by controlling when the feature's symbol draws. Furthermore, when multilayer symbols are used, you can control the drawing order of individual symbol layers.
 
Using symbol level drawing is most useful for maps with cased lines because it can be used to create overpass and underpass effects where the line features cross, which is a good way to show connectivity. Symbol level drawing can also be used to achieve other advanced effects.
 
IMapLevel is the interface that you use to assign a map level (or levels if the symbol is multilayer) to a symbol, thus preparing it to be used with symbol level drawing. Not all symbols support this interface. If you assign a symbol with map levels to a graphic element, the levels are ignored. In addition, ISymbol.Draw ignores levels.

Using symbol level drawing

Do the following steps to use symbol level drawing:
  1. Turn on symbol level drawing for a layer using ISymbolLevels.UseSymbolLevels or for your entire map using IMap.UseSymbolLevels.
  2. For each layer on your map in which you want to use symbol levels, access the layer's renderer using IGeoFeatureLayer.Renderer.
  3. Access your layer's symbols through the renderer.
  4. Using IMapLevel, set symbol levels on your layer's symbols. Symbols with MapLevel=0 draw first, then symbols with MapLevel=1, continuing until the highest MapLevel is reached. If two symbols have the same MapLevel, the features drawn with these symbols are drawn in the normal layer order. A MapLevel value of –1 for a multilayer symbol (MultiLayerMarkerSymbol, MultiLayerLineSymbol, MultiLayerFillSymbol) indicates that each of the symbol's individual layers are drawn with their individual MapLevel.
Before ArcGIS 9.0, symbol levels were referred to in ArcMap's graphical user interface (GUI) as advanced drawing options and were only available at the map level. In ArcGIS 9.0 and later versions, symbol level support was added for individual FeatureLayers and GroupLayers. In the GUI, this is called symbol level drawing. The preferred use of symbol levels is at the layer level since in ArcGIS 9.0 and later, there is no GUI for map-based symbol level drawing, and layer-based symbol level drawing is more efficient.

Joining and merging a symbol

The following illustration shows the effect of joining a symbol, which makes features with the same symbol appear to connect to each other (merge makes features with different symbols appear to connect). Both of these effects are implemented behind the scenes using symbol level objects and interfaces. Toggle symbol level drawing on or off for a layer using ISymbolLevels.UseSymbolLevels. Toggle symbol level drawing on or off for your entire map using IMap.UseSymbolLevels.
ESRI.EDNv9.3/NET_Desktop/bitmaps/8d81aed9-9643-4e22-930c-3cadcb81689110.png 
The following code example turns on symbol level drawing for the layer on the map and sets up the multilayer symbol assigned to the layer to be joined:
[VB.NET]
Public Sub SetMultiLayerSymbol(ByVal application As IApplication)
    Dim mapDoc As IMapDocument=CType(application.Document, IMapDocument)
    Dim map As IMap=mapDoc.ActiveView.FocusMap
    If TypeOf map.get_Layer() Is IGeoFeatureLayer Then
        Dim geoFeatLyr As IGeoFeatureLayer
        geoFeatLyr=New FeatureLayerClass()
        geoFeatLyr=TryCast(map.get_Layer(0), IGeoFeatureLayer)
        Dim symbolLevels As ISymbolLevels
        symbolLevels=TryCast(geoFeatLyr, ISymbolLevels)
        symbolLevels.UseSymbolLevels=True
        If TypeOf geoFeatLyr.Renderer Is ISimpleRenderer Then
            Dim simpleRend As ISimpleRenderer
            simpleRend=New SimpleRendererClass()
            If TypeOf simpleRend.Symbol Is IMultiLayerLineSymbol Then
                Dim multi As IMultiLayerLineSymbol
                multi=New MultiLayerLineSymbolClass()
                multi=TryCast(simpleRend.Symbol, IMultiLayerLineSymbol)
                SetMapLevel(TryCast(multi, IMapLevel), -1)
                Dim i As Integer
                For i=0 To multi.LayerCount - 1 Step i + 1
                    SetMapLevel(multi.get_Layer(multi.LayerCount - (i + 1)), i)
                Next
            End If
        End If
    End If
End Sub

Public Sub SetMapLevel(ByVal mapLevel As IMapLevel, ByVal iLevel As Integer)
    If Not (mapLevel Is Nothing) Then
        mapLevel.MapLevel=iLevel
    End If
End Sub
[C#]
public void maplayerdrawing(IApplication application)
{
    IMapDocument mapDoc=application.Document as IMapDocument;
    IMap map=mapDoc.ActiveView.FocusMap;
    if (map.get_Layer(0)is IGeoFeatureLayer)
    {
        IGeoFeatureLayer geoFeatLyr;
        geoFeatLyr=new FeatureLayerClass();
        geoFeatLyr=map.get_Layer(0)as IGeoFeatureLayer;
        ISymbolLevels symbolLevels;
        symbolLevels=geoFeatLyr as ISymbolLevels;
        symbolLevels.UseSymbolLevels=true;
        if (geoFeatLyr.Renderer is ISimpleRenderer)
        {
            ISimpleRenderer simpleRend;
            simpleRend=new SimpleRendererClass();
            if (simpleRend.Symbol is IMultiLayerLineSymbol)
            {
                IMultiLayerLineSymbol multi;
                multi=new MultiLayerLineSymbolClass();
                multi=simpleRend.Symbol as IMultiLayerLineSymbol;
                SetMapLevel(multi as IMapLevel,  - 1);
                for (int i=0; i < multi.LayerCount; i++)
                {
                    SetMapLevel(multi.get_Layer(i)as IMapLevel, multi.LayerCount - 
                        (i + 1));
                }
            }
        }
    }
}

public void SetMapLevel(IMapLevel mapLevel, int iLevel)
{
    if (!(mapLevel == null))
    {
        mapLevel.MapLevel=iLevel;
    }
}


See Also:

Working with symbols and colors
ISymbolLevels interface




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS for Desktop Basic ArcGIS for Desktop Basic
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
Engine Developer Kit Engine