예제 #1
0
 /// <summary>
 /// Encodes a bearing based on the list of coordinates and the BEARDIST parameter.
 /// </summary>
 public static float EncodeBearing(List <Coordinate> coordinates, bool startAtEnd)
 {
     if (startAtEnd)
     {
         return(BearingEncoder.EncodeBearing(new List <Coordinate>(coordinates.Reverse <Coordinate>())));
     }
     return(BearingEncoder.EncodeBearing(coordinates));
 }
예제 #2
0
        /// <summary>
        /// Finds candidate edges starting at a given vertex matching a given fow and frc.
        /// </summary>
        public static IEnumerable <CandidatePathSegment> FindCandidatePathSegmentsFor(this Coder coder, CandidateLocation location, bool forward, FormOfWay fow, FunctionalRoadClass frc,
                                                                                      float bearing)
        {
            var profile       = coder.Profile;
            var relevantEdges = new List <CandidatePathSegment>();

            if (location.Location.IsVertex())
            { // location is a vertex, probably 99% of the time.
                var vertex         = location.Location.VertexId(coder.Router.Db);
                var edgeEnumerator = coder.Router.Db.Network.GetEdgeEnumerator(vertex);
                foreach (var edge in edgeEnumerator)
                {
                    var edgeProfile = coder.Router.Db.EdgeProfiles.Get(edge.Data.Profile);
                    var factor      = profile.Profile.Factor(edgeProfile);

                    if (factor.Value > 0 && (factor.Direction == 0 ||
                                             (forward && (factor.Direction == 1) != edge.DataInverted) ||
                                             (!forward && (factor.Direction == 1) == edge.DataInverted)))
                    {
                        var matchScore = Score.New(Score.MATCH_ARC, "Metric indicating a match with fow, frc etc...",
                                                   profile.Match(edgeProfile, fow, frc), 2);
                        if (matchScore.Value > 0)
                        { // ok, there is a match.
                          // check bearing.
                            var shape            = coder.Router.Db.Network.GetShape(edge);
                            var localBearing     = BearingEncoder.EncodeBearing(shape, false);
                            var localBearingDiff = System.Math.Abs(Extensions.AngleSmallestDifference(localBearing, bearing));

                            var bearingScore = Score.New(Score.BEARING_DIFF, "Bearing difference score (0=1 & 180=0)", (1f - (localBearingDiff / 180f)) * 2, 2);
                            relevantEdges.Add(new CandidatePathSegment()
                            {
                                Score    = location.Score * (matchScore + bearingScore),
                                Location = location.Location,
                                Path     = new EdgePath <float>(edge.To, factor.Value * edge.Data.Distance, edge.IdDirected(), new EdgePath <float>(vertex))
                            });
                        }
                    }
                }
            }
            else
            { // location is not a vertex but a virtual point, try available directions.
                var paths             = location.Location.ToEdgePaths(coder.Router.Db, coder.Profile.Profile.DefaultWeightHandlerCached(coder.Router.Db), forward);
                var edgeEnumerator    = coder.Router.Db.Network.GetEdgeEnumerator();
                var locationOnNetwork = location.Location.LocationOnNetwork(coder.Router.Db);
                foreach (var path in paths)
                {
                    if (path.From == null)
                    {
                        throw new Exception("An LRP was resolved while at the same time it resolved to an exact vertex.");
                    }
                    edgeEnumerator.MoveToEdge(path.Edge);
                    var edge        = edgeEnumerator.Current;
                    var edgeProfile = coder.Router.Db.EdgeProfiles.Get(edge.Data.Profile);

                    var matchScore = Score.New(Score.MATCH_ARC, "Metric indicating a match with fow, frc etc...",
                                               profile.Match(edgeProfile, fow, frc), 2);
                    if (matchScore.Value > 0)
                    { // ok, there is a match.
                      // check bearing.

                        // get shape from location -> path.
                        var shape = location.Location.ShapePointsTo(coder.Router.Db, path.Vertex);
                        shape.Insert(0, locationOnNetwork);
                        shape.Add(coder.Router.Db.Network.GetVertex(path.Vertex));

                        var localBearing     = BearingEncoder.EncodeBearing(shape, false);
                        var localBearingDiff = System.Math.Abs(Extensions.AngleSmallestDifference(localBearing, bearing));

                        var bearingScore = Score.New(Score.BEARING_DIFF, "Bearing difference score (0=1 & 180=0)", (1f - (localBearingDiff / 180f)) * 2, 2);
                        relevantEdges.Add(new CandidatePathSegment()
                        {
                            Score    = location.Score * (matchScore + bearingScore),
                            Location = location.Location,
                            Path     = path
                        });
                    }
                }
            }
            return(relevantEdges);
        }