Interactive Mapping Blog

Mapping Solutions News

Bing Maps Silverlight – smooth zoom skydive animation

Have you ever wondered what it would be like to leap out of an aircraft near the edge of space and plummet to earth ? Austrian skydiver Felix Baumgartner hopes to make an attempt later in 2010, travelling the 23 miles at eye-watering super-sonic speeds.

[http://www.space.com/news/highest-parachute-jump-supersonic-100126.html]

For the rest of us there is the Silverlight Bing Maps Control. Not quite as glamorous but, equally not as uncomfortable.

This sounds like a rather simple Silverlight application, create a map, start zoomed out from your landing point and then smoothly animate the ZoomLevel parameter to ‘plummet’ to earth. The problem is that the default map animation moves too quickly and you cannot animate the Map controls ZoomLevel property yourself from a Storyboard, as Storyboard animations only operate on DependencyProperties.

ZoomLevel is not the only value that developers have needed to animate in past that has not been a DependencyProperty. The solution is to set the Storyboard animation to target your own class member as a DependencyProperty which in turn can modify your intended object member.

Code Snippet
  1. <Storyboard x:Name="ZoomIn">
  2.     <DoubleAnimation x:Name="ZoomLevel"
  3.                     Storyboard.TargetName="MainMap"  
  4.                     From="3.0"
  5.                     To="5.0"
  6.                     Duration="0:0:9" />
  7. </Storyboard>

Within your Silverlight control constructor.

Code Snippet
  1. Storyboard.SetTargetProperty(ZoomLevel,
  2.     new PropertyPath(
  3.         Attachments.MapZoomLevelProperty
  4.         )
  5.     );

Handy Attachments utility class

Code Snippet
  1. public partial class Attachments
  2. {
  3.     // Map Zoom level property
  4.     public static readonly DependencyProperty
  5.         MapZoomLevelProperty =
  6.         DependencyProperty.RegisterAttached("MapZoomLevel",
  7.         typeof(double), typeof(Attachments),
  8.         new PropertyMetadata(
  9.             new PropertyChangedCallback(OnMapZoomLevelChanged)));
  10.  
  11.     public static void SetMapZoomLevel(DependencyObject o,
  12.         double value)
  13.     {
  14.         o.SetValue(MapZoomLevelProperty, value);
  15.     }
  16.  
  17.     public static double GetMapZoomLevel(DependencyObject o)
  18.     {
  19.         return (double)o.GetValue(MapZoomLevelProperty);
  20.     }
  21.  
  22.     private static void OnMapZoomLevelChanged(DependencyObject d,
  23.         DependencyPropertyChangedEventArgs e)
  24.     {
  25.         double z = (double)((Map)d).ZoomLevel;
  26.         z = (double)e.NewValue;
  27.         ((Map)d).ZoomLevel = z;
  28.     }
  29. }

 

Most of this was gleaned from [http://www.conceptdevelopment.net/Silverlight/VEMap05/] and [http://bryantlikes.com/archive/2009/03/23/animation-hack-using-attached-properties-in-silverlight.aspx]

Just to make things a little more realistic the Map object centre Location property can be animated to provide wind shear.Instead of animating the Latitude and Longitude separately a Point based DependencyProperty can be created.

Code Snippet
  1. <Storyboard x:Name="CenterMap">
  2.     <PointAnimation
  3.        x:Name="CenterPoint"
  4.            Storyboard.TargetName="MainMap"
  5.            From="5.0,50.0"
  6.            To="-8.0,56.0"
  7.            Duration="0:0:14" />
  8. </Storyboard>

Within your Silverlight control constructor.

Code Snippet
  1. Storyboard.SetTargetProperty(CenterPoint,
  2.     new PropertyPath(
  3.         Attachments.MapCenterPositionProperty
  4.         )
  5.     );

New property for the Attachments utility class

Code Snippet
  1. // Map Center Position Property as a Point
  2. public static readonly DependencyProperty
  3.     MapCenterPositionProperty =
  4.     DependencyProperty.RegisterAttached(
  5.         "MapCenterPosition",
  6.         typeof(Point),
  7.         typeof(Attachments),
  8.     new PropertyMetadata(
  9.         new PropertyChangedCallback(
  10.             OnMapCenterPositionChanged)));
  11.  
  12. public static void SetMapCenterPosition(
  13.     DependencyObject o, Point value)
  14. {
  15.     o.SetValue(MapCenterPositionProperty, value);
  16. }
  17.  
  18. public static Point GetMapCenterPosition(
  19.     DependencyObject o)
  20. {
  21.     return (Point)o.GetValue(MapCenterPositionProperty);
  22. }
  23.  
  24. private static void OnMapCenterPositionChanged(
  25.     DependencyObject d,
  26.     DependencyPropertyChangedEventArgs e)
  27. {
  28.     Location l = (Location)((Map)d).GetValue(
  29.         Map.CenterProperty);
  30.     Point p = new Point(l.Latitude, l.Longitude);
  31.     p = (Point)e.NewValue;
  32.     double z = (double)((Map)d).ZoomLevel;
  33.     // Y is Latitude, X is Longitude        
  34.     ((Map)d).SetView(new Location(p.Y, p.X), z);
  35. }

Now clip the Map to a circle and animate the containers Angle with a regular DoubleAnimation to create a truly sickening spiralling to the ground experience.

 skydive2 skydive3

The smooth zooming and panning was used to great effect to navigate around the South Africa world cup football stadiums in time with HD video in our World Cup map http://www.theworldcupmap.com

start skydive demo download SkyDive project

Leave a Reply