Пример #1
0
        public static GeneralMatrix CreateInitialTransformationMatrix(Route route, Size mapSize, LongLat projectionOrigin)
        {
            // create initial adjustment: route should fit in the 75% inner rectangle of the map
            RectangleD routeRectangle = route.BoundingProjectedRectangle(projectionOrigin);
            RectangleD mapRectangle   = new RectangleD(1.0 / 8.0 * mapSize.Width, 1.0 / 8.0 * mapSize.Height, 3.0 / 4.0 * mapSize.Width, 3.0 / 4.0 * mapSize.Height);

            // check width/height ratio for each of the rectangles, and adjust the map rectangle to have the same ratio as the route rectangle
            double routeRatio = routeRectangle.Width / routeRectangle.Height;
            double mapRatio   = mapRectangle.Width / mapRectangle.Height;

            if (mapRatio < routeRatio)
            {
                // too narrow
                mapRectangle = new RectangleD(mapRectangle.Left, mapRectangle.Center.Y - mapRectangle.Width / routeRatio / 2.0, mapRectangle.Width, mapRectangle.Width / routeRatio);
            }
            else
            {
                // too wide
                mapRectangle = new RectangleD(mapRectangle.Center.X - mapRectangle.Height * routeRatio / 2.0, mapRectangle.Top, mapRectangle.Height * routeRatio, mapRectangle.Height);
            }

            GeneralMatrix t = LinearAlgebraUtil.CalculateTransformationMatrix(routeRectangle.LowerLeft, mapRectangle.UpperLeft, routeRectangle.UpperRight, mapRectangle.LowerRight, null, false);

            return(t);
        }
Пример #2
0
        public PointD GetDirectionVectorFromParameterizedLocation(ParameterizedLocation pl)
        {
            if (pl == null)
            {
                return(null);
            }

            double wi = GetWaypointIndexFromParameterizedLocation(pl);

            if (wi == Math.Floor(wi))
            {
                // exactly at a waypoint
                if (wi == 0)
                {
                    // first waypoint
                    AdjustedWaypoint wp0 = segments[pl.SegmentIndex].Waypoints[0];
                    AdjustedWaypoint wp1 = segments[pl.SegmentIndex].Waypoints[1];
                    return(LinearAlgebraUtil.Normalize(wp1.Location - wp0.Location));
                }
                else if ((int)wi == segments[pl.SegmentIndex].Waypoints.Count - 1)
                {
                    // last waypoint
                    int lastWaypointIndex = segments[pl.SegmentIndex].Waypoints.Count - 1;
                    AdjustedWaypoint wp0  = segments[pl.SegmentIndex].Waypoints[lastWaypointIndex - 1];
                    AdjustedWaypoint wp1  = segments[pl.SegmentIndex].Waypoints[lastWaypointIndex];
                    return(LinearAlgebraUtil.Normalize(wp1.Location - wp0.Location));
                }
                else
                {
                    AdjustedWaypoint wp0 = segments[pl.SegmentIndex].Waypoints[(int)wi - 1];
                    AdjustedWaypoint wp1 = segments[pl.SegmentIndex].Waypoints[(int)wi];
                    AdjustedWaypoint wp2 = segments[pl.SegmentIndex].Waypoints[(int)wi + 1];
                    return(LinearAlgebraUtil.Normalize(
                               LinearAlgebraUtil.Normalize(wp2.Location - wp1.Location) +
                               LinearAlgebraUtil.Normalize(wp1.Location - wp0.Location)
                               ));
                }
            }
            else
            {
                AdjustedWaypoint wp0 = segments[pl.SegmentIndex].Waypoints[(int)Math.Floor(wi)];
                AdjustedWaypoint wp1 = segments[pl.SegmentIndex].Waypoints[(int)Math.Ceiling(wi)];
                return(LinearAlgebraUtil.Normalize(wp1.Location - wp0.Location));
            }
        }
Пример #3
0
        public ParameterizedLocation GetClosestParameterizedLocation(PointD location, out double distance)
        {
            if (location == null)
            {
                distance = 0;
                return(null);
            }

            double closestDistance = 0.0;
            ParameterizedLocation closestDistanceParameterizedLocation = new ParameterizedLocation(0, 0);
            bool   closestDistanceSet = false;
            double limit = 2 * 32;

            for (int i = 0; i < segments.Count; i++)
            {
                List <AdjustedWaypoint> waypoints = segments[i].Waypoints;
                PointD p0 = waypoints[0].Location;
                for (int j = 1; j < waypoints.Count; j++)
                {
                    PointD p1 = waypoints[j].Location;

                    // long distance between p0 and p1? then we need to check more time-consuming ClosestDistancePointToLine even if p0 is far from location
                    bool isLongLineSegment = (LinearAlgebraUtil.DistancePointToPoint(p0, p1) > limit);

                    if (LinearAlgebraUtil.DistancePointToPoint(location, p1) < limit || isLongLineSegment)
                    {
                        double t;
                        double tmpDistance = LinearAlgebraUtil.ClosestDistancePointToLine(location, p0, p1, out t);
                        if (tmpDistance < closestDistance || !closestDistanceSet)
                        {
                            closestDistance = tmpDistance;
                            closestDistanceParameterizedLocation =
                                new ParameterizedLocation(i,
                                                          waypoints[j - 1].ParameterizedLocation.Value + t * (waypoints[j].ParameterizedLocation.Value - waypoints[j - 1].ParameterizedLocation.Value));
                            closestDistanceSet = true;
                        }
                    }
                    p0 = p1;
                }
            }

            distance = closestDistance;
            return(closestDistanceSet ? closestDistanceParameterizedLocation : null);
        }
Пример #4
0
        public Transformation(LongLatBox longLatBox, Size imageSize)
        {
            // calculate projection origin
            ProjectionOrigin = new LongLat((longLatBox.East + longLatBox.West) / 2,
                                           (longLatBox.North + longLatBox.South) / 2);

            // get image corners from kml file
            var imageCornerLongLats = longLatBox.GetRotatedBoxCornerLongLats();

            // project them on flat surface
            var projectedImageCorners = new Dictionary <Corner, PointD>();

            projectedImageCorners[Corner.NorthWest] = imageCornerLongLats[Corner.NorthWest].Project(ProjectionOrigin);
            projectedImageCorners[Corner.SouthEast] = imageCornerLongLats[Corner.SouthEast].Project(ProjectionOrigin);

            // calculate transformation matrix
            TransformationMatrix = LinearAlgebraUtil.CalculateTransformationMatrix(
                projectedImageCorners[Corner.NorthWest], new PointD(0, 0),
                projectedImageCorners[Corner.SouthEast], new PointD(imageSize.Width - 1, imageSize.Height - 1), null, true);
        }
Пример #5
0
        public static LongLat Deproject(PointD coordinate, LongLat projectionOrigin)
        {
            if (LinearAlgebraUtil.DistancePointToPoint(coordinate, new PointD(0, 0)) < 0.0000001)
            {
                return(new LongLat(projectionOrigin.Longitude, projectionOrigin.Latitude));
            }
            const double r       = 6378200; // earth radius in metres
            var          longLat = new LongLat();
            var          rho     = Math.Sqrt(coordinate.X * coordinate.X + coordinate.Y * coordinate.Y);
            var          c       = Math.Asin(rho / r);
            var          lambda0 = projectionOrigin.Longitude * Math.PI / 180.0;
            var          phi1    = projectionOrigin.Latitude * Math.PI / 180.0;

            longLat.Latitude =
                Math.Asin(Math.Cos(c) * Math.Sin(phi1) +
                          (coordinate.Y * Math.Sin(c) * Math.Cos(phi1) / rho)) / Math.PI * 180.0;
            longLat.Longitude = (lambda0 +
                                 Math.Atan(coordinate.X * Math.Sin(c) /
                                           (rho * Math.Cos(phi1) * Math.Cos(c) -
                                            coordinate.Y * Math.Sin(phi1) * Math.Sin(c)))) / Math.PI * 180.0;
            return(longLat);
        }
Пример #6
0
        public Dictionary <Corner, LongLat> GetRotatedBoxCornerLongLats()
        {
            var rotation = -Rotation;

            var corners = new Dictionary <Corner, LongLat>();

            corners[Corner.NorthEast] = new LongLat(East, North);
            corners[Corner.NorthWest] = new LongLat(West, North);
            corners[Corner.SouthWest] = new LongLat(West, South);
            corners[Corner.SouthEast] = new LongLat(East, South);

            var projectionOrigin = new LongLat((East + West) / 2, (North + South) / 2);

            var projectedMapCenter = projectionOrigin.Project(projectionOrigin);

            var projectedCorners = new Dictionary <Corner, PointD>();

            projectedCorners[Corner.NorthEast] = corners[Corner.NorthEast].Project(projectionOrigin);
            projectedCorners[Corner.NorthWest] = corners[Corner.NorthWest].Project(projectionOrigin);
            projectedCorners[Corner.SouthWest] = corners[Corner.SouthWest].Project(projectionOrigin);
            projectedCorners[Corner.SouthEast] = corners[Corner.SouthEast].Project(projectionOrigin);

            var projectedRotatedCorners = new Dictionary <Corner, PointD>();

            projectedRotatedCorners[Corner.NorthEast] = LinearAlgebraUtil.Rotate(projectedCorners[Corner.NorthEast], projectedMapCenter, rotation);
            projectedRotatedCorners[Corner.NorthWest] = LinearAlgebraUtil.Rotate(projectedCorners[Corner.NorthWest], projectedMapCenter, rotation);
            projectedRotatedCorners[Corner.SouthWest] = LinearAlgebraUtil.Rotate(projectedCorners[Corner.SouthWest], projectedMapCenter, rotation);
            projectedRotatedCorners[Corner.SouthEast] = LinearAlgebraUtil.Rotate(projectedCorners[Corner.SouthEast], projectedMapCenter, rotation);

            var rotatedCorners = new Dictionary <Corner, LongLat>();

            rotatedCorners[Corner.NorthWest] = LongLat.Deproject(projectedRotatedCorners[Corner.NorthWest], projectionOrigin);
            rotatedCorners[Corner.NorthEast] = LongLat.Deproject(projectedRotatedCorners[Corner.NorthEast], projectionOrigin);
            rotatedCorners[Corner.SouthWest] = LongLat.Deproject(projectedRotatedCorners[Corner.SouthWest], projectionOrigin);
            rotatedCorners[Corner.SouthEast] = LongLat.Deproject(projectedRotatedCorners[Corner.SouthEast], projectionOrigin);
            return(rotatedCorners);
        }
Пример #7
0
        /// <summary>
        /// Converts a map image pixel coordinate to a longitude and latitude coordinate
        /// </summary>
        /// <param name="mapImagePosition">Map pixel coordinate, referring to unzoomed map without any borders and image header</param>
        /// <returns></returns>
        public LongLat GetLongLatForMapImagePosition(PointD mapImagePosition, GeneralMatrix averageTransformationMatrixInverse)
        {
            var projectedPosition = LinearAlgebraUtil.Transform(mapImagePosition, averageTransformationMatrixInverse);

            return(LongLat.Deproject(projectedPosition, ProjectionOrigin));
        }