Ejemplo n.º 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);
        }
Ejemplo n.º 2
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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
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);
        }