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 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:
- Turn on symbol level drawing for a layer using ISymbolLevels.UseSymbolLevels or for your entire map using IMap.UseSymbolLevels.
- For each layer on your map in which you want to use symbol levels, access the layer's renderer using IGeoFeatureLayer.Renderer.
- Access your layer's symbols through the renderer.
- 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.
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 colorsISymbolLevels 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 |