Optimize Map Layers in Bing Maps Silverlight

Recently I wanted to load a large number of polygons on a Silverlight map. Anyone who has added a large number of polygons to the map  knows that once you get around 500kb worth of data  performance issues start to appear. A while back I made a toolkit that optimized the map to handle ~9MBworth of data. This helped a bit but I had 50mb worth of data I wante dto put on the map. Using tile layer would get rid of the performance issue but then I wouldn’t be able to interact with the shapes on the map when the mouse hovers over a polygon. The performance issue tends to only happen when you pan or zoom the map. With this in mind I decided to try one of the tricks I heard about on the Bing Maps forums that suggested hiding the map layer when moving the map. After a quick test it seemed to make a difference. In my app I had several layers that I wanted to add this to but realized that this would make my code much bigger than needed so I decided to make things easier and create a class called OptimizedMapLayer that inherited the MapLayer class.

To get this class to work without breaking the default functionality of the Visibility property I hide the base Visibility property with a new Visibility property in the OptimizedMapLayer class. This new Visibility property keeps track of the visibility value set by the user and sets the base visibility property to this value after the map is done moving. The code ended up very small and clean as you can see below.

using System.Windows; using Microsoft.Maps.MapControl; namespace GeospatialToolkit.BingMaps.SL { public class OptimizedMapLayer : MapLayer { #region Private Properties         private Visibility _visibility;

        #endregion

        #region Constructor

        ///<summary> /// Constructor ///</summary> public OptimizedMapLayer() : base() { this.Loaded += (sender, evt) => { Map map = (Map)base.ParentMap; map.ViewChangeStart += (s, e) => { _visibility = base.Visibility;

                    if (base.Visibility == Visibility.Visible) { base.Visibility = Visibility.Collapsed; } };

                map.ViewChangeEnd += (s, e) => { base.Visibility = _visibility; }; }; }

        #endregion

        #region Public Properties

        public Visibility Visibility { get { return base.Visibility; } set { base.Visibility = value; _visibility = value; } }

        #endregion } }

Implementing this new class was really easy. Simply use it the same way you would use a MapLayer as shown below.

OptimizedMapLayer dataLayer = new OptimizedMapLayer(); MyMap.Children.Add(dataLayer);

After some testing I managed to load in 96MB worth of data consisting of 5500 polygons with over 6 million coordinates with little no performance issues when panning and zooming. That’s a 10x improvement in the amount of data I’m able to get into the map. Now there is a down side to this class, when you move the map your data is hidden and does not reappear until the map ViewChangeEnd event fires which appears to be a bit delayed after zooming the map. However, this is a minor issue and the benefits heavily out weighs the negatives.

For fun I decided to go for broke and tried loading in 175MB worth of data that had over 10 million coordinates. It loaded up and displayed on the map but even with this performance enhancement things were a bit slow. I guess I’ll have to keep looking for more ways to optimize the control if I ever want to hit my goal of 2GB of data (The file size limit on ESRI Shapefiles).