The OverlayManager (Reimers.Silverlight.Bing.OverlayManager) is intended to facilitate displaying overlays on the Bing Maps Silverlight control. The map control is very good for displaying map imagery, but in my opinion it gives you too much flexibility when it comes to displaying overlays. Let's face it, there's so much you can do in the Silverlight world, that it's easy to get overwhelmed. The OverlayManager is intended to help you perform common tasks when it comes to displaying overlays on a map.
Setting up the OverlayManager
So what can you do with it? Well, in short, you can display overlays on your map in an easy straightforward way. The first step is to attached it to your map. The OverlayManager class defines an attached property called ManagerProperty. This means you can connect the OverlayManager with the map directly in XAML, like so:
XAML
<ve:Map x:Name="map"
ScaleVisibility="Collapsed"
NavigationVisibility="Collapsed"
LogoVisibility="Collapsed"
MouseWheel="map_MouseWheel">
<reimers:OverlayManager.Manager>
<reimers:OverlayManager></reimers:OverlayManager>
</reimers:OverlayManager.Manager>
</ve:Map>
You can of course also set it in code. In this case you assign the map object to the RelatedMap property. (I know, this is not good naming convention, but if you look at it, then it seems counter-intuitive to define a property in XAML called RelatedMap, when you are in fact creating an OverlayManager, and likewise it is not easy to understand that in code you are assiging the map object to the Manager property. So I went with the difference). Defining it in code is like setting any other property:
C#
OverlayManager manager = new OverlayManager();
manager.RelatedMap = map;
Adding Overlays
When the map and OverlayManager have been connected it will make some alterations to the map in order to improve overlay display and you are ready to start adding overlays, that inherit from FrameworkElement. Since the OverlayManager class inherits from a generic collection, you can add overlays to it directly in XAML, like so:
XAML
<reimers:OverlayManager.Manager>
<reimers:OverlayManager>
<Image Source="">
<ve:MapLayer.MapPosition>
<ve:Location Latitude="51.477"
Longitude="0.0" />
</ve:MapLayer.MapPosition>
</Image>
<ve:MapPolyline Stroke="Blue"
StrokeThickness="5">
<ve:MapPolyline.Locations>
<ve:LocationCollection>
<ve:Location Latitude="48.85"
Longitude="2.4333" />
<ve:Location Latitude="51.477"
Longitude="0" />
</ve:LocationCollection>
</ve:MapPolyline.Locations>
</ve:MapPolyline>
</reimers:OverlayManager>
</reimers:OverlayManager.Manager>
One thing to notice here is the way that the image defines its geographic coordinates. Where the MapPolyline has a Locations property that defines the points on the line, the marker doesn't have the same. So it has to use an attached property defined in the MapLayer class (Microsoft.VirtualEarth.MapControl.MapLayer) so you will need to include that namespace in your XAML. The MapLayer also defines other attached properties like PositioningMethod which defines how the marker is positioned in relation to its coordinates.
Manipulating Overlays
Now that you've got overlays added to the manager you are ready to use some of the other features of the OverlayManager.
The manager allows you to manipulate managed overlays. For example you can make overlays draggable by calling the MakeDraggable method, and inversely you can make it 'undraggable' by calling the MakeFixed method.
If you are working with shapes (polylines and polygons) then you can edit them on the map by calling the EnableEditing. This will put them into an edit mode where you can drag the vertices into new positions. To disable further editing simply call DisableEditing.
Display Related Information
One of the frequent uses for markers is to display related information. In traditional map applications this is done by opening a text bubble when a marker is clicked. This is not directly supported in the Silverlight map control, but the OverlayManager defines an attached property called InfoContent. You can attach this to any overlay. If the overlay is clicked and the manager detects an attached info content it will attempt to display it with the marker so you can display related information. This is how it may look in XAML
XAML
<Image Source="">
<ve:MapLayer.MapPosition>
<ve:Location Latitude="51.477"
Longitude="0.0" />
</ve:MapLayer.MapPosition>
<reimers:OverlayManager.InfoContent>
<Border BorderBrush="Black"
BorderThickness="2"
Width="50"
Height="50">
<TextBlock Text="Hello World" />
</Border>
</reimers:OverlayManager.InfoContent>
</Image>
When trying to open the info content the OverlayManager passes the DataContext of the overlay to the info content, so you can use bindings in your template.
Clustering
So now you've got through how to add overlays, and how to display related information. But what happens when you've added too many markers? As opposed to AJAX map applications, Silverlight won't care. It doesn't choke when you display hundreds (or even thousands) of overlays. But that doesn't mean it doesn't overload your users' brains. In this case you may want to cluster your overlays together to reduce clutter.
I have previously written a post about clustering so I won't repeat it here.
KML Support
Apart from the above way to add overlays by code or XAML, you can also read a KML file into the manager by calling the ReadKml method, or write it out using the WriteKml method.
The OverlayManager lets you attach some extra information to facilitate interaction with KML. The KmlOptions is another attached property that can be attached to your overlays. This lets you define some information in a structure that is recognized by KML.
The KML definition is very lengthy and only a subset is relevant for displaying overlays in Silverlight, so the OverlayManager may not read all your KML as you expect. It is a work in progress, so if you have any KML files that are not being read properly please let me know so I can improve the parser.
XAML
<ve:MapPolyline Stroke="Blue" StrokeThickness="5">
<reimers:OverlayManager.KmlOptions>
<kml:KmlOptions Name="Line" Description ="London - Paris" />
</reimers:OverlayManager.KmlOptions>
<ve:MapPolyline.Locations>
<ve:LocationCollection>
<ve:Location Latitude="48.85"
Longitude="2.4333" />
<ve:Location Latitude="51.477"
Longitude="0" />
</ve:LocationCollection>
</ve:MapPolyline.Locations>
</ve:MapPolyline>
Please report any issues you may experience using the OverlayManager so it can be improved for yourself and others.