Ejemplo n.º 1
0
        protected override void OnClick()
        {
            QueuedTask.Run(() =>
            {
                var mapView = MapView.Active;
                if (mapView == null)
                {
                    return;
                }

                var polylines = GetRouteLines();
                var leftRail  = polylines[0];
                var rightRail = polylines[1];

                double currentTimeSeconds = 0;
                MapPoint prevPoint        = null;

                var cameraTrack = mapView.Map.Animation.Tracks.OfType <CameraTrack>().First();

                for (int i = 0; i < leftRail.Points.Count; i++)
                {
                    var leftPoint           = leftRail.Points[i];
                    var rightPoint          = rightRail.Points[i];
                    var currentPoint        = GetAveragePoint(leftPoint, rightPoint);
                    List <Vector3D> vectors = null;

                    if (i + 1 == leftRail.Points.Count)
                    {
                        vectors = GetVectors(currentPoint, prevPoint, leftPoint, rightPoint);
                    }
                    else
                    {
                        var nextPoint = GetAveragePoint(leftRail.Points[i + 1], rightRail.Points[i + 1]);
                        vectors       = GetVectors(nextPoint, currentPoint, leftPoint, rightPoint);
                    }

                    var offsetPoint = MapPointBuilder.CreateMapPoint(currentPoint.X + (_metersAbove * vectors[1].X),
                                                                     currentPoint.Y + (_metersAbove * vectors[1].Y),
                                                                     currentPoint.Z + (_metersAbove * vectors[1].Z),
                                                                     currentPoint.SpatialReference);

                    var camera = new ArcGIS.Desktop.Mapping.Camera(offsetPoint.X, offsetPoint.Y, offsetPoint.Z, 0.0, 0.0, offsetPoint.SpatialReference, CameraViewpoint.LookFrom);

                    #region Heading

                    var radian     = Math.Atan2(vectors[0].X, vectors[0].Y);
                    var heading    = radian * -180 / Math.PI;
                    camera.Heading = heading;

                    #endregion

                    #region Pitch

                    var hypotenuse = Math.Sqrt(Math.Pow(vectors[0].X, 2) + Math.Pow(vectors[0].Y, 2));
                    radian         = Math.Atan2(vectors[0].Z, hypotenuse);
                    var pitch      = (radian * 180 / Math.PI);
                    camera.Pitch   = pitch;

                    #endregion

                    #region Roll

                    var d0   = new Vector3D(vectors[0].X, vectors[0].Y, 0);
                    var u0   = new Vector3D(0, 0, 1);
                    var r0   = Vector3D.CrossProduct(u0, d0);
                    var roll = Vector3D.AngleBetween(r0, vectors[2]);
                    if (vectors[2].Z < 0)
                    {
                        roll *= -1;
                    }
                    camera.Roll = roll;

                    #endregion

                    #region Speed

                    if (i > 0)
                    {
                        var line = PolylineBuilder.CreatePolyline(new List <MapPoint>()
                        {
                            prevPoint, currentPoint
                        }, currentPoint.SpatialReference);
                        var length = GeometryEngine.Length3D(line) * currentPoint.SpatialReference.Unit.ConversionFactor;

                        if (!_hasDropped && !(_hasDropped = (vectors[0].Z < 0)))
                        {
                            currentTimeSeconds += length / _currentSpeed;
                        }
                        else
                        {
                            _currentSpeed       = Math.Sqrt(((Math.Pow(_currentSpeed, 2) / 2) + 9.8 * (prevPoint.Z - currentPoint.Z)) * 2);
                            currentTimeSeconds += length / _currentSpeed;
                        }
                    }

                    #endregion

                    cameraTrack.CreateKeyframe(camera, TimeSpan.FromSeconds(currentTimeSeconds), AnimationTransition.FixedArc);
                    prevPoint = currentPoint;
                }
            });
        }