Example #1
0
        /// <summary>
        /// Aggregates a route by remove information useless to the generation of routing instructions.
        /// </summary>
        /// <param name="route"></param>
        /// <returns></returns>
        public AggregatedPoint Aggregate(Route route)
        {
            // create the enumerator.
            var enumerator = new AggregatedPointEnumerator(route);

            AggregatedRoutePoint previous      = null;
            AggregatedRoutePoint current       = null;
            AggregatedRoutePoint next          = null;
            AggregatedPoint      previousPoint = null;
            AggregatedArc        previousArc   = null;
            AggregatedPoint      p             = null;

            // loop over all aggregated points.
            while (enumerator.MoveNext())
            {
                // get the next point.
                next = enumerator.Current;

                // process
                this.Process(route, previous, current, next, ref p, ref previousArc, ref previousPoint);

                // make the next, current and the current previous.
                previous = current;
                current  = next;
                next     = null;
            }

            // process once more, the current current has not been processed.
            this.Process(route, previous, current, next, ref p, ref previousArc, ref previousPoint);

            return(p);
        }
Example #2
0
        /// <summary>
        /// Returns true if the point between the two arcs represents a significant step in the route.
        /// </summary>
        /// <param name="previous_arc"></param>
        /// <param name="next_arc"></param>
        /// <param name="vehicle"></param>
        /// <returns></returns>
        private bool IsSignificant(Vehicle vehicle, AggregatedArc previous_arc, AggregatedArc next_arc)
        {
            if (previous_arc.Next.Points != null && previous_arc.Next.Points.Count > 0)
            { // the point has at least one important point.
                return(true);
            }
            if (previous_arc.Next.ArcsNotTaken != null && previous_arc.Next.ArcsNotTaken.Count > 0)
            { // the point has at least one arc not taken.
                return(true);
            }
            // create tag interpreters for arcs to try and work out if the arcs are different for the given vehicle.
            TagsCollection previousTagsDic = new SimpleTagsCollection();

            foreach (Tag pair in previous_arc.Tags)
            {
                previousTagsDic.Add(pair.Key, pair.Value);
            }
            var nextTagsDic = new SimpleTagsCollection();

            foreach (Tag pair in next_arc.Tags)
            {
                nextTagsDic.Add(pair.Key, pair.Value);
            }
            if (!vehicle.IsEqualFor(previousTagsDic, nextTagsDic))
            { // the previous and the next edge do not represent a change for the given vehicle.
                //RoadTagsInterpreterBase previous_interpreter = new RoadTagsInterpreterBase(previous_tags_dic);
                //RoadTagsInterpreterBase next_interpreter = new RoadTagsInterpreterBase(next_tags_dic);
                //if (!previous_interpreter.IsEqualForVehicle(vehicle, next_interpreter))
                //{
                return(true);
            }
            return(false);
        }
        public override void Succes()
        {
            // get the last arc and the last point.
            AggregatedArc   latest_arc   = (this.FinalMessages[this.FinalMessages.Count - 2] as MicroPlannerMessageArc).Arc;
            AggregatedPoint latest_point = (this.FinalMessages[this.FinalMessages.Count - 1] as MicroPlannerMessagePoint).Point;

            // count the number of streets in the same turning direction as the turn
            // that was found.
            int count = 0;

            if (MicroPlannerHelper.IsLeft(latest_point.Angle.Direction, this.Planner.Interpreter))
            {
                count = MicroPlannerHelper.GetLeft(this.FinalMessages, this.Planner.Interpreter);
            }
            else if (MicroPlannerHelper.IsRight(latest_point.Angle.Direction, this.Planner.Interpreter))
            {
                count = MicroPlannerHelper.GetRight(this.FinalMessages, this.Planner.Interpreter);
            }

            // construct the box indicating the location of the resulting find by this machine.
            GeoCoordinate    point1 = latest_point.Location;
            GeoCoordinateBox box    = new GeoCoordinateBox(
                new GeoCoordinate(point1.Latitude - 0.001f, point1.Longitude - 0.001f),
                new GeoCoordinate(point1.Latitude + 0.001f, point1.Longitude + 0.001f));

            //string next_street = latest_point.Next.Name;

            // let the scentence planner generate the correct information.
            this.Planner.SentencePlanner.GenerateRoundabout(box, count - 1, latest_point.Next.Tags);
        }
Example #4
0
        /// <summary>
        /// Calculcates the metrics.
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public override Dictionary <string, double> Calculate(Vehicle vehicle, AggregatedPoint p)
        {
            Dictionary <string, double> result = new Dictionary <string, double>();

            result.Add(DISTANCE_KEY, 0);
            result.Add(TIME_KEY, 0);

            Aggregated next = p;

            while (next != null)
            {
                if (next is AggregatedPoint)
                {
                    AggregatedPoint point = (next as AggregatedPoint);
                    this.CalculatePointMetrics(vehicle, result, point);
                }
                if (next is AggregatedArc)
                {
                    AggregatedArc arc = (next as AggregatedArc);
                    this.CalculateArcMetrics(vehicle, result, arc);
                }

                next = next.GetNext();
            }

            return(result);
        }
Example #5
0
        /// <summary>
        /// Returns true if the point between the two arcs represents a significant step in the route.
        /// </summary>
        /// <param name="previous_arc"></param>
        /// <param name="next_arc"></param>
        /// <param name="vehicle"></param>
        /// <returns></returns>
        protected virtual bool IsSignificant(Vehicle vehicle, AggregatedArc previous_arc, AggregatedArc next_arc)
        {
            if (previous_arc.Next.Points != null && previous_arc.Next.Points.Count > 0)
            { // the point has at least one important point.
                return(true);
            }
            if (previous_arc.Next.ArcsNotTaken != null && previous_arc.Next.ArcsNotTaken.Count > 0)
            { // the point has at least one arc not taken.
                return(true);
            }
            // create tag interpreters for arcs to try and work out if the arcs are different for the given vehicle.
            var previousTagsDic = new TagsCollection();

            if (previous_arc.Tags != null)
            {
                foreach (Tag pair in previous_arc.Tags)
                {
                    previousTagsDic.Add(pair.Key, pair.Value);
                }
            }
            var nextTagsDic = new TagsCollection();

            if (next_arc.Tags != null)
            {
                foreach (Tag pair in next_arc.Tags)
                {
                    nextTagsDic.Add(pair.Key, pair.Value);
                }
            }
            if (!vehicle.IsEqualFor(previousTagsDic, nextTagsDic))
            { // the previous and the next edge do not represent a change for the given vehicle.
                return(true);
            }
            return(false);
        }
Example #6
0
        /// <summary>
        /// Returns true if the point between the two arcs represents a significant step in the route.
        /// </summary>
        /// <param name="previousArc"></param>
        /// <param name="nextArc"></param>
        /// <returns></returns>
        protected virtual bool IsSignificant(AggregatedArc previousArc, AggregatedArc nextArc)
        {
            if (previousArc.Next.Points != null && previousArc.Next.Points.Count > 0)
            { // the point has at least one important point.
                return(true);
            }
            if (previousArc.Next.ArcsNotTaken != null && previousArc.Next.ArcsNotTaken.Count > 0)
            { // the point has at least one arc not taken.
                return(true);
            }

            // a vehicle change is also always significant.
            if (previousArc.Vehicle != nextArc.Vehicle)
            { // there is a vehicle change.
                return(true);
            }

            // create tag interpreters for arcs to try and work out if the arcs are different for the given vehicle.
            var previousTagsDic = new TagsCollection();

            if (previousArc.Tags != null)
            {
                foreach (var pair in previousArc.Tags)
                {
                    previousTagsDic.Add(pair.Key, pair.Value);
                }
            }
            var nextTagsDic = new TagsCollection();

            if (nextArc.Tags != null)
            {
                foreach (var pair in nextArc.Tags)
                {
                    nextTagsDic.Add(pair.Key, pair.Value);
                }
            }
            if (!string.IsNullOrWhiteSpace(previousArc.Vehicle))
            { // there is a vehicle set on the previous arc.
                var vehicle = Vehicle.GetByUniqueName(previousArc.Vehicle);
                if (!vehicle.IsEqualFor(previousTagsDic, nextTagsDic))
                { // the previous and the next edge do not represent a change for the given vehicle.
                    return(true);
                }
            }
            return(false);
        }
        public override void Succes()
        {
            // get the last arc and the last point.
            AggregatedArc   latestArc         = (this.FinalMessages[this.FinalMessages.Count - 2] as MicroPlannerMessageArc).Arc;
            AggregatedPoint latestPoint       = (this.FinalMessages[this.FinalMessages.Count - 1] as MicroPlannerMessagePoint).Point;
            AggregatedArc   secondLatestArc   = (this.FinalMessages[this.FinalMessages.Count - 4] as MicroPlannerMessageArc).Arc;
            AggregatedPoint secondLatestPoint = (this.FinalMessages[this.FinalMessages.Count - 3] as MicroPlannerMessagePoint).Point;

            // count the number of streets in the same turning direction as the turn
            // that was found.
            int count = 0;

            if (MicroPlannerHelper.IsLeft(latestPoint.Angle.Direction, this.Planner.Interpreter))
            {
                count = MicroPlannerHelper.GetLeft(this.FinalMessages, this.Planner.Interpreter);
            }
            else if (MicroPlannerHelper.IsRight(latestPoint.Angle.Direction, this.Planner.Interpreter))
            {
                count = MicroPlannerHelper.GetRight(this.FinalMessages, this.Planner.Interpreter);
            }

            // construct the box indicating the location of the resulting find by this machine.
            GeoCoordinate    point1 = latestPoint.Location;
            GeoCoordinateBox box    = new GeoCoordinateBox(
                new GeoCoordinate(point1.Latitude - 0.001f, point1.Longitude - 0.001f),
                new GeoCoordinate(point1.Latitude + 0.001f, point1.Longitude + 0.001f));

            // get all the names/direction/counts.
            TagsCollectionBase nextName    = latestPoint.Next.Tags;
            TagsCollectionBase betweenName = latestArc.Tags;
            TagsCollectionBase beforeName  = secondLatestArc.Tags;

            int firstCount = count;

            RelativeDirection firstTurn  = secondLatestPoint.Angle;
            RelativeDirection secondTurn = latestPoint.Angle;

            // let the scentence planner generate the correct information.
            this.Planner.SentencePlanner.GenerateImmidiateTurn(latestPoint.EntryIdx, box, beforeName,
                                                               firstTurn, firstCount, secondTurn, betweenName, nextName, latestPoint.Points);
        }
Example #8
0
        /// <summary>
        /// Processes a part of the route.
        /// </summary>
        private void Process(Route route, AggregatedRoutePoint previous, AggregatedRoutePoint current,
                             AggregatedRoutePoint next, ref AggregatedPoint p, ref AggregatedArc previousArc, ref AggregatedPoint previousPoint)
        {
            // process the current point.
            if (current != null)
            {
                if (previous == null)
                { // point is always significant, it is the starting point!
                    // create point.
                    p              = new AggregatedPoint();
                    p.Angle        = null;
                    p.ArcsNotTaken = null;
                    p.Location     = new GeoCoordinate(current.Segment.Latitude, current.Segment.Longitude);
                    p.Points       = new List <PointPoi>();
                    p.SegmentIdx   = current.SegmentIndex;

                    if (current.Segment.Points != null)
                    {
                        foreach (var routePoint in current.Segment.Points)
                        {
                            var poi = new PointPoi();
                            poi.Name     = routePoint.Name;
                            poi.Tags     = routePoint.Tags.ConvertTo();
                            poi.Location = new GeoCoordinate(routePoint.Latitude, routePoint.Longitude);
                            poi.Angle    = null; // there is no previous point; no angle is specified.
                            p.Points.Add(poi);
                        }
                    }

                    previousPoint = p;
                }
                else
                { // test if point is significant.
                    var nextArc = this.CreateArcAndPoint(route, previous, current, next);

                    // test if the next point is significant.
                    if (previousArc == null)
                    { // this arc is always significant; it is the first arc.
                        previousPoint.Next = nextArc;
                        previousArc        = nextArc;
                    }
                    else
                    {     // there is a previous arc; a test can be done if the current point is significant.
                        if (this.IsSignificant(previousArc, nextArc))
                        { // the arc is significant; append it to the previous arc.
                            previousArc.Next.Next = nextArc;
                            previousArc           = nextArc;
                            previousPoint         = nextArc.Next;
                        }
                        else
                        { // if the arc is not significant compared to the previous one, the previous one can extend until the next point.
                          // THIS IS THE AGGREGATION STEP!

                            // add distance.
                            var distanceToNext = previousArc.Next.Location.DistanceReal(nextArc.Next.Location);
                            previousArc.Distance = previousArc.Distance + distanceToNext;

                            // set point.
                            previousArc.Next = nextArc.Next;
                        }
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Generates an arc and it's next point from the current aggregated point.
        /// </summary>
        /// <param name="route"></param>
        /// <param name="previous"></param>
        /// <param name="current"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        internal AggregatedArc CreateArcAndPoint(Route route, AggregatedRoutePoint previous,
                                                 AggregatedRoutePoint current, AggregatedRoutePoint next)
        {
            // create the arc.
            var a = new AggregatedArc();

            a.Name    = current.Segment.Name;
            a.Names   = current.Segment.Names.ConvertTo();
            a.Tags    = current.Segment.Tags.ConvertToTagsCollection();
            a.Vehicle = string.IsNullOrWhiteSpace(route.Vehicle) ? current.Segment.Vehicle : route.Vehicle;
            if (previous != null)
            {
                var previousCoordinate = new GeoCoordinate(previous.Segment.Latitude, previous.Segment.Longitude);
                var currentCoordinate  = new GeoCoordinate(current.Segment.Latitude, current.Segment.Longitude);

                var distance = previousCoordinate.DistanceReal(currentCoordinate);
                a.Distance = distance;
            }

            // create the point.
            var p = new AggregatedPoint();

            p.Location   = new GeoCoordinate(current.Segment.Latitude, current.Segment.Longitude);
            p.Points     = new List <PointPoi>();
            p.SegmentIdx = current.SegmentIndex;
            if (previous != null && next != null && next.Segment != null)
            {
                var previousCoordinate = new GeoCoordinate(previous.Segment.Latitude, previous.Segment.Longitude);
                var nextCoordinate     = new GeoCoordinate(next.Segment.Latitude, next.Segment.Longitude);

                p.Angle = RelativeDirectionCalculator.Calculate(previousCoordinate, p.Location, nextCoordinate);
            }
            if (current.Segment.SideStreets != null && current.Segment.SideStreets.Length > 0)
            {
                p.ArcsNotTaken = new List <KeyValuePair <RelativeDirection, AggregatedArc> >();
                foreach (var sideStreet in current.Segment.SideStreets)
                {
                    var side = new AggregatedArc();
                    side.Name  = sideStreet.Name;
                    side.Names = sideStreet.Names.ConvertTo();
                    side.Tags  = sideStreet.Tags.ConvertToTagsCollection();

                    RelativeDirection sideDirection = null;
                    if (previous != null)
                    {
                        var previousCoordinate = new GeoCoordinate(previous.Segment.Latitude, previous.Segment.Longitude);
                        var nextCoordinate     = new GeoCoordinate(sideStreet.Latitude, sideStreet.Longitude);

                        sideDirection = RelativeDirectionCalculator.Calculate(previousCoordinate, p.Location, nextCoordinate);
                    }

                    p.ArcsNotTaken.Add(new KeyValuePair <RelativeDirection, AggregatedArc>(sideDirection, side));
                }
            }
            if (current.Segment.Points != null)
            {
                foreach (var routePoint in current.Segment.Points)
                {
                    var poi = new PointPoi();
                    poi.Name     = routePoint.Name;
                    poi.Tags     = routePoint.Tags.ConvertTo();
                    poi.Location = new GeoCoordinate(routePoint.Latitude, routePoint.Longitude);

                    var previousCoordinate = new GeoCoordinate(previous.Segment.Latitude, previous.Segment.Longitude);
                    var currentCoordinate  = new GeoCoordinate(current.Segment.Latitude, current.Segment.Longitude);
                    poi.Angle = RelativeDirectionCalculator.Calculate(previousCoordinate, currentCoordinate, poi.Location);

                    p.Points.Add(poi);
                }
            }

            // link the arc to the point.
            a.Next = p;

            return(a);
        }
Example #10
0
        /// <summary>
        /// Generates an arc and it's next point from the current aggregated point.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="current"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        internal AggregatedArc CreateArcAndPoint(AggregatedRoutePoint previous, AggregatedRoutePoint current, AggregatedRoutePoint next)
        {
            // create the arc.
            AggregatedArc a = new AggregatedArc();

            a.Name  = current.Entry.WayFromName;
            a.Names = current.Entry.WayFromNames.ConvertTo();
            a.Tags  = current.Entry.Tags.ConvertToTagsCollection();
            if (previous != null)
            {
                GeoCoordinate previous_coordinate =
                    new GeoCoordinate(previous.Entry.Latitude, previous.Entry.Longitude);
                GeoCoordinate current_coordinate = new GeoCoordinate(current.Entry.Latitude, current.Entry.Longitude);

                Meter distance = previous_coordinate.DistanceReal(current_coordinate);
                a.Distance = distance;
            }


            // create the point.
            AggregatedPoint p = new AggregatedPoint();

            p.Location = new GeoCoordinate(current.Entry.Latitude, current.Entry.Longitude);
            p.Points   = new List <PointPoi>();
            if (previous != null && next != null && next.Entry != null)
            {
                GeoCoordinate previous_coordinate =
                    new GeoCoordinate(previous.Entry.Latitude, previous.Entry.Longitude);
                GeoCoordinate next_coordinate =
                    new GeoCoordinate(next.Entry.Latitude, next.Entry.Longitude);

                p.Angle = RelativeDirectionCalculator.Calculate(previous_coordinate, p.Location, next_coordinate);
            }
            if (current.Entry.SideStreets != null && current.Entry.SideStreets.Length > 0)
            {
                p.ArcsNotTaken = new List <KeyValuePair <RelativeDirection, AggregatedArc> >();
                foreach (RoutePointEntrySideStreet side_street in current.Entry.SideStreets)
                {
                    AggregatedArc side = new AggregatedArc();
                    side.Name  = side_street.WayName;
                    side.Names = side_street.WayNames.ConvertTo();
                    side.Tags  = side_street.Tags.ConvertToTagsCollection();

                    RelativeDirection side_direction = null;
                    if (previous != null)
                    {
                        GeoCoordinate previous_coordinate =
                            new GeoCoordinate(previous.Entry.Latitude, previous.Entry.Longitude);
                        GeoCoordinate next_coordinate =
                            new GeoCoordinate(side_street.Latitude, side_street.Longitude);

                        side_direction = RelativeDirectionCalculator.Calculate(previous_coordinate, p.Location, next_coordinate);
                    }

                    p.ArcsNotTaken.Add(new KeyValuePair <RelativeDirection, AggregatedArc>(side_direction, side));
                }
            }
            if (current.Entry.Points != null)
            {
                foreach (RoutePoint route_point in current.Entry.Points)
                {
                    PointPoi poi = new PointPoi();
                    poi.Name     = route_point.Name;
                    poi.Tags     = route_point.Tags.ConvertTo();
                    poi.Location = new GeoCoordinate(route_point.Latitude, route_point.Longitude);

                    GeoCoordinate previous_coordinate =
                        new GeoCoordinate(previous.Entry.Latitude, previous.Entry.Longitude);
                    GeoCoordinate current_coordinate = new GeoCoordinate(current.Entry.Latitude, current.Entry.Longitude);
                    poi.Angle = RelativeDirectionCalculator.Calculate(previous_coordinate, current_coordinate, poi.Location);

                    p.Points.Add(poi);
                }
            }

            // link the arc to the point.
            a.Next = p;

            return(a);
        }
Example #11
0
        /// <summary>
        /// Calculate metrics for a given arc.
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="result"></param>
        /// <param name="arc"></param>
        private void CalculateArcMetrics(Vehicle vehicle, Dictionary <string, double> result, AggregatedArc arc)
        {
            // update the distance.
            result[DISTANCE_KEY] = result[DISTANCE_KEY] + arc.Distance.Value;

            // update the time.
            KilometerPerHour speed = vehicle.ProbableSpeed(arc.Tags);
            Second           time  = arc.Distance / speed;

            // FOR NOW USE A METRIC OF 75% MAX SPEED.
            // TODO: improve this for a more realistic estimated based on the type of road.
            result[TIME_KEY] = result[TIME_KEY] + time.Value;
        }