Reimers.dk

.NET, AJAX and Google APIs brought together
Welcome to Reimers.dk Sign in | Join | Help
in Search

Jacob Reimers Weblog

Using the OverlayManager

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.

Published 10. september 2009 20:32 by jjrdk

Comments

 

bobmorris said:

Thanks very much for the example. In an old app that I'm trying to convert to Silverlight I display the track of a vehicle using a polyline and directional arrow markers (just arrow images to nearest 10%). Hovering the cursor over a market displays more info (fuel state etc), and this I'm trying to do using VE. Looking at your InfoContent snippet, this seems to be the direction I need but I've spent the last hour trying to do this in code.

VEMap is defined in the XAML.

Then in code:-

 OverlayManager manager = new OverlayManager();

           manager.RelatedMap = VEMap;

           Image img = new Image();

           img.Source = new BitmapImage(new Uri("image/truck01.png", UriKind.Relative));

           img.Stretch = Stretch.None;

           Location loc = new Location(-1.299735, 36.828151);

           manager.Add(img, loc);

I'd expect to find :-

          manager[0].InfoContent = "Kilroy was here"

Or something like that. But nothing doing. Your help will be much appreciated.

Bob

Now I want to assign stuff to the InfoContent property of manager but

september 13, 2009 08:57
 

jjrdk said:

september 13, 2009 15:36
 

bobmorris said:

Thanks very much.

Bob

september 13, 2009 16:21
 

Firebrand said:

Hi! I am new to this so here goes...

Is there any way that I can turn layers or should I say overlays on or off. I have a set of polygons and I would like to show them or not so them on the map by clicking a button. Any tips and guides would be much appreciated. Thank you.

september 27, 2009 20:25
 

jjrdk said:

All overlays are FrameworkElements, so you can show or hide them by setting the Visibility property to Visible or Collapsed respectively. Fx.

I will think about adding a show/hide feature to the OverlayManager. In such a case it would take a Predicate<FrameworkElement> to determine which overlay to show or hide. Currently you can do the same with a LINQ query as shown below, so it would be repeating an existing feature:

var toHide = from ovl in manager where ovl is MapShapeBase select ovl;

foreach (var overlay in toHide)

{

overlay.Visibility = Visibility.Collapsed;

}

september 27, 2009 20:40
 

g.duffield said:

I was just about to start having a look at this, but just to let you know that you cannot add a refernce to your control under VS2010 Beta , I have not found out why yet it errors. But works fine from VS 2008 SP1 on the same machine with the components in the same place.

november 23, 2009 17:35
 

g.duffield said:

How do you make a polygon draggable when using Bung Maps? I have added the following

OverlayManager manager = new OverlayManager();          

manager.RelatedMap = myMap;

manager.MakeDraggable(polygon);

but this does not work. If I enable editing on the polygon this works as expected. Any thoughts?

november 23, 2009 18:41
 

jjrdk said:

I had a look at the draggable issue. It was caused because in the release version of the Bing Maps control Location is a class and no longer a struct. This caused a null reference.

I fixed it and committed the change to SVN and upload a working version to the downloads section.

I'll have a look at the VS2010 issue.

november 23, 2009 19:26
 

josenunes said:

Hello!

Great tool!

What if I wanted to use and image below the overlay instead of a map ?

december 4, 2009 11:44
 

andes said:

had the same issue as jjrkd - thanks for the advice :)

februar 4, 2010 12:35
 

edsilv said:

Hi,

This is great, but I'm unable to get it to work with v1.0.1.0 of the Microsoft.Maps.MapControl assembly. It won't compile when setting manager.RelatedMap.

I'm working on a project where this could be extremely useful, but it doesn't look like the source code is available. This is too much of a concern if I get to an advanced stage and then need to change something/fix a bug. Is the source available?

Regards,

Ed

august 4, 2010 13:38
 

jjrdk said:

I run the OverlayManager against that version of the map as well, without problems.

If you want, you can pull the source code from the SVN trunk at svn://svn.reimers.dk. The OverlayManager is inside the Reimers.Silverlight project and you will need to pull out the Reimers.Silverlight.Core project as well.

Note that it is undergoing some change at the moment, so you may want to go with an older more stable revision.

august 4, 2010 15:11
 

edsilv said:

That's fantastic. Many thanks :-)

august 4, 2010 16:09
Anonymous comments are disabled