在本次GIS项目开发中,需要实现轨迹回放功能;就是从地图上了一个点,经过N个点,一路慢慢的移动,而实现这效果的最好方式就是Siverlight足帧动画了。好了废话不说,先介绍下Demo结构,看图:
persion.xaml用户控件里面显示一张图片。当然有了这个userControl,那基本上什么多可以放了。看Persion.xaml代码:
Persion.xaml
1 <UserControl x:Class="Silverlight.Views.Persion"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable="d"
7 d:DesignHeight="300" d:DesignWidth="400">
8
9 <Canvas>
10 <Canvas.Background>
11 <ImageBrush ImageSource="/Silverlight;component/Images/persion.png"></ImageBrush>
12 </Canvas.Background>
13 </Canvas>
14 </UserControl>
cs文件里面就定义了X和Y两个属性,定义这两个属性的目的是能为Storyboard.SetTargetProperty服务;
Persion.xaml.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12
13 namespace Silverlight.Views
14 {
15 public partial class Persion : UserControl
16 {
17 public Persion()
18 {
19 InitializeComponent();
20 }
21
22
23 #region 属性
24 //获取或设置X坐标
25 public double X
26 {
27 get { return (double)GetValue(XProperty); }
28 set
29 {
30 SetValue(XProperty, value);
31 SetElementEnvelope();
32 }
33 }
34 public static DependencyProperty XProperty = DependencyProperty.Register("X", typeof(double), typeof(Persion), new PropertyMetadata(OnXChange));
35 static void OnXChange(DependencyObject sender, DependencyPropertyChangedEventArgs e)
36 {
37 (sender as Persion).X = (double)e.NewValue;
38 }
39
40 //获取或设置Y坐标
41 public double Y
42 {
43 get { return (double)GetValue(YProperty); }
44 set
45 {
46 SetValue(YProperty, value);
47 SetElementEnvelope();
48 }
49 }
50
51 public static DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double), typeof(Persion), new PropertyMetadata(OnYChange));
52 static void OnYChange(DependencyObject sender, DependencyPropertyChangedEventArgs e)
53 {
54 (sender as Persion).Y = (double)e.NewValue;
55 }
56 //设置Envelope属性
57 private void SetElementEnvelope()
58 {
59 SetValue(ESRI.ArcGIS.Client.ElementLayer.EnvelopeProperty, new ESRI.ArcGIS.Client.Geometry.Envelope(X, Y, X, Y));
60 }
61 #endregion
62 }
63 }
搞定了persion后到地图上面来实现。
MainPage.xaml
1 <UserControl xmlns:esri="http://schemas.esri.com/arcgis/client/2009" x:Class="Silverlight.MainPage"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 mc:Ignorable="d"
7 d:DesignHeight="300" d:DesignWidth="400">
8
9 <Grid x:Name="LayoutRoot" Background="White">
10 <esri:Map x:Name="map1">
11 <esri:ArcGISTiledMapServiceLayer Url="http://192.168.8.188/ArcGIS/rest/services/kjtxnetMain/MapServer"></esri:ArcGISTiledMapServiceLayer>
12 </esri:Map>
13 </Grid>
14 </UserControl>
mainpage.xaml.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Documents;
8 using System.Windows.Input;
9 using System.Windows.Media;
10 using System.Windows.Media.Animation;
11 using System.Windows.Shapes;
12 using Silverlight.Views;
13
14 namespace Silverlight
15 {
16 public partial class MainPage : UserControl
17 {
18 private ESRI.ArcGIS.Client.ElementLayer _elementLayer = new ESRI.ArcGIS.Client.ElementLayer()
19 {
20 ID = "elementLayer"
21 };
22 //起始坐标
23 private ESRI.ArcGIS.Client.Geometry.MapPoint starPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(108.477998481483, 31.2812729500709);
24 //结束坐标
25 private ESRI.ArcGIS.Client.Geometry.MapPoint endPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(108.144513331365, 30.8702332329334);
26 private Storyboard storyboard = new Storyboard();
27 private Persion persion = null;
28 public MainPage()
29 {
30 InitializeComponent();
31 map1.Layers.Add(_elementLayer);
32
33 /*
34 把persion添加到ESRI.ArcGIS.Client.ElementLayer,
35 * ESRI.ArcGIS.Client.ElementLayer在添加Child之前必须设置Envelope,
36 */
37 persion = new Persion()
38 {
39 X= starPoint.X,
40 Y=starPoint.Y,
41 Width=50,
42 Height=50
43 };
44 _elementLayer.Children.Add(persion);
45
46 Start();
47 }
48
49 private void Start()
50 {
51 storyboard.Pause();
52 storyboard.Completed -= new EventHandler(storyboard_Completed);
53 storyboard = new Storyboard();
54
55 DoubleAnimationUsingKeyFrames framX = new DoubleAnimationUsingKeyFrames();
56 DoubleAnimationUsingKeyFrames framy = new DoubleAnimationUsingKeyFrames();
57
58 LinearDoubleKeyFrame keyX = new LinearDoubleKeyFrame()
59 {
60 Value=endPoint.X,
61 KeyTime =KeyTime.FromTimeSpan(TimeSpan.FromSeconds(5))
62 };
63 LinearDoubleKeyFrame keyY = new LinearDoubleKeyFrame()
64 {
65 Value = endPoint.Y,
66 KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(5))
67 };
68 framX.KeyFrames.Add(keyX);
69 framy.KeyFrames.Add(keyY);
70
71 Storyboard.SetTarget(framX,persion);
72 Storyboard.SetTargetProperty(framX,new PropertyPath(Persion.XProperty));
73 Storyboard.SetTarget(framy, persion);
74 Storyboard.SetTargetProperty(framy, new PropertyPath(Persion.YProperty));
75
76 storyboard.Children.Add(framX);
77 storyboard.Children.Add(framy);
78
79 storyboard.Completed += new EventHandler(storyboard_Completed);
80 storyboard.Begin();
81 }
82
83 void storyboard_Completed(object sender, EventArgs e)
84 {
85
86 }
87
88
89 }
90 }
到这已经可以看到Persion从starPoint流畅的移动到endPoint。如有更好的实现方法还请指教。