Marble

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

KDE's Doxygen guidelines are available online.