Example #1
0
        public Tuple <List <PointF>, float, float> CalculatePathBetweenVertices(GraphVertex vertex1, GraphVertex vertex2, RouteCalculationMode mode)
        {
            //Реализация алгоритма Дейкстры на основе очереди с приоритетом (Heap)
            int n = vertices.Count;

            float[] d = new float[n];
            int[]   p = new int[n];
            for (int i = 0; i < n; i++)
            {
                d[i] = float.MaxValue;
                p[i] = -1;
            }

            d[vertex1.Id] = 0;

            var queue = new SimplePriorityQueue <int, float>();

            queue.Enqueue(vertex1.Id, 0);

            while (queue.Count > 0)
            {
                int v = queue.Dequeue();

                for (int i = 0; i < vertices[v].Edges.Count; i++)
                {
                    int to = vertices[v].Edges[i].Vert2.Id;
                    //если нужен самый короткий путь - минимизируем длину пути.
                    //если нужен самый быстрый - минимизируем время (длина/скорость).
                    float len = (mode == RouteCalculationMode.ShortRoute) ? (vertices[v].Edges[i].Length) : (vertices[v].Edges[i].Time);
                    if (d[v] + len < d[to])
                    {
                        d[to] = d[v] + len;
                        p[to] = v;
                        if (!queue.TryUpdatePriority(to, d[to]))
                        {
                            queue.Enqueue(to, d[to]);
                        }
                    }
                }
            }

            if (p[vertex2.Id] == -1)
            {
                //не нашли путь
                throw new Exception();
            }

            // восстанавливаем путь
            int currentPoint = vertex2.Id;

            var vertPath = new List <int>();

            while (currentPoint != -1)
            {
                vertPath.Add(currentPoint);
                currentPoint = p[currentPoint];
            }

            vertPath.Reverse();

            var edgePath = new List <GraphEdge>();

            for (int i = 0; i < vertPath.Count - 1; i++)
            {
                var vert1 = vertices[vertPath[i]];
                var vert2 = vertices[vertPath[i + 1]];
                var edge  = vert1.Edges.First(e => e.Vert2.Id == vert2.Id);
                edgePath.Add(edge);
            }

            List <PointF> wktPath = edgePath.SelectMany(e => e.Shape).ToList();
            float         length  = edgePath.Sum(edge => edge.Length);
            float         time    = edgePath.Sum(edge => edge.Time);

            return(new Tuple <List <PointF>, float, float>(wktPath, length, time));
        }
Example #2
0
        public RouteCalculationCheckpointResult CalculatePathBetweenPoints(PointF startPoint, PointF finishPoint, RouteCalculationMode mode)
        {
            //TO-DO: Искать не ближайшую точку дороги, а наиболее удобную.
            //TO-DO: Обработать кейс, когда nearStart и nearFinish окажутся одинаковыми
            var nearStart  = this.GetNearVertex(startPoint);
            var nearFinish = this.GetNearVertex(finishPoint);

            var calcResult = CalculatePathBetweenVertices(nearStart, nearFinish, mode);

            if (calcResult.Item1.First() != startPoint)
            {
                calcResult.Item1.Insert(0, startPoint);
            }

            if (calcResult.Item1.Last() != finishPoint)
            {
                calcResult.Item1.Add(finishPoint);
            }

            // Length и Time маршрута учитывают только движение по дорогам
            // и не учитывают время и длину маршрута до ближайшей точки дороги
            var result = new RouteCalculationCheckpointResult
            {
                StartPoint  = startPoint,
                FinishPoint = finishPoint,
                WKTPath     = calcResult.Item1,
                Length      = calcResult.Item2,
                Time        = calcResult.Item3
            };

            return(result);
        }
Example #3
0
        public RouteCalculationResult Calculate(PointF startPoint, List <PointF> checkpoints, RouteCalculationMode mode = RouteCalculationMode.ShortRoute)
        {
            var result = new RouteCalculationResult
            {
                Mode = mode
            };

            var graph = RoadGraph.getInstance();
            var list  = new List <List <Tuple <PointF, PointF> > >();

            foreach (var checkpoint in checkpoints)
            {
                var localResult = graph.CalculatePathBetweenPoints(startPoint, checkpoint, mode);
                result.Checkpoints.Add(localResult);
                result.TotalLength += localResult.Length;
                result.TotalTime   += localResult.Time;
                startPoint          = checkpoint;
            }

            return(result);
        }