標籤:arcgis silverlight
概述
前段時間做了一個項目,要求是有一些電力輸送線,電力輸送線或者石油管道都是有流動方向的,使用者想做一個動態效果來類比電力的輸送。其實做簡單了只要線上上標識個箭頭就可以了。但也要是做成動態,至少ArcEngine實現起來是有點麻煩的。但ArcGIS API for Silverlight可以解決這個問題。
實現思路
在地圖上展示輸送電力的線和類比電力輸送方向的電都是ArcGIS API中定義的對象,否者這些資料在地圖上就不好展示了。那麼怎麼讓點沿著線動起來呢?要使用Timer嗎?然後沒間隔0.1秒就算一下點應該在的位置?這是最原始的辦法,相信在比較早期的時候,我們使用ArcEngine做跟蹤會回放的時候都採用這種方式。但現在我們用的API是基於Silverlight的,Silverlight自身是有動畫模組的,我們可以藉助Silverlight的動畫來實現。
Silverlight動畫針對的對象都是Silverligt中定義的點、線或其他對象,這是我們還需要轉換,需要在動畫播放的時候,把擷取的點轉換成ArcGIS API中對象能識別的點。
能解決以上問題,解決方案就差不多了。
實現
首先,我們要定義動畫,Silverlight中定義的動畫類型有很多種,我們使用PointAnimationUsingPath類,通過其名稱也能看到該類的作用。基於線的點動畫。
通過查看該類的定義,我們知道使用該類時需要定義好一段路徑,設定走完這段路經需要多長時間以及是不是迴圈播放。
下面的代碼我們就定義路徑,我們是Crowdsourced Security Testing道的ArcGIS中的線對象,再轉換成動畫中的路徑對象,代碼如下:
Point myStartPoint=new Point (this._ELine.StartPoint.Point.X,this._ELine.StartPoint.Point.Y); List<PathSegment> myPathSegmentList=new List<PathSegment> (); foreach(ESRI.ArcGIS.Client.Geometry.PointCollection myPointCollection in this._ELine.Line.Paths) { List<Point> myPointList=new List<Point> (); foreach(ESRI.ArcGIS.Client.Geometry.MapPoint myMapPoint in myPointCollection) { myPointList.Add (new Point (myMapPoint.X,myMapPoint.Y)); } PolyLineSegment myPolyLineSegment=new PolyLineSegment(myPointList,false); myPathSegmentList.Add (myPolyLineSegment); }定義還是挺麻煩的,但代碼一看就明白,下面我們就動畫對象
PointAnimationUsingPath myPointAnimationUsingPath = new PointAnimationUsingPath();List<PathFigure> myPathFigureList=new List<PathFigure> ();myPathFigureList.Add(new PathFigure (myStartPoint,myPathSegmentList,false));myPointAnimationUsingPath.PathGeometry = new PathGeometry(myPathFigureList);//設定路徑myPointAnimationUsingPath.Duration = new Duration(TimeSpan.FromSeconds(5));//設定走完路徑需要的時間myPointAnimationUsingPath.RepeatBehavior = RepeatBehavior.Forever;//迴圈播放
下面我們就定義要運動的點和畫板:
this._ArrowGraphic = new ArrowGraphic();//定義我們要運動的點對象this._ArrowGraphic.SetZIndex((int)GraphicZIndex.ELineArrow);//顯示在最上面this._ArrowGraphic.Geometry = new ESRI.ArcGIS.Client.Geometry.MapPoint(0, 0);//設定起始位置this._application.GraphicsLayer.Graphics.Add(this._ArrowGraphic);//添加到地圖上this._Storyboard = new Storyboard();//定義畫板this._Storyboard.Children.Add(myPointAnimationUsingPath);//把動畫加到畫板上Storyboard.SetTarget(this._Storyboard, this._ArrowGraphic);//關聯畫板和要啟動並執行對象Storyboard.SetTargetProperty(myPointAnimationUsingPath, new PropertyPath(ArrowGraphic.PointProperty));//關聯動畫對象和運動點的一個屬性this._Storyboard.Begin();//啟動動畫
通過查看PointAnimationUsingPath類的API我們可以知道,該動畫的輸出是一個System.Windows.Point類型的對象,我們必須要把這個對象轉換成ArcGIS API的對象能識別的幾何體才可以,所以我們就自訂了上面執行個體化的ArrowGraphic對象,ArrowGraphic是繼承ArcGIS API 中的Graphic類的一個對象。定義如下:
public class ArrowGraphic:Graphic{ public Point Point { get { return (Point)GetValue(PointProperty); } set { SetValue(PointProperty, value); } } public static readonly DependencyProperty PointProperty = DependencyProperty.Register ("Point", typeof(Point), typeof(ArrowGraphic), new FrameworkPropertyMetadata(OnPointChanged)); public static void OnPointChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ArrowGraphic myArrowGraphic = d as ArrowGraphic; MapPoint myMapPoint = new MapPoint(myArrowGraphic.Point.X,myArrowGraphic.Point.Y); myArrowGraphic.Geometry = myMapPoint; } public ArrowGraphic() { SimpleMarkerSymbol myMarkerSymbol = new SimpleMarkerSymbol(); myMarkerSymbol.Size = 10; myMarkerSymbol.Style = SimpleMarkerSymbol.SimpleMarkerStyle.Circle; myMarkerSymbol.Color = System.Windows.Media.Brushes.Green; this.Symbol = myMarkerSymbol; }}該對象的作用很簡單,就是通過PointProperty把Silverlight的Point轉換成ArcGIS API中的Mappoint,然後賦值給該Graphic,這樣隨著動畫的播放,Graphic的Geometry就會不斷髮生變化,這樣Graphic就可以沿著線移動了。
至於我們自訂的Graphic如何顯示,是點、圖片還是其他就需要自己定義了。
例如我們想顯示成箭頭,箭頭是有方向的,怎麼控制箭頭的方向呢?那就擷取到一個點後,當PointProperty擷取到一個新值後,就可以和上一個值進行角度計算,然後再給Geometry賦值就可以了。
下面是展示效果:
圖片中的線上的幾個綠色的點是一直沿著線動的,實在不會做jpg動畫,只能貼一張靜態圖片了。