/// <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); }
/// <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; } } } } }
/// <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); }