KOSMIndoorMap

routingcontroller.cpp
1/*
2 SPDX-FileCopyrightText: 2024 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "routingcontroller.h"
7
8#include "navmeshbuilder.h"
9#include "routingjob.h"
10#include "routeoverlay.h"
11
12#include <QDebug>
13
14using namespace KOSMIndoorRouting;
15
16RoutingController::RoutingController(QObject *parent)
17 : QObject(parent)
18 , m_routeOverlay(new RouteOverlay(this))
19{
20}
21
22RoutingController::~RoutingController() = default;
23
25{
26#if HAVE_RECAST
27 return true;
28#else
29 return false;
30#endif
31}
32
34{
35 return m_builder || m_routingJob;
36}
37
38void RoutingController::setMapData(const KOSMIndoorMap::MapData &mapData)
39{
40 if (m_mapData == mapData) {
41 return;
42 }
43 m_mapData = mapData;
44 m_navMesh.clear();
45 m_routeOverlay->setMapData(mapData);
46 m_start = {};
47 m_end = {};
48
49 // TODO cancel ongoing jobs
50 m_builder = nullptr;
51 m_routingJob = nullptr;
52
53 Q_EMIT mapDataChanged();
54}
55
56// TODO nav mesh rebuild when elevator model changes
57
58void RoutingController::setStartPosition(double lat, double lon, int floorLevel)
59{
60 qDebug() << lat << lon <<floorLevel;
61 m_start = OSM::Coordinate{lat, lon};
62 m_startLevel = floorLevel;
63 m_routeOverlay->setStart(m_start, m_startLevel);
64}
65
66void RoutingController::setEndPosition(double lat, double lon, int floorLevel)
67{
68 qDebug() << lat << lon <<floorLevel;
69 m_end = OSM::Coordinate{lat, lon};
70 m_endLevel = floorLevel;
71 m_routeOverlay->setEnd(m_end, m_endLevel);
72}
73
74KOSMIndoorMap::AbstractOverlaySource* RoutingController::routeOverlay() const
75{
76 return m_routeOverlay;
77}
78
79void RoutingController::setProfile(const RoutingProfile &profile)
80{
81 qDebug() << profile.flags();
82 if (profile == m_routingProfile) {
83 return;
84 }
85 m_routingProfile = profile;
86 Q_EMIT profileChanged();
87}
88
89void RoutingController::searchRoute()
90{
91 qDebug();
92 if (m_builder) { // already running
93 return;
94 }
95
96 if (!m_start.isValid() && !m_end.isValid()) {
97 return;
98 }
99
100 if (!m_navMesh.isValid()) {
101 buildNavMesh();
102 Q_EMIT progressChanged();
103 return;
104 }
105
106 auto router = new RoutingJob(this);
107 router->setNavMesh(m_navMesh);
108 router->setStart(m_navMesh.transform().mapGeoHeightToNav(m_start, m_startLevel));
109 router->setEnd(m_navMesh.transform().mapGeoHeightToNav(m_end, m_endLevel));
110 router->setRoutingProfile(m_routingProfile);
111 connect(router, &RoutingJob::finished, this, [this, router]() {
112 router->deleteLater();
113 if (m_routingJob == router) {
114 m_routeOverlay->setRoute(router->route());
115 m_routingJob = nullptr;
116
117 // navmesh became invalid during routing...
118 if (!m_navMesh.isValid()) {
119 QMetaObject::invokeMethod(this, &RoutingController::searchRoute);
120 }
121 }
122 Q_EMIT progressChanged();
123 });
124 m_routingJob = router;
125 router->start();
126 Q_EMIT progressChanged();
127}
128
129void RoutingController::buildNavMesh()
130{
131 auto builder = new NavMeshBuilder(this);
132 builder->setMapData(m_mapData);
133 builder->setEquipmentModel(m_elevatorModel);
134 connect(builder, &NavMeshBuilder::finished, this, [this, builder]() {
135 builder->deleteLater();
136 if (m_builder == builder) {
137 m_navMesh = builder->navMesh();
138 m_builder = nullptr;
139 }
140
141 // TODO loop protection/error handling
142 if (m_navMesh.isValid()) {
143 searchRoute();
144 } else {
145 qWarning() << "Failed to generate nav mesh, routing not available!";
146 }
147
148 Q_EMIT progressChanged();
149 });
150 builder->start();
151 m_builder = builder;
152}
153
154#include "moc_routingcontroller.cpp"
A source for overlay elements, drawn on top of the static map data.
Raw OSM map data, separated by levels.
Definition mapdata.h:60
Job for building a navigation mesh for the given building.
bool isValid() const
Returns true if the nav mesh is neither null (ie.
Definition navmesh.cpp:43
bool routingInProgress() const
Indicates an ongoing routing or navmesh compilation process.
bool routingAvailable() const
Indicates that routing support is built-in at all.
Job for running a routing query on a compiled NavMesh instance.
Definition routingjob.h:25
Coordinate, stored as 1e7 * degree to avoid floating point precision issues, and offset to unsigned v...
Definition datatypes.h:37
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:57:47 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.