New to Telerik UI for WPF? Download free 30-day trial

Virtualization Layer

The Virtualization Layer can be used to visualize large data sources due to its superior performance, compared to the Information Layer or the Dynamic Layer.

Similarly to the Dynamic Layer, the Virtualization Layer raises an items request event when the zoom or center property is changed. The difference is that it processes that request within the background thread, that way freeing the UI thread.

The Virtualization Layer exposes the following properties:

  • RenderWhileMotion - boolean property indicating whether the layer should request and render items while the user is zooming or scrolling.

  • ZoomLevelGridList - collection of ZoomLevelGrids that are used to specify the map devision.

  • VirtualizationSource - used to specify the item source of the layer. Expects an object of type that implements IMapVirtualizationSource.

Map Division

Like the DynamicLayer, the Virtualization requires a division of the map space in regions. The division of map space is defined using the VirtualizationLayer.ZoomLevelGridList collection. Each ZoomLevelGrid should define a minimum zoom level for its division. The maximum zoom level for a grid is the minimum zoom layer of the next grid in the list. Also each zoom level is divided in a grid of latitude/longitude divisions.

The ZoomLevelGrid provides the CellWidth and CellHeight properties which allow specifying the size of cell on the map in pixels. By default the cell has a size which equals the size of tile (256x256) which is usually used by the map providers like Bing and OpenStreet.

Specifying the size of cell for the zoom level affects to a number of requests to a Virtualization Source which is depended on the viewport size of the map.

If the requests are performed slowly (for example they use a service which has low performance) you can increase the cell size to lower the number of requests.

Here is a sample Virtualization Layer declaration:

<telerik:RadMap x:Name="radMap"> 
    <telerik:VirtualizationLayer x:Name="virtualizationLayer"> 
        <telerik:VirtualizationLayer.ZoomLevelGridList> 
            <telerik:ZoomLevelGrid MinZoom="3"/> 
            <telerik:ZoomLevelGrid MinZoom="6"/> 
        </telerik:VirtualizationLayer.ZoomLevelGridList> 
    </telerik:VirtualizationLayer> 
</telerik:RadMap> 

Virtualization Source

The data provided to the VirtualizationLayer should be wrapped in a class that implements the IMapVirtualizationSource interface. This interface contains a BackgroundItemsRequest() method, which is used by the VirtualizationLayer to request new data, whenever the zoom level or the region changes.

When there are no ZoomLevelGrid that satisfy the current zoom level, no request would be made. Also when the changed value of the zoom level or the region stays in the range of a ZoomLevelGrid or one of it cells, no request is made neither. In the current case, for example, when the zoom level is 1 or 2, no requests would be made, because there is no grid which represent this range. When the value is bigger than 6, requests would be made only when the grid cell changes, because the gird is defined for the range from 6 to the maximal zoom level.

The BackgroundItemsRequestEventArgs provides the following properties:

  • Layer - reference to the layer that is requesting items.

  • minZoom - represents the minimum zoom level of the currently active ZoomGrid.

  • upperLeft - represents the upper left corner of the currently visible region.

  • lowerRight - represents the lower right corner of the currently visible region.

  • CompleteItemsRequest - represents an Action, which is responsible to pass the desired item back to the VirtualizationLayer.

In the BackgroundItemsRequest() method you have to implement your logic for getting the desired items. The items can be represented by static and dynamic data as well.

Here is an example of how to implement simple static functionality in the BackgroundItemsRequest() method:

public class MapVirtualizationSource : IMapVirtualizationSource 
{ 
    static readonly Location bulgariaLocation = new Location(42.7669999748468, 25.2819999307394); 
    static readonly Location sofiaLocation = new Location(42.6957539183824, 23.3327663758679); 
 
    Ellipse BulgariaEllipse { get; set; } 
    Ellipse SofiaEllipse { get; set; } 
 
    public MapVirtualizationSource() 
    { 
        //Exectued ot UI thread 
        BulgariaEllipse = new Ellipse(); 
        BulgariaEllipse.Width = 15; 
        BulgariaEllipse.Height = 15; 
        BulgariaEllipse.Fill = new SolidColorBrush(Colors.Red); 
        BulgariaEllipse.SetValue(MapLayer.LocationProperty, bulgariaLocation); 
        MapLayer.SetHotSpot(BulgariaEllipse, new HotSpot { X = 0.5, Y = 0.5 }); 
        ToolTipService.SetToolTip(BulgariaEllipse, "Bulgaria"); 
 
        SofiaEllipse = new Ellipse(); 
        SofiaEllipse.Width = 20; 
        SofiaEllipse.Height = 20; 
        SofiaEllipse.Stroke = new SolidColorBrush(Colors.Red); 
        SofiaEllipse.Fill = new SolidColorBrush(Colors.Transparent); 
        SofiaEllipse.StrokeThickness = 3; 
        SofiaEllipse.SetValue(MapLayer.LocationProperty, sofiaLocation); 
        MapLayer.SetHotSpot(SofiaEllipse, new HotSpot { X = 0.5, Y = 0.5 }); 
        ToolTipService.SetToolTip(SofiaEllipse, "Sofia"); 
    } 
 
    public void BackgroundItemsRequest(object sender, BackgroundItemsRequestEventArgs e) 
    { 
        LocationRect currentRegion = new LocationRect(e.UpperLeft, e.LowerRight); 
 
        List<object> visibleItems = new List<object>(); 
 
        if (currentRegion.Contains(bulgariaLocation)) 
        { 
            if (e.MinZoom == 3) 
            { 
                visibleItems.Add(this.BulgariaEllipse); 
            } 
            else if (e.MinZoom == 6) 
            { 
                visibleItems.Add(this.SofiaEllipse); 
            } 
        } 
        e.CompleteItemsRequest(visibleItems); 
    } 
} 
Public Class MapVirtualizationSource Implements IMapVirtualizationSource 
    Shared ReadOnly bulgariaLocation As New Location(42.7669999748468, 25.2819999307394) 
    Shared ReadOnly sofiaLocation As New Location(42.6957539183824, 23.3327663758679) 
 
    Private Property BulgariaEllipse() As Ellipse 
        Get 
            Return m_BulgariaEllipse 
        End Get 
        Set 
            m_BulgariaEllipse = Value 
        End Set 
    End Property 
    Private m_BulgariaEllipse As Ellipse 
    Private Property SofiaEllipse() As Ellipse 
        Get 
            Return m_SofiaEllipse 
        End Get 
        Set 
            m_SofiaEllipse = Value 
        End Set 
    End Property 
    Private m_SofiaEllipse As Ellipse 
 
    Public Sub New() 
        'Exectued ot UI thread' 
        BulgariaEllipse = New Ellipse() 
        BulgariaEllipse.Width = 15 
        BulgariaEllipse.Height = 15 
        BulgariaEllipse.Fill = New SolidColorBrush(Colors.Red) 
        BulgariaEllipse.SetValue(MapLayer.LocationProperty, bulgariaLocation) 
        MapLayer.SetHotSpot(BulgariaEllipse, New HotSpot() With { .X = 0.5,  .Y = 0.5 }) 
        ToolTipService.SetToolTip(BulgariaEllipse, "Bulgaria") 
 
        SofiaEllipse = New Ellipse() 
        SofiaEllipse.Width = 20 
        SofiaEllipse.Height = 20 
        SofiaEllipse.Stroke = New SolidColorBrush(Colors.Red) 
        SofiaEllipse.Fill = New SolidColorBrush(Colors.Transparent) 
        SofiaEllipse.StrokeThickness = 3 
        SofiaEllipse.SetValue(MapLayer.LocationProperty, sofiaLocation) 
        MapLayer.SetHotSpot(SofiaEllipse, New HotSpot() With { .X = 0.5, .Y = 0.5 }) 
        ToolTipService.SetToolTip(SofiaEllipse, "Sofia") 
    End Sub 
 
    Public Sub BackgroundItemsRequest(sender As Object, e As BackgroundItemsRequestEventArgs) 
        Dim currentRegion As New LocationRect(e.UpperLeft, e.LowerRight) 
 
        Dim visibleItems As New List(Of Object)() 
 
        If currentRegion.Contains(bulgariaLocation) Then 
            If e.MinZoom = 3 Then 
                visibleItems.Add(Me.BulgariaEllipse) 
            ElseIf e.MinZoom = 6 Then 
                visibleItems.Add(Me.SofiaEllipse) 
            End If 
        End If 
        e.CompleteItemsRequest(visibleItems) 
    End Sub 
End Class    

You can set the virtualization source to a new instance of the MapVirtualizationSource and create a new definition for the OpenStreetMap provider:

public MainWindow() 
{ 
    InitializeComponent(); 
    this.radMap.Provider = new OpenStreetMapProvider(); 
    this.virtualizationLayer.VirtualizationSource = new MapVirtualizationSource(); 
} 
Public Sub New() 
    InitializeComponent() 
    Me.radMap.Provider = New OpenStreetMapProvider() 
    Me.virtualizationLayer.VirtualizationSource = New MapVirtualizationSource() 
End Sub 

The result:

ZoomLevel = 3:

Rad Map Features Virtualization Layer 01

ZoomLevel = 6:

Rad Map Features Virtualization Layer 02

In this article