• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
AutoNavigation.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2010 Siddharth Srivastava <akssps011@gmail.com>
9 // Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
10 //
11 
12 
13 #include "AutoNavigation.h"
14 
15 #include "GeoDataCoordinates.h"
16 #include "PositionTracking.h"
17 #include "MarbleDebug.h"
18 #include "MarbleModel.h"
19 #include "MarbleMath.h"
20 #include "ViewportParams.h"
21 #include "MarbleGlobal.h"
22 
23 #include <QPixmap>
24 #include <QWidget>
25 #include <QRect>
26 #include <QPointF>
27 #include <QTimer>
28 #include <math.h>
29 
30 namespace Marble {
31 
32 class AutoNavigation::Private
33 {
34 public:
35 
36  AutoNavigation *const m_parent;
37  const MarbleModel *const m_model;
38  const ViewportParams *const m_viewport;
39  const PositionTracking *const m_tracking;
40  AutoNavigation::CenterMode m_recenterMode;
41  bool m_adjustZoom;
42  QTimer m_lastWidgetInteraction;
43  bool m_selfInteraction;
44 
46  Private( MarbleModel *model, const ViewportParams *viewport, AutoNavigation *parent );
47 
53  void moveOnBorderToCenter( const GeoDataCoordinates &position, qreal speed );
54 
60  GeoDataCoordinates findIntersection( qreal currentX, qreal currentY ) const;
61 
66  void adjustZoom( const GeoDataCoordinates &currentPosition, qreal speed );
67 
71  void centerOn( const GeoDataCoordinates &position );
72 };
73 
74 AutoNavigation::Private::Private( MarbleModel *model, const ViewportParams *viewport, AutoNavigation *parent ) :
75  m_parent( parent ),
76  m_model( model ),
77  m_viewport( viewport ),
78  m_tracking( model->positionTracking() ),
79  m_recenterMode( AutoNavigation::DontRecenter ),
80  m_adjustZoom( 0 ),
81  m_selfInteraction( false )
82 {
83  m_lastWidgetInteraction.setInterval( 10 * 1000 );
84  m_lastWidgetInteraction.setSingleShot( true );
85 }
86 
87 void AutoNavigation::Private::moveOnBorderToCenter( const GeoDataCoordinates &position, qreal )
88 {
89  qreal lon = 0.0;
90  qreal lat = 0.0;
91 
92  position.geoCoordinates( lon, lat, GeoDataCoordinates::Degree );
93 
94  qreal x = 0.0;
95  qreal y = 0.0;
96  //recenter if initially the gps location is not visible on the screen
97  if(!( m_viewport->screenCoordinates( lon, lat, x, y ) ) ) {
98  centerOn( position );
99  }
100  qreal centerLon = m_viewport->centerLongitude();
101  qreal centerLat = m_viewport->centerLatitude();
102 
103  qreal centerX = 0.0;
104  qreal centerY = 0.0;
105 
106  m_viewport->screenCoordinates( centerLon, centerLat, centerX, centerY );
107 
108  const qreal borderRatio = 0.25;
109  //defining the default border distance from map center
110  int shiftX = qRound( centerX * borderRatio );
111  int shiftY = qRound( centerY * borderRatio );
112 
113  QRect recenterBorderBound;
114  recenterBorderBound.setCoords( centerX-shiftX, centerY-shiftY, centerX+shiftX, centerY+shiftY );
115 
116  if( !recenterBorderBound.contains( x,y ) ) {
117  centerOn( position );
118  }
119 }
120 
121 GeoDataCoordinates AutoNavigation::Private::findIntersection( qreal currentX, qreal currentY ) const
122 {
123  qreal direction = m_tracking->direction();
124  if ( direction >= 360 ) {
125  direction = fmod( direction,360.0 );
126  }
127 
128  const qreal width = m_viewport->width();
129  const qreal height = m_viewport->height();
130 
131  QPointF intercept;
132  QPointF destinationHorizontal;
133  QPointF destinationVertical;
134  QPointF destination;
135 
136  bool crossHorizontal = false;
137  bool crossVertical = false;
138 
139  //calculation of intersection point
140  if( 0 < direction && direction < 90 ) {
141  const qreal angle = direction;
142 
143  //Intersection with line x = width
144  intercept.setX( width - currentX );
145  intercept.setY( intercept.x() / tan( angle ) );
146  destinationVertical.setX( width );
147  destinationVertical.setY( currentY-intercept.y() );
148 
149  //Intersection with line y = 0
150  intercept.setY( currentY );
151  intercept.setX( intercept.y() * tan( angle ) );
152  destinationHorizontal.setX( currentX + intercept.x() );
153  destinationHorizontal.setY( 0 );
154 
155  if ( destinationVertical.y() < 0 ) {
156  crossHorizontal = true;
157  }
158  else if( destinationHorizontal.x() > width ) {
159  crossVertical = true;
160  }
161 
162  }
163  else if( 270 < direction && direction < 360 ) {
164  const qreal angle = direction - 270;
165 
166  //Intersection with line y = 0
167  intercept.setY( currentY );
168  intercept.setX( intercept.y() / tan( angle ) );
169  destinationHorizontal.setX( currentX - intercept.x() );
170  destinationHorizontal.setY( 0 );
171 
172  //Intersection with line x = 0
173  intercept.setX( currentX );
174  intercept.setY( intercept.x() * tan( angle ) );
175  destinationVertical.setY( currentY - intercept.y() );
176  destinationVertical.setX( 0 );
177 
178  if( destinationHorizontal.x() > width ) {
179  crossVertical = true;
180  }
181  else if( destinationVertical.y() < 0 ) {
182  crossHorizontal = true;
183  }
184 
185  }
186  else if( 180 < direction && direction < 270 ) {
187  const qreal angle = direction - 180;
188 
189  //Intersection with line x = 0
190  intercept.setX( currentX );
191  intercept.setY( intercept.x() / tan( angle ) );
192  destinationVertical.setY( currentY + intercept.y() );
193  destinationVertical.setX( 0 );
194 
195  //Intersection with line y = height
196  intercept.setY( currentY );
197  intercept.setX( intercept.y() * tan( angle ) );
198  destinationHorizontal.setX( currentX - intercept.x() );
199  destinationHorizontal.setY( height );
200 
201  if ( destinationVertical.y() > height ) {
202  crossHorizontal = true;
203  }
204  else if ( destinationHorizontal.x() < 0 ) {
205  crossVertical = true;
206  }
207 
208  }
209  else if( 90 < direction && direction < 180 ) {
210  const qreal angle = direction - 90;
211 
212  //Intersection with line y = height
213  intercept.setY( height - currentY );
214  intercept.setX( intercept.y() / tan( angle ) );
215  destinationHorizontal.setX( currentX + intercept.x() );
216  destinationHorizontal.setY( height );
217 
218  //Intersection with line x = width
219  intercept.setX( width - currentX );
220  intercept.setY( intercept.x() * tan( angle ) );
221  destinationVertical.setX( width );
222  destinationVertical.setY( currentY + intercept.y() );
223 
224  if ( destinationHorizontal.x() > width ) {
225  crossVertical = true;
226  }
227  else if( destinationVertical.y() > height ) {
228  crossHorizontal = true;
229  }
230 
231  }
232  else if( direction == 0 ) {
233  destinationHorizontal.setX( currentX );
234  destinationHorizontal.setY( 0 );
235  crossHorizontal = true;
236  }
237  else if( direction == 90 ) {
238  destinationVertical.setX( width );
239  destinationVertical.setY( currentY );
240  crossVertical = true;
241  }
242  else if( direction == 190 ) {
243  destinationHorizontal.setX( currentX );
244  destinationHorizontal.setY( height );
245  crossHorizontal = true;
246  }
247  else if( direction == 270 ) {
248  destinationVertical.setX( 0 );
249  destinationVertical.setY( currentY );
250  crossVertical = true;
251  }
252 
253  if ( crossHorizontal == true && crossVertical == false ) {
254  destination.setX( destinationHorizontal.x() );
255  destination.setY( destinationHorizontal.y() );
256  }
257  else if ( crossVertical == true && crossHorizontal == false ) {
258  destination.setX( destinationVertical.x() );
259  destination.setY( destinationVertical.y() );
260  }
261 
262  qreal destinationLon = 0.0;
263  qreal destinationLat = 0.0;
264  m_viewport->geoCoordinates( destination.x(), destination.y(), destinationLon, destinationLat,
265  GeoDataCoordinates::Radian );
266  GeoDataCoordinates destinationCoord( destinationLon, destinationLat, GeoDataCoordinates::Radian );
267 
268  return destinationCoord;
269 }
270 
271 void AutoNavigation::Private::adjustZoom( const GeoDataCoordinates &currentPosition, qreal speed )
272 {
273  const qreal lon = currentPosition.longitude( GeoDataCoordinates::Degree );
274  const qreal lat = currentPosition.latitude( GeoDataCoordinates::Degree );
275 
276  qreal currentX = 0;
277  qreal currentY = 0;
278 
279  if( !m_viewport->screenCoordinates( lon, lat, currentX, currentY ) ) {
280  return;
281  }
282 
283  const GeoDataCoordinates destination = findIntersection( currentX, currentY );
284 
285  qreal greatCircleDistance = distanceSphere( currentPosition, destination );
286  qreal radius = m_model->planetRadius();
287  qreal distance = greatCircleDistance * radius;
288 
289  if( speed != 0 ) {
290  //time(in minutes) remaining to reach the border of the map
291  qreal remainingTime = ( distance / speed ) * SEC2MIN;
292 
293  //tolerance time limits( in minutes ) before auto zooming
294  qreal thresholdLow = 1.0;
295  qreal thresholdHigh = 12.0 * thresholdLow;
296 
297  m_selfInteraction = true;
298  if ( remainingTime < thresholdLow ) {
299  emit m_parent->zoomOut( Instant );
300  }
301  else if ( remainingTime < thresholdHigh ) {
302  /* zoom level optimal, nothing to do */
303  }
304  else {
305  emit m_parent->zoomIn( Instant );
306  }
307  m_selfInteraction = false;
308  }
309 }
310 
311 void AutoNavigation::Private::centerOn( const GeoDataCoordinates &position )
312 {
313  m_selfInteraction = true;
314  emit m_parent->centerOn( position, false );
315  m_selfInteraction = false;
316 }
317 
318 AutoNavigation::AutoNavigation( MarbleModel *model, const ViewportParams *viewport, QObject *parent ) :
319  QObject( parent ),
320  d( new AutoNavigation::Private( model, viewport, this ) )
321 {
322  connect( d->m_tracking, SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
323  this, SLOT(adjust(GeoDataCoordinates,qreal)) );
324 }
325 
326 AutoNavigation::~AutoNavigation()
327 {
328  delete d;
329 }
330 
331 void AutoNavigation::adjust( const GeoDataCoordinates &position, qreal speed )
332 {
333  if ( d->m_lastWidgetInteraction.isActive() ) {
334  return;
335  }
336 
337  switch( d->m_recenterMode ) {
338  case DontRecenter:
339  /* nothing to do */
340  break;
341  case AlwaysRecenter:
342  d->centerOn( position );
343  break;
344  case RecenterOnBorder:
345  d->moveOnBorderToCenter( position, speed );
346  break;
347  }
348 
349  if ( d->m_adjustZoom ) {
350  switch( d->m_recenterMode ) {
351  case DontRecenter:
352  /* nothing to do */
353  break;
354  case AlwaysRecenter:
355  case RecenterOnBorder: // fallthrough
356  d->adjustZoom( position, speed );
357  break;
358  }
359  }
360 }
361 
362 void AutoNavigation::setAutoZoom( bool autoZoom )
363 {
364  d->m_adjustZoom = autoZoom;
365  emit autoZoomToggled( autoZoom );
366 }
367 
368 void AutoNavigation::setRecenter( CenterMode recenterMode )
369 {
370  d->m_recenterMode = recenterMode;
371  emit recenterModeChanged( recenterMode );
372 }
373 
374 void AutoNavigation::inhibitAutoAdjustments()
375 {
376  if ( !d->m_selfInteraction ) {
377  d->m_lastWidgetInteraction.start();
378  }
379 }
380 
381 AutoNavigation::CenterMode AutoNavigation::recenterMode() const
382 {
383  return d->m_recenterMode;
384 }
385 
386 bool AutoNavigation::autoZoom() const
387 {
388  return d->m_adjustZoom;
389 }
390 
391 } // namespace Marble
392 
393 #include "AutoNavigation.moc"
GeoDataCoordinates.h
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::AutoNavigation::AlwaysRecenter
Enum Value AlwaysRecenter.
Definition: AutoNavigation.h:49
Marble::AutoNavigation::autoZoom
bool autoZoom() const
Definition: AutoNavigation.cpp:386
Marble::GeoDataCoordinates::Radian
Definition: GeoDataCoordinates.h:65
Marble::SEC2MIN
const qreal SEC2MIN
Definition: MarbleGlobal.h:232
angle
double angle(double vec1[3], double vec2[3])
Definition: sgp4ext.cpp:164
MarbleMath.h
Marble::AutoNavigation::inhibitAutoAdjustments
void inhibitAutoAdjustments()
Temporarily inhibits auto-centering and auto-zooming.
Definition: AutoNavigation.cpp:374
MarbleModel.h
This file contains the headers for MarbleModel.
Marble::AutoNavigation::DontRecenter
Definition: AutoNavigation.h:48
Marble::AutoNavigation::RecenterOnBorder
Enum Value RecenterOnBorder.
Definition: AutoNavigation.h:50
Marble::distanceSphere
qreal distanceSphere(qreal lon1, qreal lat1, qreal lon2, qreal lat2)
This method calculates the shortest distance between two points on a sphere.
Definition: MarbleMath.h:52
Marble::AutoNavigation
Definition: AutoNavigation.h:27
MarbleDebug.h
Marble::AutoNavigation::autoZoomToggled
void autoZoomToggled(bool enabled)
signal emitted when auto zoom is toggled
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
QPointF
QRect
QPointF::x
qreal x() const
QPointF::y
qreal y() const
QTimer
AutoNavigation.h
Marble::AutoNavigation::recenterModeChanged
void recenterModeChanged(AutoNavigation::CenterMode mode)
signal emitted when auto center is turned on (Always re-center, re-center when required ) or off(Disa...
QObject
Marble::AutoNavigation::setRecenter
void setRecenter(CenterMode recenterMode)
For Auto Centering adjustment of map in Navigation Mode.
Definition: AutoNavigation.cpp:368
QRect::setCoords
void setCoords(int x1, int y1, int x2, int y2)
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
Marble::AutoNavigation::adjust
void adjust(const GeoDataCoordinates &position, qreal speed)
For adjusting the gps location (recentering) or map(autozooming)
Definition: AutoNavigation.cpp:331
Marble::AutoNavigation::setAutoZoom
void setAutoZoom(bool activate)
For Auto Zooming adjustment of map in Navigation Mode.
Definition: AutoNavigation.cpp:362
QRect::contains
bool contains(const QPoint &point, bool proper) const
MarbleGlobal.h
Marble::AutoNavigation::~AutoNavigation
~AutoNavigation()
Destructor.
Definition: AutoNavigation.cpp:326
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
ViewportParams.h
This file contains the headers for ViewportParams.
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:97
direction
qreal direction
Definition: tools/osm-addresses/OsmParser.cpp:40
QPointF::setX
void setX(qreal x)
QPointF::setY
void setY(qreal y)
Marble::AutoNavigation::AutoNavigation
AutoNavigation(MarbleModel *model, const ViewportParams *viewport, QObject *parent=0)
Constructor.
Definition: AutoNavigation.cpp:318
Marble::Instant
Change camera position immediately (no interpolation)
Definition: MarbleGlobal.h:175
PositionTracking.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
Marble::AutoNavigation::CenterMode
CenterMode
An enum type Represents which recentering method is selected.
Definition: AutoNavigation.h:47
Marble::AutoNavigation::centerOn
void centerOn(const GeoDataCoordinates &position, bool animated)
Marble::AutoNavigation::recenterMode
AutoNavigation::CenterMode recenterMode() const
Definition: AutoNavigation.cpp:381
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:38 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal