Silverlight VirtualEarth Map Control - test #4 (works)

After attempts one, two and three, it works!. The 'official course image' pans and zooms in 'real time' AS DOES the course path (now a MapPolyline) AND the animated Ellipse 'runners' (now using MapLayer.MapPosition and MapLayer.MapPositionMethod). pan AND zoom/scale successfully - the only remaining problem is they don't scale in 'real time' (so I hide them while the zoom is in progress).

Open apology

This means I owe an apology to the devs for saying there was a bug, and this couldn't be done. When something is CTP you can hardly complain that the documentation or API is a bit rough - so to those guys: I take it back!

Making it work...

Scaling images on the map

Place your Image inside a m:MapLayer and specify the MapRectangle ONLY - DO NOT specify Height or Width since these will force the image to remain

<Image x:Name="CourseMap4" Source="map1.png"
m:MapLayer.MapRectangle="40.8325608405556,-74.1015908473376,40.5722860972124,-73.843755459154">

Drawing the course line on the map

My original line wasn't working because it was a Path with a Data="m5,5 L 40.2013036809816,33.2764570552147 66,54... attribute, wrapped in a Canvas with a TransformGroup applied. Forcing all that to scale during zoom operations required a pile of code which "knew" at what zoom level those point coordinates were 'based on'.

Changing this to a m:MapPolyline means all that happens automatically!

 <m:MapPolyline 
    Stroke="DarkOrange" StrokeThickness="10" x:Name="Course"
    Locations="40.60359196519483,-74.0542459487915 40.6096520 ... 40.771831872647006,-73.97704124450684"
    />

Animating Location (Latitude/Longitude) properties

Unfortunately animating the 'runner' indicators wasn't as simple. Positioning them was easy - remove Canvas.Top/Left and use MapLayer attached properties:

<Ellipse RenderTransformOrigin="0.5,0.5" Fill="#FF0000ff" Stroke="#FF0000ff" 
    x:Name="craigdunn" Width="11" Height="11"
    m:MapLayer.MapPosition="40.60359196519483,-74.0542459487915"
    m:MapLayer.MapPositionMethod="Center" />

but animating was hard - at least for me - because I couldn't find a simple way to target the MapLayer.MapPosition.Latitude/Longitude properties. By a stroke of good luck, SilverlightNews twittered a link to Animating Custom Attached Properties which provided a solution (via Bryant).

Basically remove the Storyboard.TargetProperty altogether (although the IDE doesn't like this, and you might want to leave a hack-default in)...

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                               x:Name="craigdunnanimX"
                               Storyboard.TargetName="craigdunn">

... and use a custom Attached Property like this

Storyboard.SetTargetProperty(craigdunnanimX, new PropertyPath(Attachments.LatitudeProperty));
Storyboard.SetTargetProperty(craigdunnanimY, new PropertyPath(Attachments.LongitudeProperty));

the key method allowing us to animate the otherwise difficult-to-access Latitude/Longitude properties.

// OnLatitudeChanged required as well
private static void OnLongitudeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    Location l = (Location)((Ellipse)d).GetValue(MapLayer.MapPositionProperty);
    l.Longitude = (double)e.NewValue;
    ((Ellipse)d).SetValue(MapLayer.MapPositionProperty, l);
}

Useful links

blog post

Download the control

Getting Started with the control

Interactive SDK

Look back at Test #1 Test #2 Test #3 and the Silverlight 3.0 beta fun