コード例 #1
0
ファイル: CoderProfile.cs プロジェクト: mshakurov/OpenLR
        /// <summary>
        /// Matches nwb/fow.
        /// </summary>
        public virtual float Match(IAttributeCollection attributes, FormOfWay fow, FunctionalRoadClass frc)
        {
            FormOfWay           actualFow;
            FunctionalRoadClass actualFrc;

            if (this.Extract(attributes, out actualFrc, out actualFow))
            { // a mapping was found. match and score.
                return(MatchScoring.MatchAndScore(frc, fow, actualFrc, actualFow));
            }
            return(0);
        }
コード例 #2
0
        /// <summary>
        /// Encodes a functional road class into binary data.
        /// </summary>
        /// <param name="functionalRoadClass"></param>
        /// <param name="data"></param>
        /// <param name="startIndex"></param>
        /// <param name="byteIndex"></param>
        public static void Encode(FunctionalRoadClass functionalRoadClass, byte[] data, int startIndex, int byteIndex)
        {
            if (byteIndex > 5)
            {
                throw new ArgumentOutOfRangeException("byteIndex", "byteIndex has to be a value in the range of [0-5].");
            }

            byte value = 0;

            switch (functionalRoadClass)
            {
            case FunctionalRoadClass.Frc0:
                value = 0;
                break;

            case FunctionalRoadClass.Frc1:
                value = 1;
                break;

            case FunctionalRoadClass.Frc2:
                value = 2;
                break;

            case FunctionalRoadClass.Frc3:
                value = 3;
                break;

            case FunctionalRoadClass.Frc4:
                value = 4;
                break;

            case FunctionalRoadClass.Frc5:
                value = 5;
                break;

            case FunctionalRoadClass.Frc6:
                value = 6;
                break;

            case FunctionalRoadClass.Frc7:
                value = 7;
                break;
            }

            byte target = data[startIndex];

            byte mask = (byte)(7 << (5 - byteIndex));

            target = (byte)(target & ~mask);           // set to zero.
            value  = (byte)(value << (5 - byteIndex)); // move value to correct position.
            target = (byte)(target | value);           // add to byte.

            data[startIndex] = target;
        }
コード例 #3
0
ファイル: ReferencedNWBDecoder.cs プロジェクト: emij/OpenLR
        /// <summary>
        /// Calculates a match between the tags collection and the properties of the OpenLR location reference.
        /// </summary>
        /// <param name="tags"></param>
        /// <param name="fow"></param>
        /// <param name="frc"></param>
        /// <returns></returns>
        public override float MatchArc(TagsCollectionBase tags, FormOfWay fow, FunctionalRoadClass frc)
        {
            FormOfWay           actualFow;
            FunctionalRoadClass actualFrc;

            if (NWBMapping.ToOpenLR(tags, out actualFow, out actualFrc))
            { // a mapping was found. match and score.
                return(MatchScoring.MatchAndScore(frc, fow, actualFrc, actualFow));
            }
            return(0);
        }
コード例 #4
0
ファイル: MatchScoring.cs プロジェクト: mshakurov/OpenLR
        /// <summary>
        /// Calculates a matching and score by comparing the expected agains the actual FRC's and FOW's.
        /// </summary>
        /// <param name="expectedFrc"></param>
        /// <param name="expectedFow"></param>
        /// <param name="actualFrc"></param>
        /// <param name="actualFow"></param>
        /// <returns></returns>
        public static float MatchAndScore(FunctionalRoadClass expectedFrc, FormOfWay expectedFow,
                                          FunctionalRoadClass actualFrc, FormOfWay actualFow)
        {
            if (expectedFow == actualFow && expectedFrc == actualFrc)
            { // perfect score.
                return(1);
            }

            // sore frc and fow seperately and take frc for 75% and fow for 25%.
            float frcWeight = .75f, fowWeight = .25f;

            return(MatchScoring.MatchAndScore(expectedFrc, actualFrc) * frcWeight +
                   MatchScoring.MatchAndScore(expectedFow, actualFow) * fowWeight);
        }
コード例 #5
0
ファイル: ReferencedDecoderBase.cs プロジェクト: emij/OpenLR
 /// <summary>
 /// Calculates a route between the two given vertices.
 /// </summary>
 /// <returns></returns>
 public abstract CandidateRoute FindCandidateRoute(CandidateVertexEdge from, CandidateVertexEdge to, FunctionalRoadClass minimum,
                                                   bool ignoreFromEdge = false, bool ignoreToEdge = false);
コード例 #6
0
ファイル: ReferencedDecoderBase.cs プロジェクト: emij/OpenLR
 /// <summary>
 /// Calculates a match between the tags collection and the properties of the OpenLR location reference.
 /// </summary>
 /// <param name="tags"></param>
 /// <param name="fow"></param>
 /// <param name="frc"></param>
 /// <returns></returns>
 public abstract float MatchArc(TagsCollectionBase tags, FormOfWay fow, FunctionalRoadClass frc);
コード例 #7
0
ファイル: ReferencedDecoderBase.cs プロジェクト: emij/OpenLR
        /// <summary>
        /// Finds candidate edges starting at a given vertex matching a given fow and frc.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="forward"></param>
        /// <param name="fow"></param>
        /// <param name="frc"></param>
        /// <param name="bearing"></param>
        /// <returns></returns>
        public virtual IEnumerable <CandidateEdge> FindCandidateEdgesFor(long vertex, bool forward, FormOfWay fow, FunctionalRoadClass frc, Degree bearing)
        {
            var relevantEdges = new List <CandidateEdge>();

            foreach (var arc in this.Graph.GetEdges(vertex))
            {
                var tags = this.Graph.TagsIndex.Get(arc.Value.Tags);

                // check one-way.
                if (_vehicle.CanTraverse(tags))
                { // yay! can traverse.
                    var oneway = _vehicle.IsOneWay(tags);
                    if (oneway == null ||
                        (forward && oneway.Value == arc.Value.Forward) ||
                        (!forward && oneway.Value != arc.Value.Forward))
                    {
                        var score = Score.New(Score.MATCH_ARC, "Metric indicating a match with fow, frc etc...", this.MatchArc(tags, fow, frc), 2);
                        if (score.Value > 0)
                        { // ok, there is a match.
                            // check bearing.
                            var shape            = this.Graph.GetEdgeShape(vertex, arc.Key);
                            var localBearing     = this.GetBearing(vertex, arc.Value, shape, arc.Key, true);
                            var localBearingDiff = (float)System.Math.Abs(localBearing.SmallestDifference(bearing));

                            relevantEdges.Add(new CandidateEdge()
                            {
                                TargetVertex = arc.Key,
                                Score        = score +
                                               Score.New(Score.BEARING_DIFF, "Bearing difference (0=0 & 180=1)", ((180f - localBearingDiff) / 180f), 1),
                                Edge = arc.Value
                            });
                        }
                    }
                }
            }
            return(relevantEdges);
        }
コード例 #8
0
 /// <summary>
 /// Tries to match the given tags and figure out a corresponding frc and fow.
 /// </summary>
 /// <param name="tags"></param>
 /// <param name="frc"></param>
 /// <param name="fow"></param>
 /// <returns>False if no matching was found.</returns>
 public abstract bool TryMatching(TagsCollectionBase tags, out FunctionalRoadClass frc, out FormOfWay fow);
コード例 #9
0
ファイル: MatchScoring.cs プロジェクト: mshakurov/OpenLR
        /// <summary>
        /// Calculates a matching and score by comparing the expected agains the actual FRC's.
        /// </summary>
        /// <param name="expected"></param>
        /// <param name="actual"></param>
        /// <returns></returns>
        public static float MatchAndScore(FunctionalRoadClass expected, FunctionalRoadClass actual)
        {
            if (expected == actual)
            { // perfect score for frc.
                return(1);
            }
            else
            {
                float frcOneDifferent  = 0.8f;
                float frcTwoDifferent  = 0.6f;
                float frcMoreDifferent = 0.2f;

                switch (expected)
                {
                case FunctionalRoadClass.Frc0:
                    if (actual == FunctionalRoadClass.Frc1)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc2)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc1:
                    if (actual == FunctionalRoadClass.Frc0 ||
                        actual == FunctionalRoadClass.Frc2)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc3)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc2:
                    if (actual == FunctionalRoadClass.Frc1 ||
                        actual == FunctionalRoadClass.Frc3)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc4 ||
                             actual == FunctionalRoadClass.Frc0)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc3:
                    if (actual == FunctionalRoadClass.Frc2 ||
                        actual == FunctionalRoadClass.Frc4)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc1 ||
                             actual == FunctionalRoadClass.Frc5)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc4:
                    if (actual == FunctionalRoadClass.Frc3 ||
                        actual == FunctionalRoadClass.Frc5)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc2 ||
                             actual == FunctionalRoadClass.Frc6)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc5:
                    if (actual == FunctionalRoadClass.Frc4 ||
                        actual == FunctionalRoadClass.Frc6)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc3 ||
                             actual == FunctionalRoadClass.Frc7)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc6:
                    if (actual == FunctionalRoadClass.Frc5 ||
                        actual == FunctionalRoadClass.Frc7)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc4)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }

                case FunctionalRoadClass.Frc7:
                    if (actual == FunctionalRoadClass.Frc6)
                    {
                        return(frcOneDifferent);
                    }
                    else if (actual == FunctionalRoadClass.Frc5)
                    {
                        return(frcTwoDifferent);
                    }
                    else
                    {
                        return(frcMoreDifferent);
                    }
                }
                return(0);
            }
        }
コード例 #10
0
ファイル: CoderExtensions.cs プロジェクト: mshakurov/OpenLR
        /// <summary>
        /// Calculates a route between the two given vertices.
        /// </summary>
        public static CandidateRoute FindCandidateRoute(this Coder coder, CandidatePathSegment from, CandidatePathSegment to, FunctionalRoadClass minimum,
                                                        bool invertTargetEdge = true)
        {
            var weightHandler = coder.Profile.Profile.DefaultWeightHandler(coder.Router);

            var directedEdgeFrom = from.Path.Edge;
            var directedEdgeTo   = -to.Path.Edge;

            if (!invertTargetEdge)
            {
                directedEdgeTo = -directedEdgeTo;
            }

            // TODO: probably the bug is one-edge routes.
            var path = coder.Router.TryCalculateRaw(coder.Profile.Profile, weightHandler,
                                                    directedEdgeFrom, directedEdgeTo, coder.Profile.RoutingSettings);

            if (Itinero.LocalGeo.Coordinate.DistanceEstimateInMeter(from.Location.Location(), to.Location.Location()) > coder.Profile.MaxSearch / 2)
            {
                try
                {
                    coder.Profile.RoutingSettings.SetMaxSearch(coder.Profile.Profile.FullName, coder.Profile.MaxSearch * 4);
                    path = coder.Router.TryCalculateRaw(coder.Profile.Profile, weightHandler,
                                                        directedEdgeFrom, directedEdgeTo, coder.Profile.RoutingSettings);
                }
                catch
                {
                    throw;
                }
                finally
                {
                    coder.Profile.RoutingSettings.SetMaxSearch(coder.Profile.Profile.FullName, coder.Profile.MaxSearch);
                }
            }

            // if no route is found, score is 0.
            if (path.IsError)
            {
                return(new CandidateRoute()
                {
                    Route = null,
                    Score = Score.New(Score.CANDIDATE_ROUTE, "Candidate route quality.", 0, 1)
                });
            }

            var pathAsList = path.Value.ToList();
            var edges      = new List <long>();
            var vertices   = new List <uint>();

            for (var i = 0; i < pathAsList.Count; i++)
            {
                vertices.Add(pathAsList[i].Vertex);
                if (i > 0)
                {
                    if (pathAsList[i].Edge != Itinero.Constants.NO_EDGE &&
                        pathAsList[i].Edge != -Itinero.Constants.NO_EDGE)
                    {
                        edges.Add(pathAsList[i].Edge);
                    }
                    else
                    {
                        var   edgeEnumerator = coder.Router.Db.Network.GeometricGraph.Graph.GetEdgeEnumerator();
                        float best;
                        var   edge = edgeEnumerator.FindBestEdge(weightHandler, vertices[vertices.Count - 2],
                                                                 vertices[vertices.Count - 1], out best);
                        edges.Add(edge);
                    }
                }
            }

            var startLocation = from.Location;

            if (!from.Location.IsVertex())
            { // first vertex is virtual.
                vertices[0] = Itinero.Constants.NO_VERTEX;
            }
            else
            { // make sure routerpoint has same edge.
                startLocation = coder.Router.Db.CreateRouterPointForEdgeAndVertex(edges[0], vertices[0]);
            }

            var endLocation = to.Location;

            if (!to.Location.IsVertex())
            { // last vertex is virtual.
                vertices[vertices.Count - 1] = Itinero.Constants.NO_VERTEX;
            }
            else
            { // make sure routerpoint has the same edge.
                endLocation = coder.Router.Db.CreateRouterPointForEdgeAndVertex(edges[edges.Count - 1], vertices[vertices.Count - 1]);
            }

            return(new CandidateRoute()
            {
                Route = new ReferencedLine()
                {
                    Edges = edges.ToArray(),
                    Vertices = vertices.ToArray(),
                    StartLocation = startLocation,
                    EndLocation = endLocation
                },
                Score = Score.New(Score.CANDIDATE_ROUTE, "Candidate route quality.", 1, 1)
            });
        }
コード例 #11
0
ファイル: CoderExtensions.cs プロジェクト: mshakurov/OpenLR
        /// <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);
        }
コード例 #12
0
        /// <summary>
        /// Calculates a path between the two candidates using the information in the candidates.
        /// </summary>
        /// <returns></returns>
        public PathSegment <long> Calculate(BasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter,
                                            Vehicle vehicle, CandidateVertexEdge from, CandidateVertexEdge to, FunctionalRoadClass minimum, uint maxSettles,
                                            bool ignoreFromEdge, bool ignoreToEdge)
        {
            // first check for the simple stuff.
            if (from.Vertex == to.Vertex)
            { // route consists of one vertex.
                return(new PathSegment <long>(from.Vertex));
            }

            // check paths.
            var fromPath = new PathSegment <long>(from.TargetVertex, vehicle.Weight(graph.TagsIndex.Get(from.Edge.Tags),
                                                                                    from.Edge.Distance), new PathSegment <long>(from.Vertex));

            if (!ignoreFromEdge || !ignoreToEdge)
            { // do not check paths when one of the edges need to be ignored.
                if (from.Vertex == to.TargetVertex &&
                    to.Vertex == from.TargetVertex)
                { // edges are the same,
                    return(fromPath);
                }
            }
            if (ignoreFromEdge)
            { // ignore from edge, just use the from-vertex.
                fromPath = new PathSegment <long>(from.Vertex);
            }

            // initialize the heap/visit list.
            var heap    = new BinaryHeap <PathSegment <long> >(maxSettles / 4);
            var visited = new HashSet <long>();

            visited.Add(from.Vertex);

            // set target.
            var target       = to.Vertex;
            var targetWeight = double.MaxValue;

            if (!ignoreToEdge)
            { // also add the target to the visit list and actually search for the target candidate edge ending.
                target = to.TargetVertex;
                visited.Add(to.Vertex);
            }

            // create a path segment from the from-candidate.
            heap.Push(fromPath, (float)fromPath.Weight);

            // keep searching for the target.
            while (true)
            {
                // get the next vertex.
                var current = heap.Pop();
                if (current == null)
                { // there is nothing more in the queue, target will not be found.
                    break;
                }
                if (visited.Contains(current.VertexId))
                { // move to the next neighbour.
                    continue;
                }
                visited.Add(current.VertexId);

                // check for the target.
                if (current.VertexId == target)
                { // target was found.
                    if (ignoreToEdge)
                    {
                        return(current);
                    }
                    return(new PathSegment <long>(to.Vertex, current.Weight, current));
                }

                // check if the maximum settled vertex count has been reached.
                if (visited.Count >= maxSettles)
                { // stop search, target will not be found.
                    break;
                }

                // add the neighbours to queue.
                var neighbours = graph.GetEdges(current.VertexId);
                if (neighbours != null)
                { // neighbours exist.
                    foreach (var neighbour in neighbours)
                    {
                        // check if the neighbour was settled before.
                        if (visited.Contains(neighbour.Key))
                        { // move to the next neighbour.
                            continue;
                        }

                        // get tags and check traversability and oneway.
                        var tags = graph.TagsIndex.Get(neighbour.Value.Tags);
                        if (vehicle.CanTraverse(tags))
                        { // yay! can traverse.
                            var oneway = vehicle.IsOneWay(tags);
                            if (oneway == null ||
                                oneway.Value == neighbour.Value.Forward)
                            {
                                // create path to neighbour and queue it.
                                var weight = vehicle.Weight(graph.TagsIndex.Get(neighbour.Value.Tags), neighbour.Value.Distance);
                                var path   = new PathSegment <long>(neighbour.Key, current.Weight + weight, current);
                                if (path.Weight < targetWeight)
                                { // the weight of the neighbour is smaller than the first neighbour found.
                                    heap.Push(path, (float)path.Weight);

                                    // save distance.
                                    if (path.VertexId == target)
                                    {     // the target is already found, no use of queuing neigbours that have a higher weight.
                                        if (targetWeight > path.Weight)
                                        { // set the weight.
                                            targetWeight = path.Weight;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
コード例 #13
0
 /// <summary>
 /// Calculates a path between the two candidates using the information in the candidates.
 /// </summary>
 public PathSegment <long> Calculate(BasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter,
                                     Vehicle vehicle, CandidateVertexEdge from, CandidateVertexEdge to, FunctionalRoadClass minimum,
                                     bool ignoreFromEdge, bool ignoreToEdge)
 {
     return(this.Calculate(graph, interpreter, vehicle, from, to, minimum, MaxSettles, ignoreFromEdge, ignoreToEdge));
 }
コード例 #14
0
        /// <summary>
        /// Calculates a match between the tags collection and the properties of the OpenLR location reference.
        /// </summary>
        /// <param name="tags"></param>
        /// <param name="fow"></param>
        /// <param name="frc"></param>
        /// <returns></returns>
        public override float MatchArc(TagsCollectionBase tags, FormOfWay fow, FunctionalRoadClass frc)
        {
            string frcString;

            if (!tags.TryGetValue("FRC", out frcString))
            { // not even an FRC column.
                return(0);
            }

            float frcOneDifferent  = 0.8f;
            float frcTwoDifferent  = 0.6f;
            float frcMoreDifferent = 0.4f;

            var frcScore = 0.0f;

            switch (frcString)
            {
            case "0":     // main road.
                if (frc == FunctionalRoadClass.Frc0)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc1)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc2)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "1":     // first class road.
                if (frc == FunctionalRoadClass.Frc1)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc0 ||
                         frc == FunctionalRoadClass.Frc2)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc3)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "2":     // second class road.
                if (frc == FunctionalRoadClass.Frc2)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc1 ||
                         frc == FunctionalRoadClass.Frc3)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc4 ||
                         frc == FunctionalRoadClass.Frc0)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "3":
                if (frc == FunctionalRoadClass.Frc3)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc2 ||
                         frc == FunctionalRoadClass.Frc4)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc1 ||
                         frc == FunctionalRoadClass.Frc5)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "4":
                if (frc == FunctionalRoadClass.Frc4)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc3 ||
                         frc == FunctionalRoadClass.Frc5)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc2 ||
                         frc == FunctionalRoadClass.Frc6)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "5":
                if (frc == FunctionalRoadClass.Frc5)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc4 ||
                         frc == FunctionalRoadClass.Frc6)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc3 ||
                         frc == FunctionalRoadClass.Frc7)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "6":
                if (frc == FunctionalRoadClass.Frc6)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc5 ||
                         frc == FunctionalRoadClass.Frc7)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc4)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "7":
                if (frc == FunctionalRoadClass.Frc7)
                {
                    frcScore = 1;
                }
                else if (frc == FunctionalRoadClass.Frc6)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc5)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;

            case "8":
                if (frc == FunctionalRoadClass.Frc7)
                {
                    frcScore = frcOneDifferent;
                }
                else if (frc == FunctionalRoadClass.Frc6)
                {
                    frcScore = frcTwoDifferent;
                }
                else
                {
                    frcScore = frcMoreDifferent;
                }
                break;
            }

            float fowOneDifferent  = 0.8f;
            float fowMoreDifferent = 0.4f;

            var    fowScore = 0.0f;
            string fowString;

            if (tags.TryGetValue("FOW", out fowString))
            {
                fowScore = 0.2f;
                switch (fowString)
                {
                case "1":
                    if (fow == FormOfWay.Motorway)
                    {
                        fowScore = 1;
                    }
                    else if (fow == FormOfWay.MultipleCarriageWay)
                    {
                        fowScore = fowOneDifferent;
                    }
                    break;

                case "2":
                    if (fow == FormOfWay.MultipleCarriageWay)
                    {
                        fowScore = 1;
                    }
                    else if (fow == FormOfWay.Motorway ||
                             fow == FormOfWay.SingleCarriageWay)
                    {
                        fowScore = fowOneDifferent;
                    }
                    break;

                case "3":
                    if (fow == FormOfWay.SingleCarriageWay)
                    {
                        fowScore = 1;
                    }
                    else if (fow == FormOfWay.MultipleCarriageWay)
                    {
                        fowScore = fowOneDifferent;
                    }
                    break;

                case "4":
                    if (fow == FormOfWay.Roundabout)
                    {
                        fowScore = 1;
                    }
                    fowScore = fowMoreDifferent;
                    break;

                case "8":
                    if (fow == FormOfWay.TrafficSquare)
                    {
                        fowScore = 1;
                    }
                    fowScore = fowMoreDifferent;
                    break;

                case "10":
                    if (fow == FormOfWay.SlipRoad)
                    {
                        fowScore = 1;
                    }
                    fowScore = fowMoreDifferent;
                    break;

                case "6":
                case "7":
                case "9":
                case "11":
                case "12":
                case "14":
                case "15":
                    if (fow == FormOfWay.Other)
                    {
                        fowScore = fowOneDifferent;
                    }
                    break;

                default:
                    if (fow == FormOfWay.Undefined)
                    {
                        fowScore = fowMoreDifferent;
                    }
                    break;
                }
            }
            return(frcScore + fowScore);
        }
コード例 #15
0
        /// <summary>
        /// Tries to match the given tags and figure out a corresponding frc and fow.
        /// </summary>
        /// <param name="tags"></param>
        /// <param name="frc"></param>
        /// <param name="fow"></param>
        /// <returns>False if no matching was found.</returns>
        public override bool TryMatching(TagsCollectionBase tags, out FunctionalRoadClass frc, out FormOfWay fow)
        {
            frc = FunctionalRoadClass.Frc7;
            fow = FormOfWay.Undefined;
            string frcValue;

            if (tags.TryGetValue("FRC", out frcValue))
            {
                switch (frcValue)
                {
                case "0":     // main road.
                    frc = FunctionalRoadClass.Frc0;
                    break;

                case "1":     // main road.
                    frc = FunctionalRoadClass.Frc1;
                    break;

                case "2":     // main road.
                    frc = FunctionalRoadClass.Frc2;
                    break;

                case "3":     // main road.
                    frc = FunctionalRoadClass.Frc3;
                    break;

                case "4":     // main road.
                    frc = FunctionalRoadClass.Frc4;
                    break;

                case "5":     // main road.
                    frc = FunctionalRoadClass.Frc5;
                    break;

                case "6":     // main road.
                    frc = FunctionalRoadClass.Frc6;
                    break;

                case "7":     // main road.
                    frc = FunctionalRoadClass.Frc7;
                    break;
                }
            }
            string fowValue;

            if (tags.TryGetValue("FOW", out fowValue))
            {
                switch (fowValue)
                {
                case "1":     // main road.
                    fow = FormOfWay.Motorway;
                    break;

                case "2":
                    fow = FormOfWay.MultipleCarriageWay;
                    break;

                case "3":
                    fow = FormOfWay.SingleCarriageWay;
                    break;

                case "4":
                    fow = FormOfWay.Roundabout;
                    break;

                case "8":
                    fow = FormOfWay.TrafficSquare;
                    break;

                case "10":
                    fow = FormOfWay.SlipRoad;
                    break;

                case "6":
                case "7":
                case "9":
                case "11":
                case "12":
                case "14":
                case "15":
                    fow = FormOfWay.Other;
                    break;
                }
            }
            return(true);
        }
コード例 #16
0
ファイル: CoderProfile.cs プロジェクト: mshakurov/OpenLR
 /// <summary>
 /// Tries to extract fow/frc from the given attributes.
 /// </summary>
 public abstract bool Extract(IAttributeCollection tags, out FunctionalRoadClass frc, out FormOfWay fow);
コード例 #17
0
ファイル: NWBCoderProfile.cs プロジェクト: mshakurov/OpenLR
        /// <summary>
        /// Extracts nwb/fow.
        /// </summary>
        public override bool Extract(IAttributeCollection attributes, out FunctionalRoadClass frc, out FormOfWay fow)
        {
            fow = FormOfWay.Undefined;
            frc = FunctionalRoadClass.Frc7;
            string baansubsrt = string.Empty, wegbeerder = string.Empty, wegnummer = string.Empty, rijrichting = string.Empty, dvkletter_ = string.Empty;

            if (!attributes.TryGetValue(BAANSUBSRT, out baansubsrt) &
                !attributes.TryGetValue(WEGBEHSRT, out wegbeerder) &
                !attributes.TryGetValue(WEGNUMMER, out wegnummer) &
                !attributes.TryGetValue(HECTOLTTR, out dvkletter_) &
                !attributes.TryGetValue(RIJRICHTNG, out rijrichting))
            { // not even a BAANSUBSRT tag!
                // defaults: FRC5, OTHER.
                fow = FormOfWay.Other;
                frc = FunctionalRoadClass.Frc5;
                return(true);
            }

            // make sure everything is lowercase.
            char?dvkletter = null;  // assume dkv letter is the suffix used for exits etc. see: http://www.wegenwiki.nl/Hectometerpaal#Suffix

            if (!string.IsNullOrWhiteSpace(wegbeerder))
            {
                wegbeerder = wegbeerder.ToLowerInvariant();
            }
            if (!string.IsNullOrWhiteSpace(baansubsrt))
            {
                baansubsrt = baansubsrt.ToLowerInvariant();
            }
            if (!string.IsNullOrWhiteSpace(wegnummer))
            {
                wegnummer = wegnummer.ToLowerInvariant(); if (!string.IsNullOrEmpty(dvkletter_))
                {
                    dvkletter = dvkletter_[0];
                }
            }
            if (!string.IsNullOrWhiteSpace(rijrichting))
            {
                rijrichting = rijrichting.ToLowerInvariant();
            }

            fow = FormOfWay.Other;
            frc = FunctionalRoadClass.Frc5;
            if (wegbeerder == "r")
            {
                if (baansubsrt == "hr")
                {
                    fow = FormOfWay.Motorway;
                    frc = FunctionalRoadClass.Frc0;
                }
                else if (baansubsrt == "nrb" ||
                         baansubsrt == "mrb")
                {
                    fow = FormOfWay.Roundabout;
                    frc = FunctionalRoadClass.Frc0;
                }
                else if (baansubsrt == "pst")
                {
                    if (dvkletter.HasValue)
                    {
                        fow = FormOfWay.SlipRoad;
                        if (dvkletter == 'a' ||
                            dvkletter == 'b' ||
                            dvkletter == 'c' ||
                            dvkletter == 'd')
                        { // r  pst (a|b|c|d)
                            frc = FunctionalRoadClass.Frc3;
                        }
                        else
                        { // r  pst !(a|b|c|d)
                            frc = FunctionalRoadClass.Frc0;
                        }
                    }
                    else if (!string.IsNullOrWhiteSpace(rijrichting))
                    { // r  pst !(a|b|c|d)
                        fow = FormOfWay.SlipRoad;
                        frc = FunctionalRoadClass.Frc0;
                    }
                }
                else if (baansubsrt == "opr" ||
                         baansubsrt == "afr")
                {
                    frc = FunctionalRoadClass.Frc3;
                    fow = FormOfWay.SlipRoad;
                }
                else if (baansubsrt.StartsWith("vb"))
                {
                    if (!string.IsNullOrWhiteSpace(rijrichting))
                    {
                        fow = FormOfWay.SlipRoad;
                        frc = FunctionalRoadClass.Frc0;
                    }
                }
            }
            else if (wegbeerder == "p")
            {
                if (baansubsrt == "hr")
                {
                    frc = FunctionalRoadClass.Frc3;
                    fow = FormOfWay.MultipleCarriageWay;
                    if (string.IsNullOrWhiteSpace(rijrichting))
                    {
                        frc = FunctionalRoadClass.Frc2;
                        fow = FormOfWay.SingleCarriageWay;
                    }
                }
                else if (baansubsrt == "nrb" ||
                         baansubsrt == "mrb")
                {
                    frc = FunctionalRoadClass.Frc3;
                    fow = FormOfWay.Roundabout;
                }
                else if (baansubsrt == "opr" ||
                         baansubsrt == "afr")
                {
                    frc = FunctionalRoadClass.Frc3;
                    fow = FormOfWay.SlipRoad;
                }
                else if (baansubsrt == "pst" ||
                         baansubsrt.StartsWith("vb"))
                {
                    frc = FunctionalRoadClass.Frc3;
                    fow = FormOfWay.SlipRoad;
                }
            }
            return(true);
        }
コード例 #18
0
        /// <summary>
        /// Tries to match the given tags and figure out a corresponding frc and fow.
        /// </summary>
        /// <param name="tags"></param>
        /// <param name="frc"></param>
        /// <param name="fow"></param>
        /// <returns>False if no matching was found.</returns>
        public override bool TryMatching(TagsCollectionBase tags, out FunctionalRoadClass frc, out FormOfWay fow)
        {
            frc = FunctionalRoadClass.Frc7;
            fow = FormOfWay.Undefined;
            string highway;

            if (tags.TryGetValue("highway", out highway))
            {
                switch (highway)
                { // check there reference values against OSM: http://wiki.openstreetmap.org/wiki/Highway
                case "motorway":
                case "trunk":
                    frc = FunctionalRoadClass.Frc0;
                    break;

                case "primary":
                case "primary_link":
                    frc = FunctionalRoadClass.Frc1;
                    break;

                case "secondary":
                case "secondary_link":
                    frc = FunctionalRoadClass.Frc2;
                    break;

                case "tertiary":
                case "tertiary_link":
                    frc = FunctionalRoadClass.Frc3;
                    break;

                case "road":
                case "road_link":
                case "unclassified":
                case "residential":
                    frc = FunctionalRoadClass.Frc4;
                    break;

                case "living_street":
                    frc = FunctionalRoadClass.Frc5;
                    break;

                default:
                    frc = FunctionalRoadClass.Frc7;
                    break;
                }
                switch (highway)
                { // check there reference values against OSM: http://wiki.openstreetmap.org/wiki/Highway
                case "motorway":
                case "trunk":
                    fow = FormOfWay.Motorway;
                    break;

                case "primary":
                case "primary_link":
                    fow = FormOfWay.MultipleCarriageWay;
                    break;

                case "secondary":
                case "secondary_link":
                case "tertiary":
                case "tertiary_link":
                    fow = FormOfWay.SingleCarriageWay;
                    break;

                default:
                    fow = FormOfWay.SingleCarriageWay;
                    break;
                }
                return(true); // should never fail on a highway tag.
            }
            return(false);
        }
コード例 #19
0
ファイル: ReferencedEncoder.cs プロジェクト: emij/OpenLR
 /// <summary>
 /// Tries to match the given tags and figure out a corresponding frc and fow.
 /// </summary>
 /// <param name="tags"></param>
 /// <param name="frc"></param>
 /// <param name="fow"></param>
 /// <returns>False if no matching was found.</returns>
 protected bool TryMatching(TagsCollectionBase tags, out FunctionalRoadClass frc, out FormOfWay fow)
 {
     return(_mainEncoder.TryMatching(tags, out frc, out fow));
 }
コード例 #20
0
        /// <summary>
        /// Calculates a match between the tags collection and the properties of the OpenLR location reference.
        /// </summary>
        /// <param name="tags"></param>
        /// <param name="fow"></param>
        /// <param name="frc"></param>
        /// <returns></returns>
        public override float MatchArc(TagsCollectionBase tags, FormOfWay fow, FunctionalRoadClass frc)
        {
            string highway;

            if (!tags.TryGetValue("highway", out highway))
            { // not even a highway tag!
                return(0);
            }

            // TODO: take into account form of way? Maybe not for OSM-data?
            switch (frc)
            {                              // check there reference values against OSM: http://wiki.openstreetmap.org/wiki/Highway
            case FunctionalRoadClass.Frc0: // main road.
                if (highway == "motorway" || highway == "trunk")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc1:     // first class road.
                if (highway == "primary" || highway == "primary_link")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc2:     // second class road.
                if (highway == "secondary" || highway == "secondary_link")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc3:     // third class road.
                if (highway == "tertiary" || highway == "tertiary_link")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc4:
                if (highway == "road" || highway == "road_link" ||
                    highway == "unclassified" || highway == "residential")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc5:
                if (highway == "road" || highway == "road_link" ||
                    highway == "unclassified" || highway == "residential" ||
                    highway == "living_street")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc6:
                if (highway == "road" || highway == "track" ||
                    highway == "unclassified" || highway == "residential" ||
                    highway == "living_street")
                {
                    return(1);
                }
                break;

            case FunctionalRoadClass.Frc7:     // other class road.
                if (highway == "footway" || highway == "bridleway" ||
                    highway == "steps" || highway == "path" ||
                    highway == "living_street")
                {
                    return(1);
                }
                break;
            }

            if (highway != null && highway.Length > 0)
            { // for any other highway return a low match.
                return(0.2f);
            }
            return(0);
        }
コード例 #21
0
ファイル: ReferencedNWBDecoder.cs プロジェクト: emij/OpenLR
        /// <summary>
        /// Calculates a route between the two given vertices.
        /// </summary>
        /// <returns></returns>
        public override CandidateRoute FindCandidateRoute(CandidateVertexEdge from, CandidateVertexEdge to, FunctionalRoadClass minimum,
                                                          bool ignoreFromEdge = false, bool ignoreToEdge = false)
        {
            var edgeInterpreter = new ShapefileEdgeInterpreter();
            var interpreter     = new ShapefileRoutingInterpreter();
            var path            = this.GetRouter().Calculate(this.Graph, interpreter, this.Vehicle, from, to, minimum,
                                                             ignoreFromEdge, ignoreToEdge);

            // if no route is found, score is 0.
            if (path == null)
            {
                return(new CandidateRoute()
                {
                    Route = null,
                    Score = Score.New(Score.CANDIDATE_ROUTE, "Candidate route quality.", 0, 1)
                });
            }

            var edges    = new List <LiveEdge>();
            var vertices = new List <long>();

            vertices.Add(path.VertexId);
            while (path.From != null)
            {
                // add to vertices list.
                vertices.Add(path.From.VertexId);

                // get edge between current and from.
                var fromVertex = path.From.VertexId;
                var toVertex   = path.VertexId;

                var      edgeDistance = double.MaxValue;
                var      arcs         = this.Graph.GetEdges(fromVertex);
                LiveEdge?edge         = null;
                foreach (var arc in arcs)
                {
                    if (arc.Key == toVertex &&
                        arc.Value.Distance < edgeDistance)
                    { // there is a candidate arc.
                        edgeDistance = arc.Value.Distance;
                        edge         = arc.Value;
                    }
                }

                if (!edge.HasValue)
                { // this should be impossible.
                    throw new Exception("No edge found between two consequtive vertices on a route.");
                }
                edges.Add(edge.Value);


                // move to next segment.
                path = path.From;
            }

            // reverse lists.
            edges.Reverse();
            vertices.Reverse();

            // fill shapes.
            var edgeShapes = new GeoCoordinateSimple[edges.Count][];

            for (int i = 0; i < edges.Count; i++)
            {
                edgeShapes[i] = this.Graph.GetEdgeShape(vertices[i], vertices[i + 1]);
            }

            return(new CandidateRoute()
            {
                Route = new ReferencedLine(this.Graph)
                {
                    Edges = edges.ToArray(),
                    EdgeShapes = edgeShapes,
                    Vertices = vertices.ToArray()
                },
                Score = Score.New(Score.CANDIDATE_ROUTE, "Candidate route quality.", 1, 1)
            });
        }
コード例 #22
0
 /// <summary>
 /// Tries to match the given tags and figure out a corresponding frc and fow.
 /// </summary>
 /// <param name="tags"></param>
 /// <param name="frc"></param>
 /// <param name="fow"></param>
 /// <returns>False if no matching was found.</returns>
 public override bool TryMatching(TagsCollectionBase tags, out FunctionalRoadClass frc, out FormOfWay fow)
 {
     return(NWBMapping.ToOpenLR(tags, out fow, out frc));
 }