Marble

Tracking.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2011 Dennis Nienhüser <nienhueser@kde.org>
4//
5
6#include "Tracking.h"
7
8#include "AutoNavigation.h"
9#include "MarbleModel.h"
10#include "MarbleQuickItem.h"
11#include "PositionTracking.h"
12#include "RenderPlugin.h"
13#include "ViewportParams.h"
14
15namespace Marble
16{
17
18Tracking::Tracking(QObject *parent)
19 : QObject(parent)
20 , m_showTrack(true)
21 , m_hasLastKnownPosition(false)
22 , m_positionMarkerType(None)
23{
24 connect(&m_lastKnownPosition, &Coordinate::longitudeChanged, this, &Tracking::setHasLastKnownPosition);
25 connect(&m_lastKnownPosition, &Coordinate::latitudeChanged, this, &Tracking::setHasLastKnownPosition);
26}
27
28bool Tracking::showTrack() const
29{
30 return m_showTrack;
31}
32
33void Tracking::setShowTrack(bool show)
34{
35 if (show != m_showTrack) {
36 if (m_marbleQuickItem) {
37 m_marbleQuickItem->model()->positionTracking()->setTrackVisible(show);
38 m_marbleQuickItem->update();
39 }
40
41 m_showTrack = show;
42 Q_EMIT showTrackChanged();
43 }
44}
45
46PositionSource *Tracking::positionSource()
47{
48 return m_positionSource;
49}
50
51void Tracking::setPositionSource(PositionSource *source)
52{
53 if (source != m_positionSource) {
54 m_positionSource = source;
55 if (source) {
56 connect(source, SIGNAL(positionChanged()), this, SLOT(updatePositionMarker()));
57 connect(source, SIGNAL(positionChanged()), this, SLOT(updateLastKnownPosition()));
58 connect(source, SIGNAL(hasPositionChanged()), this, SLOT(updatePositionMarker()));
59 connect(source, SIGNAL(positionChanged()), this, SIGNAL(distanceChanged()));
60 }
61 Q_EMIT positionSourceChanged();
62 }
63}
64
65MarbleQuickItem *Tracking::map()
66{
67 return m_marbleQuickItem;
68}
69
70void Tracking::setMap(MarbleQuickItem *item)
71{
72 if (item != m_marbleQuickItem) {
73 m_marbleQuickItem = item;
74
75 if (m_marbleQuickItem) {
76 m_marbleQuickItem->model()->positionTracking()->setTrackVisible(showTrack());
77 setShowPositionMarkerPlugin(m_positionMarkerType == Arrow);
78
79 connect(m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), this, SLOT(updatePositionMarker()));
80 connect(m_marbleQuickItem, SIGNAL(mapThemeChanged()), this, SLOT(updatePositionMarker()));
81 }
82
83 Q_EMIT mapChanged();
84 }
85}
86
87void Tracking::setPositionMarker(QObject *marker)
88{
89 if (marker != m_positionMarker) {
90 m_positionMarker = marker;
91 Q_EMIT positionMarkerChanged();
92 }
93}
94
95QObject *Tracking::positionMarker()
96{
97 return m_positionMarker;
98}
99
100void Tracking::updatePositionMarker()
101{
102 if (m_marbleQuickItem && m_positionMarker && m_positionMarkerType == Circle) {
103 Coordinate *position = nullptr;
104 bool visible = (m_marbleQuickItem->model()->planetId() == QLatin1StringView("earth"));
105 if (m_positionSource && m_positionSource->hasPosition()) {
106 position = m_positionSource->position();
107 } else if (hasLastKnownPosition()) {
108 position = lastKnownPosition();
109 } else {
110 visible = false;
111 }
112
113 qreal x(0), y(0);
114 if (position) {
115 Marble::GeoDataCoordinates const pos(position->longitude(), position->latitude(), 0.0, GeoDataCoordinates::Degree);
116 visible = visible && m_marbleQuickItem->map()->viewport()->screenCoordinates(pos.longitude(), pos.latitude(), x, y);
117 QQuickItem *item = qobject_cast<QQuickItem *>(m_positionMarker);
118 if (item) {
119 item->setVisible(visible);
120 if (visible) {
121 item->setX(x - item->width() / 2.0);
122 item->setY(y - item->height() / 2.0);
123 }
124 }
125 }
126 } else if (m_positionMarkerType != Circle) {
127 QQuickItem *item = qobject_cast<QQuickItem *>(m_positionMarker);
128 if (item) {
129 item->setVisible(false);
130 }
131 }
132}
133
134void Tracking::updateLastKnownPosition()
135{
136 if (m_positionSource && m_positionSource->hasPosition()) {
137 setLastKnownPosition(m_positionSource->position());
138 }
139}
140
141void Tracking::setHasLastKnownPosition()
142{
143 if (!m_hasLastKnownPosition) {
144 m_hasLastKnownPosition = true;
145 Q_EMIT hasLastKnownPositionChanged();
146 }
147}
148
149void Tracking::setShowPositionMarkerPlugin(bool visible)
150{
151 if (m_marbleQuickItem) {
152 QList<RenderPlugin *> const renderPlugins = m_marbleQuickItem->map()->renderPlugins();
153 for (RenderPlugin *renderPlugin : renderPlugins) {
154 Q_ASSERT(renderPlugin);
155 if (renderPlugin->nameId() == QLatin1StringView("positionMarker")) {
156 renderPlugin->setEnabled(true);
157 renderPlugin->setVisible(visible);
158 }
159 }
160 }
161}
162
163bool Tracking::hasLastKnownPosition() const
164{
165 return m_hasLastKnownPosition;
166}
167
168Coordinate *Tracking::lastKnownPosition()
169{
170 return &m_lastKnownPosition;
171}
172
173void Tracking::setLastKnownPosition(Coordinate *lastKnownPosition)
174{
175 if (lastKnownPosition && *lastKnownPosition != m_lastKnownPosition) {
176 m_lastKnownPosition.setCoordinates(lastKnownPosition->coordinates());
177 Q_EMIT lastKnownPositionChanged();
178 }
179}
180
181bool Tracking::autoCenter() const
182{
183 if (m_autoNavigation) {
184 return m_autoNavigation->recenterMode() != Marble::AutoNavigation::DontRecenter;
185 }
186
187 return false;
188}
189
190void Tracking::setAutoCenter(bool enabled)
191{
192 if (autoCenter() != enabled) {
193 if (enabled && !m_autoNavigation && m_marbleQuickItem) {
194 m_autoNavigation = new Marble::AutoNavigation(m_marbleQuickItem->model(), m_marbleQuickItem->map()->viewport(), this);
195 connect(m_autoNavigation, SIGNAL(zoomIn(FlyToMode)), m_marbleQuickItem, SLOT(zoomIn()));
196 connect(m_autoNavigation, SIGNAL(zoomOut(FlyToMode)), m_marbleQuickItem, SLOT(zoomOut()));
197 connect(m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates, bool)), m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)));
198
199 connect(m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), m_autoNavigation, SLOT(inhibitAutoAdjustments()));
200 }
201
202 if (m_autoNavigation) {
203 m_autoNavigation->setRecenter(Marble::AutoNavigation::RecenterOnBorder);
204 }
205
206 Q_EMIT autoCenterChanged();
207 }
208}
209
210bool Tracking::autoZoom() const
211{
212 if (m_autoNavigation) {
213 return m_autoNavigation->autoZoom();
214 }
215
216 return false;
217}
218
219void Tracking::setAutoZoom(bool enabled)
220{
221 if (autoZoom() != enabled) {
222 if (enabled && !m_autoNavigation && m_marbleQuickItem) {
223 m_autoNavigation = new Marble::AutoNavigation(m_marbleQuickItem->model(), m_marbleQuickItem->map()->viewport(), this);
224 connect(m_autoNavigation, SIGNAL(zoomIn(FlyToMode)), m_marbleQuickItem, SLOT(zoomIn()));
225 connect(m_autoNavigation, SIGNAL(zoomOut(FlyToMode)), m_marbleQuickItem, SLOT(zoomOut()));
226 connect(m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates, bool)), m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)));
227
228 connect(m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), m_autoNavigation, SLOT(inhibitAutoAdjustments()));
229 }
230
231 if (m_autoNavigation) {
232 m_autoNavigation->setAutoZoom(enabled);
233 }
234
235 Q_EMIT autoZoomChanged();
236 }
237}
238
239Tracking::PositionMarkerType Tracking::positionMarkerType() const
240{
241 return m_positionMarkerType;
242}
243
244void Tracking::setPositionMarkerType(Tracking::PositionMarkerType type)
245{
246 setShowPositionMarkerPlugin(type == Arrow);
247 if (type != m_positionMarkerType) {
248 m_positionMarkerType = type;
249 Q_EMIT positionMarkerTypeChanged();
250 }
251}
252
253double Tracking::distance() const
254{
255 return m_marbleQuickItem ? m_marbleQuickItem->model()->positionTracking()->length(m_marbleQuickItem->model()->planetRadius()) : 0.0;
256}
257
258void Tracking::saveTrack(const QString &fileName)
259{
260 if (m_marbleQuickItem) {
261 /** @todo FIXME: replace the file:// prefix on QML side */
262 QString target = fileName.startsWith(QLatin1StringView("file://")) ? fileName.mid(7) : fileName;
263 m_marbleQuickItem->model()->positionTracking()->saveTrack(target);
264 }
265}
266
267void Tracking::openTrack(const QString &fileName)
268{
269 if (m_marbleQuickItem) {
270 /** @todo FIXME: replace the file:// prefix on QML side */
271 QString target = fileName.startsWith(QLatin1StringView("file://")) ? fileName.mid(7) : fileName;
272 m_marbleQuickItem->model()->addGeoDataFile(target);
273 }
274}
275
276void Tracking::clearTrack()
277{
278 if (m_marbleQuickItem) {
279 m_marbleQuickItem->model()->positionTracking()->clearTrack();
280 }
281}
282
283}
284
285#include "moc_Tracking.cpp"
This file contains the headers for MarbleModel.
This file contains the headers for ViewportParams.
Represents a coordinate with the properties of a name and coordinates.
Definition Coordinate.h:19
Marble::GeoDataCoordinates coordinates() const
Change the altitude of the coordinate.
A 3d point representation.
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QAction * zoomIn(const QObject *recvr, const char *slot, QObject *parent)
QAction * zoomOut(const QObject *recvr, const char *slot, QObject *parent)
Binds a QML item to a specific geodetic location in screen coordinates.
void setVisible(bool)
void setX(qreal)
void setY(qreal)
QString mid(qsizetype position, qsizetype n) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 8 2024 12:02:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.