コード例 #1
0
        internal double GetGeodesicDistance(MapPoint p1, MapPoint p2)
        {
            var meters = GeometryEngine.GeodesicDistance(p1, p2);

            // convert to current linear unit
            return(UpdateDistanceFromTo(DistanceTypes.Meters, LineDistanceType, meters));
        }
コード例 #2
0
        /// <summary>
        /// Gets a point a certain distance down a polyline
        /// </summary>
        /// <param name="dist">Distance in meters along the line</param>
        /// <param name="course"></param>
        /// <returns></returns>
        private double[] PointAlongLine(double dist, out double course)
        {
            double accDist = 0;

            course = double.NaN;
            if (dist > lineLength)             //reached end - move to next direction, or start over
            {
                directionIndex++;
                Route currDir;
                if (directionIndex >= m_route.Routes.Count)
                {
                    directionIndex = 0;
                }
                currDir       = m_route.Routes[directionIndex];
                lineLength    = GeometryEngine.GeodesicLength(currDir.RouteFeature.Geometry);
                totalDistance = 0;
                drivePath     = currDir.RouteFeature.Geometry as Polyline;
                course        = 0; dist = 0;
            }
            //else
            {
                var parts = drivePath.Parts.GetPartsAsPoints().ToList();
                for (int j = 0; j < parts.Count; j++)
                {
                    var part = parts[j].ToList();
                    for (int i = 0; i < part.Count - 1; i++)
                    {
                        var p1 = part[i];
                        var p2 = part[i + 1];
                        if (p1.X == p2.X && p2.Y == p2.Y)
                        {
                            continue;
                        }
                        double distToWaypoint = GeometryEngine.GeodesicDistance(p1, p2, LinearUnits.Meters);
                        if (dist < accDist + distToWaypoint)
                        {
                            var    distAlongSegment = dist - accDist;
                            double fraction         = distAlongSegment / distToWaypoint;
                            course = GetTrueBearingGeodesic(p1.X, p1.Y, p2.X, p2.Y);
                            return(GetPointFromHeadingGeodesic(new double[] { p1.X, p1.Y }, distAlongSegment, course));
                        }
                        accDist += distToWaypoint;
                    }
                }
            }
            return(null);
        }
コード例 #3
0
        private void CalculateDistances()
        {
            double sum           = 0;
            double maxDistance   = 0;
            double minDistance   = double.MaxValue;
            int    distanceCount = 0;

            Task task = Task.Factory.StartNew(() =>
            {
                lock (_mapPointLock)
                {
                    for (int i = 0; i < _mapPoints.Count - 1; i++)
                    {
                        MapPoint outer = _mapPoints[i];

                        for (int j = i + 1; j < _mapPoints.Count; j++)
                        {
                            MapPoint inner = _mapPoints[j];

                            double distance = GeometryEngine.GeodesicDistance(outer, inner, LinearUnits.Kilometers);
                            sum            += distance;
                            if (maxDistance < distance)
                            {
                                maxDistance = distance;
                            }
                            if (minDistance > distance)
                            {
                                minDistance = distance;
                            }

                            distanceCount++;
                        }
                    }
                }
            });

            task.Wait();

            DistanceSum = sum;
            MaxDistance = maxDistance;
            MinDistance = minDistance == double.MaxValue ? 0 : minDistance;
            if (sum > 0 && distanceCount > 0)
            {
                AvgDistance = sum / distanceCount;
            }
        }
コード例 #4
0
        /// <summary>
        /// Creates a new camera offset from the provided camera around an ellipse.
        /// </summary>
        /// <param name="camera">The starting camera.</param>
        /// <param name="ellipse">The ellipse around which the camera will rotate.</param>
        /// <param name="centerPoint">The center point of the ellipse.</param>
        /// <param name="percentAlong">The percentage around the ellipse to create the camera.</param>
        private Camera OffsetCamera(Camera camera, Polyline ellipse, MapPoint centerPoint, double percentAlong)
        {
            camera = CloneCamera(camera);

            var fromPoint = GeometryEngine.MovePointAlongLine(ellipse, percentAlong, true, 0);

            var segment = LineBuilder.CreateLineSegment(new Coordinate2D(centerPoint.X, centerPoint.Y), new Coordinate2D(fromPoint.X, centerPoint.Y), centerPoint.SpatialReference);
            var difX    = GeometryEngine.GeodesicLength(PolylineBuilder.CreatePolyline(segment, segment.SpatialReference));

            if (centerPoint.X - fromPoint.X < 0)
            {
                difX *= -1;
            }

            segment = LineBuilder.CreateLineSegment(new Coordinate2D(centerPoint.X, centerPoint.Y), new Coordinate2D(centerPoint.X, fromPoint.Y), centerPoint.SpatialReference);
            var difY = GeometryEngine.GeodesicLength(PolylineBuilder.CreatePolyline(segment, segment.SpatialReference));

            if (centerPoint.Y - fromPoint.Y < 0)
            {
                difY *= -1;
            }

            var radian  = Math.Atan2(difX, difY);
            var heading = radian * -180 / Math.PI;

            camera.Heading = heading;

            var difZ       = centerPoint.Z - (camera.Z * ((camera.SpatialReference.IsGeographic) ? 1.0 : camera.SpatialReference.Unit.ConversionFactor));
            var hypotenuse = GeometryEngine.GeodesicDistance(fromPoint, centerPoint);

            radian = Math.Atan2(difZ, hypotenuse);
            var pitch = radian * 180 / Math.PI;

            camera.Pitch = pitch;

            if (fromPoint.SpatialReference.Wkid != camera.SpatialReference.Wkid)
            {
                var transformation = ProjectionTransformation.Create(fromPoint.SpatialReference, camera.SpatialReference);
                fromPoint = GeometryEngine.ProjectEx(fromPoint, transformation) as MapPoint;
            }

            camera.X = fromPoint.X;
            camera.Y = fromPoint.Y;
            return(camera);
        }
コード例 #5
0
        private async void MapView_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Point   screenPoint = e.GetPosition(MyMapView);
            Graphic graphic     = await _graphicsLayer.HitTestAsync(MyMapView, screenPoint);


            if (_lineGraphic != null)
            {
                _graphicsLayer.Graphics.Remove(_lineGraphic);
            }

            if (graphic == null)
            {
                DistanceTextBlock.Text = "";
                return;
            }


            graphic.IsSelected = true;

            if (_selectedGraphic != null)
            {
                var mapPoint         = graphic.Geometry as MapPoint;
                var selectedMapPoint = _selectedGraphic.Geometry as MapPoint;

                if (mapPoint != null && selectedMapPoint != null)
                {
                    double distance = GeometryEngine.GeodesicDistance(mapPoint, selectedMapPoint, LinearUnits.Kilometers);

                    DistanceTextBlock.Text = String.Format("Distance: {0:0.00}", distance);

                    _lineGraphic        = new Graphic(Geodesic.GetGeodesicLine(selectedMapPoint, mapPoint));
                    _lineGraphic.Symbol = new SimpleLineSymbol {
                        Color = Colors.DarkOrange, Width = 3
                    };

                    _graphicsLayer.Graphics.Add(_lineGraphic);
                }

                _selectedGraphic.IsSelected = false;
            }

            _selectedGraphic = graphic;
        }
コード例 #6
0
        /// <summary>
        /// Create keyframes centered around a point.
        /// </summary>
        /// <param name="point">The center point around which the keyframes are created.</param>
        internal Task CreateKeyframesAroundPoint(MapPoint point)
        {
            return(QueuedTask.Run(() =>
            {
                var mapView = MapView.Active;
                var degrees = Animation.Settings.Degrees;
                if (mapView == null || degrees == 0)
                {
                    return;
                }

                //Get the camera track from the active map's animation.
                //There will always be only one camera track in the animation.
                var cameraTrack = mapView.Map.Animation.Tracks.OfType <CameraTrack>().First();
                var camera = mapView.Camera;

                //Calculate the number of keys to create.
                var keyEvery = (degrees < 0) ? -10 : 10; //10 degrees
                var numOfKeys = Math.Floor(degrees / keyEvery);
                var remainder = degrees % keyEvery;

                //To maintain a constant speed we need to divide the total time we want the animation to take by the number of degrees of rotation.
                var duration = Animation.Settings.Duration;
                double timeInterval = duration / Math.Abs(degrees);
                double currentTimeSeconds = GetInsertTime(mapView.Map.Animation);

                //Get the distance from the current location to the point we want to rotate around to get the radius.
                var cameraPoint = MapPointBuilder.CreateMapPoint(camera.X, camera.Y, camera.SpatialReference);
                var radius = GeometryEngine.GeodesicDistance(cameraPoint, point);
                var radian = ((camera.Heading - 90) / 180.0) * Math.PI;

                //If the spatial reference of the point is projected and the unit is not in meters we need to convert the Z values to meters.
                if (!point.SpatialReference.IsGeographic && point.SpatialReference.Unit.ConversionFactor != 1.0)
                {
                    point = MapPointBuilder.CreateMapPoint(point.X, point.Y,
                                                           point.Z * point.SpatialReference.Unit.ConversionFactor, point.SpatialReference);
                }

                //For all geodesic calculations we will use WGS84 so we will project the point if it is not already.
                if (point.SpatialReference.Wkid != SpatialReferences.WGS84.Wkid)
                {
                    var transformation = ProjectionTransformation.Create(point.SpatialReference, SpatialReferences.WGS84);
                    point = GeometryEngine.ProjectEx(point, transformation) as MapPoint;
                }

                //Create an ellipse around the center point.
                var parameter = new GeometryEngine.GeodesicEllipseParameter();
                parameter.Center = point.Coordinate;
                parameter.SemiAxis1Length = radius;
                parameter.SemiAxis2Length = radius;
                parameter.AxisDirection = radian;
                parameter.LinearUnit = LinearUnit.Meters;
                parameter.OutGeometryType = GeometryType.Polyline;
                parameter.VertexCount = 36;
                var ellipse = GeometryEngine.GeodesicEllipse(parameter, point.SpatialReference) as Polyline;

                //For each key we will progressively rotate around the ellipse and calculate the camera position at each.
                for (int i = 0; i <= numOfKeys; i++)
                {
                    var percentAlong = ((Math.Abs(keyEvery) * i) % 360) / 360.0;
                    if (keyEvery > 0)
                    {
                        percentAlong = 1 - percentAlong;
                    }

                    //Get the camera at the position around the ellipse.
                    camera = OffsetCamera(camera, ellipse, point, percentAlong);

                    //Increment the time by the amount of time per key.
                    if (i != 0)
                    {
                        currentTimeSeconds += (timeInterval * Math.Abs(keyEvery));
                    }

                    //Create a new keyframe for the camera.
                    cameraTrack.CreateKeyframe(camera, TimeSpan.FromSeconds(currentTimeSeconds), AnimationTransition.FixedArc);
                }

                //For any degree rotation left over create a keyframe. For example 155, would have a keyframe every 10 degrees and then one for the final 5 degrees.
                if (remainder != 0.0)
                {
                    var percentAlong = ((Math.Abs(keyEvery) * numOfKeys + Math.Abs(remainder)) % 360) / 360.0;
                    if (remainder > 0)
                    {
                        percentAlong = 1 - percentAlong;
                    }

                    OffsetCamera(camera, ellipse, point, percentAlong);

                    //Increment the time and create the keyframe.
                    currentTimeSeconds += (timeInterval * Math.Abs(remainder));
                    cameraTrack.CreateKeyframe(camera, TimeSpan.FromSeconds(currentTimeSeconds), AnimationTransition.FixedArc);
                }
            }));
        }