qHexWalker 0.0.1
Hexagonal Grid Pathfinding & Maze Visualization on Interactive Maps
Loading...
Searching...
No Matches
dijkstra.cpp
Go to the documentation of this file.
1#include "dijkstra.h"
2
3#include <queue>
4
5std::vector<H3Index> Dijkstra::findShortestPath(H3Index start, H3Index end) {
6 // Проверка валидности индексов
7 if (!isValidCell(start) || !isValidCell(end)) {
8 throw std::domain_error("Невалидные H3 индексы");
9 }
10
11 if (start == end) {
12 throw std::runtime_error("Стартовая и конечная точка равны");
13 }
14
15 const int startRes = getResolution(start);
16 const int endRes = getResolution(end);
17
18 if (startRes != endRes) {
19 throw std::domain_error("Для Dijkstra H3 индексы только одинакового разрешения");
20 return {};
21 }
22
23 // Приоритетная очередь для алгоритма Дейкстры (мин-куча)
24 std::priority_queue<Node, std::vector<Node>, std::greater<>> pq;
25
26 // Карта расстояний
27 std::unordered_map<H3Index, double, H3IndexHash> distances;
28
29 // Карта предшественников для восстановления пути
30 std::unordered_map<H3Index, H3Index, H3IndexHash> previous;
31
32 // Посещенные узлы
33 std::unordered_set<H3Index, H3IndexHash> visited;
34
35 // Инициализация
36 distances[start] = 0.0;
37 pq.push({start, 0.0});
38
39 while (!pq.empty()) {
40 auto [cell, distance] = pq.top();
41 pq.pop();
42
43 // Если достигли конечной точки
44 if (cell == end) {
45 return reconstructPath(previous, start, end);
46 }
47
48 // Если уже посещали этот узел, пропускаем
49 if (visited.contains(cell)) {
50 continue;
51 }
52
53 visited.insert(cell);
54 // Получаем соседей текущей ячейки
55
56 for (std::vector<H3Index> neighbors = getNeighbors(cell); const H3Index &neighbor : neighbors) {
57 if (visited.contains(neighbor)) {
58 continue;
59 }
60
61 // Вычисляем расстояние до соседа
62 // Используем расстояние между центрами ячеек
63 double edgeDistance = getDistanceBetweenCells(cell, neighbor);
64 // Если нашли более короткий путь
65 if (double newDistance = distances[cell] + edgeDistance;
66 !distances.contains(neighbor) || newDistance < distances[neighbor]) {
67 distances[neighbor] = newDistance;
68 previous[neighbor] = cell;
69 pq.push({neighbor, newDistance});
70 }
71 }
72 }
73
74 // Путь не найден
75 // spdlog::warn("Путь не найден между индексами");
76 return {};
77}
78
79std::vector<H3Index> Dijkstra::getNeighbors(const H3Index cell) {
80 std::vector<H3Index> neighbors;
81
82 // H3 v4 API: получаем соседей через gridDisk с k=1
83 int64_t maxSize = 0;
84 H3Error err = maxGridDiskSize(1, &maxSize);
85 if (err != E_SUCCESS) {
86 return neighbors;
87 }
88
89 std::vector<H3Index> ring(maxSize);
90 err = gridDisk(cell, 1, ring.data());
91 if (err != E_SUCCESS) {
92 return neighbors;
93 }
94
95 // Фильтруем результаты (исключаем саму ячейку и нулевые индексы)
96 for (const H3Index &idx : ring) {
97 if (idx != 0 && idx != cell) {
98 neighbors.emplace_back(idx);
99 }
100 }
101
102 return neighbors;
103}
104double Dijkstra::getDistanceBetweenCells(const H3Index cell1, const H3Index cell2) {
105 LatLng coord1, coord2;
106
107 // Получаем координаты центров ячеек
108 const H3Error err1 = cellToLatLng(cell1, &coord1);
109 const H3Error err2 = cellToLatLng(cell2, &coord2);
110
111 if (err1 != E_SUCCESS || err2 != E_SUCCESS) {
112 return 1.0; // Возвращаем единичное расстояние по умолчанию
113 }
114
115 // Вычисляем расстояние по формуле гаверсинуса
116 return greatCircleDistanceM(&coord1, &coord2);
117}
118std::vector<H3Index> Dijkstra::reconstructPath(const std::unordered_map<H3Index, H3Index, H3IndexHash> &previous,
119 H3Index start, const H3Index end) {
120 std::vector<H3Index> path;
121 H3Index current = end;
122
123 while (current != start) {
124 path.emplace_back(current);
125 auto it = previous.find(current);
126 if (it == previous.end()) {
127 return {}; // Путь не найден
128 }
129 current = it->second;
130 }
131
132 path.emplace_back(start);
133 std::ranges::reverse(path);
134
135 return path;
136}
std::vector< H3Index > findShortestPath(H3Index start, H3Index end)
Definition dijkstra.cpp:5
static double getDistanceBetweenCells(H3Index cell1, H3Index cell2)
Definition dijkstra.cpp:104
static std::vector< H3Index > reconstructPath(const std::unordered_map< H3Index, H3Index, H3IndexHash > &previous, H3Index start, H3Index end)
Definition dijkstra.cpp:118
static std::vector< H3Index > getNeighbors(H3Index cell)
Definition dijkstra.cpp:79