Esempio n. 1
0
        /// <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)
            });
        }
Esempio n. 2
0
        /// <summary>
        /// Builds a line location along the shortest path between the two given coordinates.
        /// </summary>
        public static ReferencedLine BuildLineLocationFromShortestPath(this ReferencedEncoderBase encoder, GeoCoordinate coordinate1, GeoCoordinate coordinate2,
                                                                       out OsmSharp.Routing.Route route)
        {
            // creates the live edge router.
            var interpreter    = new ShapefileRoutingInterpreter();
            var basicRouter    = new OsmSharp.Routing.Graph.Routing.Dykstra();
            var data           = encoder.Graph.Data;
            var liveEdgeRouter = new TypedRouterLiveEdge(
                data, interpreter, basicRouter);
            var router = new OsmSharp.Routing.Router(liveEdgeRouter);

            // resolve source/target.
            var point1       = router.Resolve(encoder.Vehicle, coordinate1);
            var point2       = router.Resolve(encoder.Vehicle, coordinate2);
            var point1Source = liveEdgeRouter.RouteResolvedGraph(encoder.Vehicle, point1, false);

            var point1Vertices = point1Source.GetVertices().ToList();
            var edge1          = GetEdge(data, (uint)point1Vertices[0], (uint)point1Vertices[1]);

            var point2Source = liveEdgeRouter.RouteResolvedGraph(encoder.Vehicle, point2, true);

            var point2Vertices = point2Source.GetVertices().ToList();
            var edge2          = GetEdge(data, (uint)point2Vertices[0], (uint)point2Vertices[1]);

            // calculate the route.
            var rawPath = basicRouter.Calculate(data, interpreter, encoder.Vehicle, point1Source, point2Source, float.MaxValue, null);

            route = liveEdgeRouter.ConstructRouteFromPath(encoder.Vehicle, rawPath, point1, point2, true);

            // convert route to vertex/edge array.
            var rawRoute   = new List <Tuple <long, LiveEdge> >();
            var routeArray = rawPath.ToArrayWithWeight();

            for (var i = 0; i < routeArray.Length; i++)
            {
                if (routeArray[i].Item1 > -int.MaxValue)
                {
                    rawRoute.Add(new Tuple <long, LiveEdge>(routeArray[i].Item1, new LiveEdge()));

                    if (i > 1)
                    {
                        var vertex1 = rawRoute[rawRoute.Count - 2].Item1;
                        var vertex2 = rawRoute[rawRoute.Count - 1].Item1;

                        if (vertex1 > 0 && vertex2 > 0 &&
                            vertex1 < data.VertexCount && vertex2 < data.VertexCount)
                        {
                            var edge = data.GetEdge((uint)vertex1, (uint)vertex2);
                            rawRoute[rawRoute.Count - 1] = new Tuple <long, LiveEdge>(vertex2, edge);
                        }
                    }
                }
            }

            // replace first parts with resolved edge.
            for (var i = 0; i < rawRoute.Count; i++)
            {
                var vertex = rawRoute[i].Item1;
                if (vertex > 0 && vertex < data.VertexCount)
                { // this is the first valid vertex.
                    while (i > 0)
                    {
                        rawRoute.RemoveAt(0);
                        i--;
                    }

                    if (vertex == point1Vertices[0])
                    {
                        rawRoute[0] = new Tuple <long, LiveEdge>(rawRoute[0].Item1, (LiveEdge)edge1.Reverse());
                        rawRoute.Insert(0, new Tuple <long, LiveEdge>(point1Vertices[1], new LiveEdge()));
                    }
                    else
                    {
                        rawRoute[0] = new Tuple <long, LiveEdge>(rawRoute[0].Item1, (LiveEdge)edge1);
                        rawRoute.Insert(0, new Tuple <long, LiveEdge>(point1Vertices[0], new LiveEdge()));
                    }
                    break;
                }
            }

            for (var i = rawRoute.Count - 1; i >= 0; i--)
            {
                var vertex = rawRoute[i].Item1;
                if (vertex > 0 && vertex < data.VertexCount)
                {
                    while (i <= rawRoute.Count - 1)
                    {
                        rawRoute.RemoveAt(rawRoute.Count - 1);
                        i++;
                    }

                    if (vertex == point2Vertices[0])
                    {
                        rawRoute.Add(new Tuple <long, LiveEdge>(point2Vertices[1], edge2));
                    }
                    else
                    {
                        rawRoute.Add(new Tuple <long, LiveEdge>(point2Vertices[0], (LiveEdge)edge2.Reverse()));
                    }
                    break;
                }
            }

            var vertices = new long[rawRoute.Count];
            var edges    = new LiveEdge[rawRoute.Count - 1];

            for (var i = 0; i < rawRoute.Count; i++)
            {
                vertices[i] = rawRoute[i].Item1;
                if (i > 0)
                {
                    edges[i - 1] = rawRoute[i].Item2;
                }
            }

            var lineLocation = encoder.BuildLineLocation(vertices, edges, 0, 0);

            var coordinates = lineLocation.GetCoordinates(encoder.Graph);
            var total       = (float)coordinates.Length().Value;

            // project point1.
            var               positiveOffset = 0f;
            PointF2D          bestProjected;
            LinePointPosition useless1;
            Meter             bestOffset;
            int               bestIndex;

            if (!coordinates.ProjectOn(point1.Location, out bestProjected, out useless1, out bestOffset, out bestIndex))
            {
                var distanceToProjected = float.MaxValue;
                var totalLength         = 0f;
                for (var i = 0; i < coordinates.Count; i++)
                {
                    var distance = (float)coordinates[i].DistanceEstimate(point1.Location).Value;
                    if (i > 0)
                    {
                        totalLength += (float)coordinates[i].DistanceEstimate(coordinates[i - 1]).Value;
                    }
                    if (distance < distanceToProjected)
                    {
                        distanceToProjected = distance;
                        bestOffset          = totalLength;
                        bestIndex           = i;
                        useless1            = LinePointPosition.On;
                        bestProjected       = coordinates[i];
                    }
                }
            }
            positiveOffset = (float)bestOffset.Value;

            // project point2.
            var negativeOffset = 0f;

            if (!coordinates.ProjectOn(point2.Location, out bestProjected, out useless1, out bestOffset, out bestIndex))
            {
                var distanceToProjected = float.MaxValue;
                var totalLength         = 0f;
                for (var i = 0; i < coordinates.Count; i++)
                {
                    var distance = (float)coordinates[i].DistanceEstimate(point2.Location).Value;
                    if (i > 0)
                    {
                        totalLength += (float)coordinates[i].DistanceEstimate(coordinates[i - 1]).Value;
                    }
                    if (distance < distanceToProjected)
                    {
                        distanceToProjected = distance;
                        bestOffset          = totalLength;
                        bestIndex           = i;
                        useless1            = LinePointPosition.On;
                        bestProjected       = coordinates[i];
                    }
                }
            }
            negativeOffset = total - (float)bestOffset.Value;

            lineLocation.NegativeOffsetPercentage = 100.0f * (negativeOffset / total);
            lineLocation.PositiveOffsetPercentage = 100.0f * (positiveOffset / total);

            return(lineLocation);
        }