• 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
  • routing
RoutingLayer.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 Dennis Nienhüser <earthwings@gentoo.org>
9 //
10 
11 #include "RoutingLayer.h"
12 
13 #include "GeoDataCoordinates.h"
14 #include "GeoDataLineString.h"
15 #include "GeoPainter.h"
16 #include "GeoSceneDocument.h"
17 #include "GeoSceneHead.h"
18 #include "MarblePlacemarkModel.h"
19 #include "MarbleWidget.h"
20 #include "MarbleWidgetPopupMenu.h"
21 #include "RoutingModel.h"
22 #include "RouteRequest.h"
23 #include "MarbleModel.h"
24 #include "AlternativeRoutesModel.h"
25 #include "RoutingManager.h"
26 #include "Maneuver.h"
27 
28 #include <QMap>
29 #include <QAbstractItemModel>
30 #include <QIcon>
31 #include <QItemSelectionModel>
32 #include <QKeyEvent>
33 #include <QMenu>
34 #include <QMouseEvent>
35 #include <QPixmap>
36 #include <QFileDialog>
37 
38 namespace Marble
39 {
40 
41 class RoutingLayerPrivate
42 {
43  template<class T>
44  struct PaintRegion {
45  T index;
46  QRegion region;
47 
48  PaintRegion( const T &index_, const QRegion &region_ ) :
49  index( index_ ), region( region_ )
50  {
51  // nothing to do
52  }
53  };
54 
55  typedef PaintRegion<QModelIndex> ModelRegion;
56  typedef PaintRegion<int> RequestRegion;
57 
58 public:
59  RoutingLayer *const q;
60 
61  QList<ModelRegion> m_instructionRegions;
62 
63  QList<RequestRegion> m_regions;
64 
65  QList<RequestRegion> m_alternativeRouteRegions;
66 
67  QList<ModelRegion> m_placemarks;
68 
69  QRegion m_routeRegion;
70 
71  int m_movingIndex;
72 
73  MarbleWidget *const m_marbleWidget;
74 
75  QPixmap m_targetPixmap;
76 
77  QRect m_dirtyRect;
78 
79  QPoint m_dropStopOver;
80 
81  QPoint m_dragStopOver;
82 
83  int m_dragStopOverRightIndex;
84 
85  RoutingModel *const m_routingModel;
86 
87  MarblePlacemarkModel *m_placemarkModel;
88 
89  QItemSelectionModel *m_selectionModel;
90 
91  bool m_routeDirty;
92 
93  QSize m_pixmapSize;
94 
95  RouteRequest *const m_routeRequest;
96 
97  MarbleWidgetPopupMenu *m_contextMenu;
98 
99  QAction *m_removeViaPointAction;
100 
101  int m_activeMenuIndex;
102 
103  AlternativeRoutesModel *const m_alternativeRoutesModel;
104 
105  ViewContext m_viewContext;
106 
107  bool m_viewportChanged;
108 
109  bool m_isInteractive;
110 
112  explicit RoutingLayerPrivate( RoutingLayer *parent, MarbleWidget *widget );
113 
115  void storeDragPosition( const QPoint &position );
116 
117  // The following methods are mostly only called at one place in the code, but often
118  // Inlined to avoid the function call overhead. Having functions here is just to
119  // keep the code clean
120 
122  static inline QColor alphaAdjusted( const QColor &color, int alpha );
123 
128  inline int viaInsertPosition( Qt::KeyboardModifiers modifiers ) const;
129 
131  inline void renderPlacemarks( GeoPainter *painter );
132 
134  inline void renderRoute( GeoPainter *painter );
135 
137  inline void renderAnnotations( GeoPainter *painter ) const;
138 
140  inline void renderAlternativeRoutes( GeoPainter *painter );
141 
143  inline void renderRequest( GeoPainter *painter );
144 
146  void setRouteDirty( bool dirty );
147 
149  inline bool handleMouseButtonRelease( QMouseEvent *e );
150 
152  inline bool handleMouseButtonPress( QMouseEvent *e );
153 
155  inline bool handleMouseMove( QMouseEvent *e );
156 
158  inline bool isInfoPoint( const QPoint &point );
159 
161  inline bool isAlternativeRoutePoint( const QPoint &point );
162 
164  inline void paintStopOver( QRect position );
165 
167  inline void clearStopOver();
168 };
169 
170 RoutingLayerPrivate::RoutingLayerPrivate( RoutingLayer *parent, MarbleWidget *widget ) :
171  q( parent ), m_movingIndex( -1 ), m_marbleWidget( widget ),
172  m_targetPixmap( ":/data/bitmaps/routing_pick.png" ), m_dragStopOverRightIndex( -1 ),
173  m_routingModel( widget->model()->routingManager()->routingModel() ),
174  m_placemarkModel( 0 ), m_selectionModel( 0 ), m_routeDirty( false ), m_pixmapSize( 22, 22 ),
175  m_routeRequest( widget->model()->routingManager()->routeRequest() ),
176  m_activeMenuIndex( -1 ),
177  m_alternativeRoutesModel( widget->model()->routingManager()->alternativeRoutesModel() ),
178  m_viewContext( Still ),
179  m_viewportChanged( true ),
180  m_isInteractive( true )
181 {
182  m_contextMenu = new MarbleWidgetPopupMenu( m_marbleWidget, m_marbleWidget->model() );
183  m_removeViaPointAction = new QAction( QObject::tr( "&Remove this destination" ), q );
184  QObject::connect( m_removeViaPointAction, SIGNAL(triggered()), q, SLOT(removeViaPoint()) );
185  m_contextMenu->addAction( Qt::RightButton, m_removeViaPointAction );
186  QAction *exportAction = new QAction( QObject::tr( "&Export route..." ), q );
187  QObject::connect( exportAction, SIGNAL(triggered()), q, SLOT(exportRoute()) );
188  m_contextMenu->addAction( Qt::RightButton, exportAction );
189  if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
190  m_pixmapSize = QSize( 38, 38 );
191  }
192 
193 }
194 
195 int RoutingLayerPrivate::viaInsertPosition( Qt::KeyboardModifiers modifiers ) const
196 {
197  if ( modifiers & Qt::ControlModifier ) {
198  bool leftHand = m_routeRequest->size() / 2 >= m_dragStopOverRightIndex;
199  if ( leftHand && m_routeRequest->size() > 2 ) {
200  return 0;
201  } else {
202  return m_routeRequest->size();
203  }
204  } else {
205  return m_dragStopOverRightIndex;
206  }
207 }
208 
209 void RoutingLayerPrivate::renderPlacemarks( GeoPainter *painter )
210 {
211  m_placemarks.clear();
212  painter->setPen( QColor( Qt::black ) );
213  for ( int i = 0; i < m_placemarkModel->rowCount(); ++i ) {
214  QModelIndex index = m_placemarkModel->index( i, 0 );
215  QVariant data = index.data( MarblePlacemarkModel::CoordinateRole );
216  if ( index.isValid() && !data.isNull() ) {
217  GeoDataCoordinates pos = data.value<GeoDataCoordinates>();
218 
219  QPixmap pixmap = index.data( Qt::DecorationRole ).value<QPixmap>();
220  if ( !pixmap.isNull() && m_selectionModel->isSelected( index ) ) {
221  QIcon selected = QIcon( pixmap );
222  QPixmap result = selected.pixmap( m_pixmapSize, QIcon::Selected, QIcon::On );
223  painter->drawPixmap( pos, result );
224  } else {
225  painter->drawPixmap( pos, pixmap );
226  }
227 
228  QRegion region = painter->regionFromRect( pos, m_targetPixmap.width(), m_targetPixmap.height() );
229  m_placemarks.push_back( ModelRegion( index, region ) );
230  }
231  }
232 }
233 
234 void RoutingLayerPrivate::renderAlternativeRoutes( GeoPainter *painter )
235 {
236  QPen alternativeRoutePen( m_marbleWidget->model()->routingManager()->routeColorAlternative() );
237  alternativeRoutePen.setWidth( 5 );
238  painter->setPen( alternativeRoutePen );
239 
240  for ( int i=0; i<m_alternativeRoutesModel->rowCount(); ++i ) {
241  GeoDataDocument* route = m_alternativeRoutesModel->route( i );
242  if ( route && route != m_alternativeRoutesModel->currentRoute() ) {
243  const GeoDataLineString* points = AlternativeRoutesModel::waypoints( route );
244  if ( points ) {
245  painter->drawPolyline( *points );
246  if ( m_viewportChanged && m_isInteractive && m_viewContext == Still ) {
247  QRegion region = painter->regionFromPolyline( *points, 8 );
248  m_alternativeRouteRegions.push_back( RequestRegion( i, region ) );
249  }
250  }
251  }
252  }
253 }
254 
255 void RoutingLayerPrivate::renderRoute( GeoPainter *painter )
256 {
257  GeoDataLineString waypoints = m_routingModel->route().path();
258 
259  QPen standardRoutePen( m_marbleWidget->model()->routingManager()->routeColorStandard() );
260  standardRoutePen.setWidth( 5 );
261  if ( m_routeDirty ) {
262  standardRoutePen.setStyle( Qt::DotLine );
263  }
264  painter->setPen( standardRoutePen );
265 
266  painter->drawPolyline( waypoints );
267  if ( m_viewportChanged && m_viewContext == Still ) {
268  int const offset = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ? 24 : 8;
269  if ( m_isInteractive ) {
270  m_routeRegion = painter->regionFromPolyline( waypoints, offset );
271  }
272  }
273 
274 
275  standardRoutePen.setWidth( 2 );
276  painter->setPen( standardRoutePen );
277 
278  // Map matched position
279  //painter->setBrush( QBrush( Oxygen::brickRed4) );
280  //painter->drawEllipse( m_routingModel->route().positionOnRoute(), 8, 8 );
281 
282  painter->setBrush( QBrush( m_marbleWidget->model()->routingManager()->routeColorAlternative() ) );
283 
284  if ( !m_dropStopOver.isNull() ) {
285  int dx = 1 + m_pixmapSize.width() / 2;
286  int dy = 1 + m_pixmapSize.height() / 2;
287  QPoint center = m_dropStopOver - QPoint( dx, dy );
288  painter->drawPixmap( center, m_targetPixmap );
289 
290  if ( !m_dragStopOver.isNull() && m_dragStopOverRightIndex >= 0 && m_dragStopOverRightIndex <= m_routeRequest->size() ) {
291  QPoint moved = m_dropStopOver - m_dragStopOver;
292  if ( moved.manhattanLength() > 10 ) {
293  qreal lon( 0.0 ), lat( 0.0 );
294  if ( m_marbleWidget->geoCoordinates( m_dropStopOver.x(), m_dropStopOver.y(),
295  lon, lat, GeoDataCoordinates::Radian ) ) {
296  GeoDataCoordinates drag( lon, lat );
297  standardRoutePen.setStyle( Qt::DotLine );
298  painter->setPen( standardRoutePen );
299  GeoDataLineString lineString;
300  if ( m_dragStopOverRightIndex > 0 ) {
301  lineString << m_routeRequest->at( m_dragStopOverRightIndex-1 );
302  }
303  lineString << drag;
304  if ( m_dragStopOverRightIndex < m_routeRequest->size() ) {
305  lineString << m_routeRequest->at( m_dragStopOverRightIndex );
306  }
307  painter->drawPolyline( lineString );
308  standardRoutePen.setStyle( Qt::SolidLine );
309  painter->setPen( standardRoutePen );
310  }
311  }
312  }
313  }
314 
315  if ( m_viewContext == Animation ) {
316  return;
317  }
318 
319  m_instructionRegions.clear();
320  for ( int i = 0; i < m_routingModel->rowCount(); ++i ) {
321  QModelIndex index = m_routingModel->index( i, 0 );
322  GeoDataCoordinates pos = index.data( MarblePlacemarkModel::CoordinateRole ).value<GeoDataCoordinates>();
323 
324  painter->setBrush( QBrush( m_marbleWidget->model()->routingManager()->routeColorAlternative() ) );
325  if ( m_selectionModel && m_selectionModel->selection().contains( index ) ) {
326  for ( int j=0; j<m_routingModel->route().size(); ++j ) {
327  const RouteSegment & segment = m_routingModel->route().at( j );
328  if ( segment.maneuver().position() == pos ) {
329  GeoDataLineString currentRoutePoints = segment.path();
330 
331  QPen activeRouteSegmentPen( m_marbleWidget->model()->routingManager()->routeColorHighlighted() );
332 
333  activeRouteSegmentPen.setWidth( 6 );
334  if ( m_routeDirty ) {
335  activeRouteSegmentPen.setStyle( Qt::DotLine );
336  }
337  painter->setPen( activeRouteSegmentPen );
338  painter->drawPolyline( currentRoutePoints );
339 
340  painter->setPen( standardRoutePen );
341  painter->setBrush( QBrush( alphaAdjusted( Oxygen::hotOrange4, 200 ) ) );
342  }
343  }
344  }
345 
346  if ( m_isInteractive ) {
347  QRegion region = painter->regionFromEllipse( pos, 12, 12 );
348  m_instructionRegions.push_front( ModelRegion( index, region ) );
349  }
350  painter->drawEllipse( pos, 6, 6 );
351 
352  if( !m_routingModel->deviatedFromRoute() ) {
353  GeoDataCoordinates location = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().position();
354  QString nextInstruction = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().instructionText();
355  if( !nextInstruction.isEmpty() ) {
356  painter->setBrush( QBrush( Oxygen::hotOrange4 ) );
357  painter->drawEllipse( location, 6, 6 );
358  }
359  }
360  }
361 }
362 
363 void RoutingLayerPrivate::renderAnnotations( GeoPainter *painter ) const
364 {
365  if ( !m_selectionModel || m_selectionModel->selection().isEmpty() ) {
366  // nothing to do
367  return;
368  }
369 
370  for ( int i = 0; i < m_routingModel->rowCount(); ++i ) {
371  QModelIndex index = m_routingModel->index( i, 0 );
372 
373  if ( m_selectionModel->selection().contains( index ) ) {
374  bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
375  GeoDataCoordinates pos = index.data( MarblePlacemarkModel::CoordinateRole ).value<GeoDataCoordinates>();
376  painter->setPen( QColor( Qt::black ) );
377  painter->setBrush( QBrush( Oxygen::sunYellow6 ) );
378  painter->drawAnnotation( pos, index.data().toString(), QSize( smallScreen ? 240 : 120, 0 ), 10, 30, 5, 5 );
379  }
380  }
381 }
382 
383 void RoutingLayerPrivate::renderRequest( GeoPainter *painter )
384 {
385  m_regions.clear();
386  for ( int i = 0; i < m_routeRequest->size(); ++i ) {
387  GeoDataCoordinates pos = m_routeRequest->at( i );
388  if ( pos.longitude() != 0.0 && pos.latitude() != 0.0 ) {
389  QPixmap pixmap = m_routeRequest->pixmap( i );
390  painter->drawPixmap( pos, pixmap );
391  QRegion region = painter->regionFromRect( pos, pixmap.width(), pixmap.height() );
392  m_regions.push_front( RequestRegion( i, region ) );
393  }
394  }
395 }
396 
397 void RoutingLayerPrivate::storeDragPosition( const QPoint &pos )
398 {
399  m_dragStopOver = pos;
400  m_dragStopOverRightIndex = -1;
401 
402  qreal lon( 0.0 ), lat( 0.0 );
403  if ( m_routeRequest && !pos.isNull()
404  && m_marbleWidget->geoCoordinates( pos.x(), pos.y(), lon, lat, GeoDataCoordinates::Radian ) ) {
405  GeoDataCoordinates waypoint( lon, lat );
406  m_dragStopOverRightIndex = m_routingModel->rightNeighbor( waypoint, m_routeRequest );
407  }
408 }
409 
410 QColor RoutingLayerPrivate::alphaAdjusted( const QColor &color, int alpha )
411 {
412  QColor result( color );
413  result.setAlpha( alpha );
414  return result;
415 }
416 
417 bool RoutingLayerPrivate::handleMouseButtonPress( QMouseEvent *e )
418 {
419  foreach( const RequestRegion &region, m_regions ) {
420  if ( region.region.contains( e->pos() ) ) {
421  if ( e->button() == Qt::LeftButton ) {
422  m_movingIndex = region.index;
423  m_dropStopOver = QPoint();
424  m_dragStopOver = QPoint();
425  return true;
426  } else if ( e->button() == Qt::RightButton ) {
427  m_removeViaPointAction->setEnabled( true );
428  m_activeMenuIndex = region.index;
429  m_contextMenu->showRmbMenu( e->x(), e->y() );
430  return true;
431  } else
432  return false;
433  }
434  }
435 
436  foreach( const ModelRegion &region, m_instructionRegions ) {
437  if ( region.region.contains( e->pos() ) && m_selectionModel ) {
438  if ( e->button() == Qt::LeftButton ) {
439  QItemSelectionModel::SelectionFlag command = QItemSelectionModel::ClearAndSelect;
440  if ( m_selectionModel->isSelected( region.index ) ) {
441  command = QItemSelectionModel::Clear;
442  }
443  m_selectionModel->select( region.index, command );
444  m_dropStopOver = e->pos();
445  storeDragPosition( e->pos() );
446  // annotation and old annotation are dirty, large region
447  emit q->repaintNeeded();
448  return true;
449  } else if ( e->button() == Qt::RightButton ) {
450  m_removeViaPointAction->setEnabled( false );
451  m_contextMenu->showRmbMenu( e->x(), e->y() );
452  return true;
453  } else
454  return false;
455  }
456  }
457 
458  if ( m_routeRegion.contains( e->pos() ) ) {
459  if ( e->button() == Qt::LeftButton ) {
461  m_dropStopOver = e->pos();
462  storeDragPosition( e->pos() );
463  return true;
464  } else if ( e->button() == Qt::RightButton ) {
465  m_removeViaPointAction->setEnabled( false );
466  m_contextMenu->showRmbMenu( e->x(), e->y() );
467  return true;
468  } else
469  return false;
470  }
471 
472  if ( e->button() != Qt::LeftButton ) {
473  return false;
474  }
475 
476  foreach( const RequestRegion &region, m_alternativeRouteRegions ) {
477  if ( region.region.contains( e->pos() ) ) {
478  m_alternativeRoutesModel->setCurrentRoute( region.index );
479  return true;
480  }
481  }
482 
483  foreach( const ModelRegion &region, m_placemarks ) {
484  if ( region.region.contains( e->pos() ) ) {
485  emit q->placemarkSelected( region.index );
486  return true;
487  }
488  }
489 
490  return false;
491 }
492 
493 bool RoutingLayerPrivate::handleMouseButtonRelease( QMouseEvent *e )
494 {
495  if ( e->button() != Qt::LeftButton ) {
496  return false;
497  }
498 
499  if ( m_movingIndex >= 0 ) {
500  m_movingIndex = -1;
501  clearStopOver();
502  m_marbleWidget->model()->routingManager()->retrieveRoute();
503  return true;
504  }
505 
506  if ( !m_dropStopOver.isNull() && !m_dragStopOver.isNull() ) {
507  QPoint moved = e->pos() - m_dragStopOver;
508  if ( moved.manhattanLength() < 10 ) {
509  return false;
510  }
511 
512  qreal lon( 0.0 ), lat( 0.0 );
513  if ( m_dragStopOverRightIndex >= 0 && m_dragStopOverRightIndex <= m_routeRequest->size()
514  && m_marbleWidget->geoCoordinates( m_dropStopOver.x(), m_dropStopOver.y(), lon, lat, GeoDataCoordinates::Radian ) ) {
515  GeoDataCoordinates position( lon, lat );
516  m_dragStopOverRightIndex = viaInsertPosition( e->modifiers() );
517  m_routeRequest->insert( m_dragStopOverRightIndex, position );
518  clearStopOver();
519  m_marbleWidget->model()->routingManager()->retrieveRoute();
520  return true;
521  }
522  }
523 
524  return false;
525 }
526 
527 bool RoutingLayerPrivate::handleMouseMove( QMouseEvent *e )
528 {
529  qreal lon( 0.0 ), lat( 0.0 );
530  if ( m_marbleWidget->geoCoordinates( e->pos().x(), e->pos().y(),
531  lon, lat, GeoDataCoordinates::Radian ) ) {
532 
533  if ( m_movingIndex >= 0 ) {
534  GeoDataCoordinates moved( lon, lat );
535  m_routeRequest->setPosition( m_movingIndex, moved );
536  m_marbleWidget->setCursor( Qt::ArrowCursor );
537  } else if ( !m_dragStopOver.isNull() ) {
538  // Repaint only that region of the map that is affected by the change
539  m_dragStopOverRightIndex = viaInsertPosition( e->modifiers() );
540  QRect dirty = m_routeRegion.boundingRect();
541  dirty |= QRect( m_dropStopOver, m_pixmapSize );
542  dirty |= QRect( e->pos(), m_pixmapSize );
543  if ( e->buttons() & Qt::LeftButton ) {
544  m_dropStopOver = e->pos();
545  } else {
546  m_dragStopOver = QPoint();
547  m_dropStopOver = QPoint();
548  }
549  emit q->repaintNeeded( dirty );
550  m_marbleWidget->setCursor( Qt::ArrowCursor );
551  } else if ( isInfoPoint( e->pos() ) ) {
552  clearStopOver();
553  m_marbleWidget->setCursor( Qt::ArrowCursor );
554  } else if ( m_routeRegion.contains( e->pos() ) ) {
555  m_dropStopOver = e->pos();
556  m_marbleWidget->setCursor( Qt::ArrowCursor );
557  } else if ( !m_dropStopOver.isNull() ) {
558  clearStopOver();
559  } else if ( isAlternativeRoutePoint( e->pos() ) ) {
560  m_marbleWidget->setCursor( Qt::ArrowCursor );
561  }
562  else {
563  return false;
564  }
565 
566  // Update pixmap in the map (old and new position needs repaint)
567  paintStopOver( QRect( e->pos(), m_pixmapSize ) );
568  return true;
569  }
570 
571  return false;
572 }
573 
574 bool RoutingLayerPrivate::isInfoPoint( const QPoint &point )
575 {
576  foreach( const RequestRegion &region, m_regions ) {
577  if ( region.region.contains( point ) ) {
578  return true;
579  }
580  }
581 
582  foreach( const ModelRegion &region, m_instructionRegions ) {
583  if ( region.region.contains( point ) ) {
584  return true;
585  }
586  }
587 
588  return false;
589 }
590 
591  bool RoutingLayerPrivate::isAlternativeRoutePoint( const QPoint &point )
592  {
593  foreach( const RequestRegion &region, m_alternativeRouteRegions ) {
594  if ( region.region.contains( point ) ) {
595  return true;
596  }
597  }
598 
599  return false;
600  }
601 
602 void RoutingLayerPrivate::paintStopOver( QRect dirty )
603 {
604  emit q->repaintNeeded( m_dirtyRect );
605  int dx = 1 + m_pixmapSize.width() / 2;
606  int dy = 1 + m_pixmapSize.height() / 2;
607  dirty.adjust( -dx, -dy, -dx, -dy );
608  emit q->repaintNeeded( dirty );
609  m_dirtyRect = dirty;
610 }
611 
612 void RoutingLayerPrivate::clearStopOver()
613 {
614  m_dropStopOver = QPoint();
615  m_dragStopOver = QPoint();
616  emit q->repaintNeeded( m_dirtyRect );
617 }
618 
619 RoutingLayer::RoutingLayer( MarbleWidget *widget, QWidget *parent ) :
620  QObject( parent ), d( new RoutingLayerPrivate( this, widget ) )
621 {
622  connect( widget->model()->routingManager(), SIGNAL(stateChanged(RoutingManager::State)),
623  this, SLOT(updateRouteState(RoutingManager::State)) );
624  connect( widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
625  this, SLOT(setViewportChanged()) );
626  connect( widget->model()->routingManager()->alternativeRoutesModel(), SIGNAL(currentRouteChanged(GeoDataDocument*)),
627  this, SLOT(setViewportChanged()) );
628  connect( widget->model()->routingManager()->alternativeRoutesModel(), SIGNAL(currentRouteChanged(GeoDataDocument*)),
629  this, SIGNAL(repaintNeeded()) );
630  connect( widget->model()->routingManager()->alternativeRoutesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
631  this, SLOT(showAlternativeRoutes()) );
632 }
633 
634 RoutingLayer::~RoutingLayer()
635 {
636  delete d;
637 }
638 
639 QStringList RoutingLayer::renderPosition() const
640 {
641  return QStringList() << "HOVERS_ABOVE_SURFACE";
642 }
643 
644 qreal RoutingLayer::zValue() const
645 {
646  return 1.0;
647 }
648 
649 bool RoutingLayer::render( GeoPainter *painter, ViewportParams *viewport,
650  const QString& renderPos, GeoSceneLayer *layer )
651 {
652  Q_UNUSED( viewport )
653  Q_UNUSED( renderPos )
654  Q_UNUSED( layer )
655 
656  painter->save();
657 
658  if ( d->m_placemarkModel) {
659  d->renderPlacemarks( painter );
660  }
661 
662  if ( d->m_alternativeRoutesModel ) {
663  d->renderAlternativeRoutes( painter );
664  }
665 
666  d->renderRoute( painter );
667 
668  if ( d->m_routeRequest) {
669  d->renderRequest( painter );
670  }
671 
672  d->renderAnnotations( painter );
673 
674  painter->restore();
675  if ( d->m_viewportChanged && d->m_viewContext == Still ) {
676  d->m_viewportChanged = false;
677  }
678  return true;
679 }
680 
681 RenderState RoutingLayer::renderState() const
682 {
683  return RenderState( "Routing", d->m_routeDirty ? WaitingForUpdate : Complete );
684 }
685 
686 bool RoutingLayer::eventFilter( QObject *obj, QEvent *event )
687 {
688  Q_UNUSED( obj )
689 
690  if ( !d->m_isInteractive ) {
691  return false;
692  }
693 
694  if ( event->type() == QEvent::MouseButtonPress ) {
695  QMouseEvent *e = static_cast<QMouseEvent*>( event );
696  return d->handleMouseButtonPress( e );
697  }
698 
699  if ( event->type() == QEvent::MouseButtonRelease ) {
700  QMouseEvent *e = static_cast<QMouseEvent*>( event );
701  return d->handleMouseButtonRelease( e );
702  }
703 
704  if ( event->type() == QEvent::MouseMove ) {
705  QMouseEvent *e = static_cast<QMouseEvent*>( event );
706  return d->handleMouseMove( e );
707  }
708 
709  return false;
710 }
711 
712 void RoutingLayer::setPlacemarkModel ( MarblePlacemarkModel *model )
713 {
714  d->m_placemarkModel = model;
715  setViewportChanged();
716 }
717 
718 void RoutingLayer::synchronizeWith( QItemSelectionModel *selection )
719 {
720  d->m_selectionModel = selection;
721 }
722 
723 void RoutingLayerPrivate::setRouteDirty( bool dirty )
724 {
725  m_routeDirty = dirty;
726 
731  emit q->repaintNeeded();
732 }
733 
734 void RoutingLayer::removeViaPoint()
735 {
736  if ( d->m_activeMenuIndex >= 0 ) {
737  d->m_routeRequest->remove( d->m_activeMenuIndex );
738  d->m_activeMenuIndex = -1;
739  d->setRouteDirty( true );
740  d->m_marbleWidget->model()->routingManager()->retrieveRoute();
741  }
742 }
743 
744 void RoutingLayer::showAlternativeRoutes()
745 {
746  setViewportChanged();
747  emit repaintNeeded();
748 }
749 
750 void RoutingLayer::exportRoute()
751 {
752  QString fileName = QFileDialog::getSaveFileName( d->m_marbleWidget,
753  tr( "Export Route" ), // krazy:exclude=qclasses
754  QDir::homePath(),
755  tr( "GPX and KML files (*.gpx *.kml)" ) );
756 
757  if ( !fileName.isEmpty() ) {
758  if ( fileName.endsWith( QLatin1String( ".gpx" ), Qt::CaseInsensitive ) ) {
759  QFile gpx( fileName );
760  if ( gpx.open( QFile::WriteOnly) ) {
761  d->m_routingModel->exportGpx( &gpx );
762  gpx.close();
763  }
764  } else {
765  d->m_marbleWidget->model()->routingManager()->saveRoute( fileName );
766  }
767  }
768 }
769 
770 void RoutingLayer::updateRouteState( RoutingManager::State state )
771 {
772  d->setRouteDirty( state == RoutingManager::Downloading );
773  setViewportChanged();
774 }
775 
776 void RoutingLayer::setViewportChanged()
777 {
778  d->m_viewportChanged = true;
779  d->m_routeRegion = QRegion();
780  d->m_instructionRegions.clear();
781  d->m_alternativeRouteRegions.clear();
782 }
783 
784 void RoutingLayer::setViewContext( ViewContext viewContext )
785 {
786  d->m_viewContext = viewContext;
787 }
788 
789 void RoutingLayer::setInteractive( bool interactive )
790 {
791  d->m_isInteractive = interactive;
792 }
793 
794 bool RoutingLayer::isInteractive() const
795 {
796  return d->m_isInteractive;
797 }
798 
799 } // namespace Marble
800 
801 #include "RoutingLayer.moc"
GeoSceneHead.h
QModelIndex
GeoDataCoordinates.h
QEvent
QWidget
RoutingModel.h
Marble::MarblePlacemarkModel
This class represents a model of all place marks which are currently available through a given Placem...
Definition: MarblePlacemarkModel.h:37
QEvent::type
Type type() const
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:65
QPixmap::width
int width() const
Marble::RoutingLayer::eventFilter
bool eventFilter(QObject *obj, QEvent *event)
Overriding QWidget, used to make the layer interactive.
Definition: RoutingLayer.cpp:686
Marble::RoutingLayer::setViewContext
void setViewContext(ViewContext viewContext)
Set the view context to determine whether the map is used interactively.
Definition: RoutingLayer.cpp:784
Marble::RoutingLayer::repaintNeeded
void repaintNeeded(const QRect &rect=QRect())
Marble::GeoPainter
A painter that allows to draw geometric primitives on the map.
Definition: GeoPainter.h:98
Marble::RoutingLayer::zValue
qreal zValue() const
Reimplemented from LayerInterface.
Definition: RoutingLayer.cpp:644
MarbleModel.h
This file contains the headers for MarbleModel.
QMouseEvent::x
int x() const
QMouseEvent::y
int y() const
Marble::ViewContext
ViewContext
This enum is used to choose context in which map quality gets used.
Definition: MarbleGlobal.h:74
QPainter::save
void save()
QVariant::value
T value() const
QBrush
GeoSceneDocument.h
QPoint
QMouseEvent
Marble::RoutingLayer::isInteractive
bool isInteractive() const
Returns whether the route is interactive (true by default if not changed by setInteractive) ...
Definition: RoutingLayer.cpp:794
QMouseEvent::buttons
Qt::MouseButtons buttons() const
QDir::homePath
QString homePath()
QObject::tr
QString tr(const char *sourceText, const char *disambiguation, int n)
Marble::RoutingLayer::~RoutingLayer
~RoutingLayer()
Destructor.
Definition: RoutingLayer.cpp:634
QFile
QPoint::x
int x() const
QPoint::y
int y() const
Marble::Oxygen::hotOrange4
QColor const hotOrange4
Definition: MarbleColors.h:86
QIcon::pixmap
QPixmap pixmap(const QSize &size, Mode mode, State state) const
Maneuver.h
Marble::MarbleWidget
A widget class that displays a view of the earth.
Definition: MarbleWidget.h:104
QObject::event
virtual bool event(QEvent *e)
QRect
QModelIndex::isValid
bool isValid() const
RoutingManager.h
Marble::GeoSceneLayer
Layer of a GeoScene document.
Definition: GeoSceneLayer.h:43
Marble::Animation
animated view (e.g. while rotating the globe)
Definition: MarbleGlobal.h:76
QVariant::isNull
bool isNull() const
Marble::MarbleModel::routingManager
RoutingManager * routingManager()
Definition: MarbleModel.cpp:675
QObject
QMouseEvent::button
Qt::MouseButton button() const
RoutingLayer.h
Marble::MarbleWidget::model
MarbleModel * model()
Return the model that this view shows.
Definition: MarbleWidget.cpp:289
QString::isEmpty
bool isEmpty() const
MarbleWidgetPopupMenu.h
Marble::Still
still image
Definition: MarbleGlobal.h:75
GeoDataLineString.h
Marble::Oxygen::sunYellow6
QColor const sunYellow6
Definition: MarbleColors.h:78
Marble::RoutingLayer::renderPosition
QStringList renderPosition() const
Reimplemented from LayerInterface.
Definition: RoutingLayer.cpp:639
Marble::RoutingLayer::render
bool render(GeoPainter *painter, ViewportParams *viewport, const QString &renderPos="NONE", GeoSceneLayer *layer=0)
Reimplemented from LayerInterface.
Definition: RoutingLayer.cpp:649
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QString
QList< ModelRegion >
MarblePlacemarkModel.h
QColor
GeoPainter.h
Marble::RenderState
Definition: RenderState.h:22
QStringList
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
QPixmap
QInputEvent::modifiers
Qt::KeyboardModifiers modifiers() const
QPoint::manhattanLength
int manhattanLength() const
QSize
QPixmap::height
int height() const
Marble::Complete
All data is there and up to date.
Definition: MarbleGlobal.h:192
Marble::MarbleGlobal::SmallScreen
Definition: MarbleGlobal.h:287
Marble::MarbleGlobal::getInstance
static MarbleGlobal * getInstance()
Definition: MarbleGlobal.cpp:37
QPainter::restore
void restore()
Marble::RoutingManager::State
State
Definition: RoutingManager.h:42
QPoint::isNull
bool isNull() const
QModelIndex::data
QVariant data(int role) const
QPen::setWidth
void setWidth(int width)
QLatin1String
Marble::RoutingLayer::setPlacemarkModel
void setPlacemarkModel(MarblePlacemarkModel *model)
Set the placemark model to use.
Definition: RoutingLayer.cpp:712
QAction
QRect::adjust
void adjust(int dx1, int dy1, int dx2, int dy2)
QFileDialog::getSaveFileName
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
AlternativeRoutesModel.h
QPen
MarbleWidget.h
This file contains the headers for MarbleWidget.
Marble::WaitingForUpdate
Rendering is based on complete, but outdated data, data update was requested.
Definition: MarbleGlobal.h:193
RouteRequest.h
Marble::RoutingManager::Downloading
Definition: RoutingManager.h:43
Marble::RoutingLayer::synchronizeWith
void synchronizeWith(QItemSelectionModel *selection)
Set the proxy model another QAbstractItemView uses that should share its selection model with us...
Definition: RoutingLayer.cpp:718
QMouseEvent::pos
const QPoint & pos() const
MarbleWidget
Wraps a Marble::MarbleWidget, providing access to important properties and methods.
Definition: MarbleDeclarativeWidget.h:50
QItemSelectionModel
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QVariant::toString
QString toString() const
Marble::GeoDataLatLonAltBox
A class that defines a 3D bounding box for geographic data.
Definition: GeoDataLatLonAltBox.h:49
QRegion
QIcon
Marble::RoutingLayer::renderState
RenderState renderState() const
Definition: RoutingLayer.cpp:681
Marble::RoutingManager::alternativeRoutesModel
AlternativeRoutesModel * alternativeRoutesModel()
Provides access to the model which contains a list of alternative routes.
Definition: RoutingManager.cpp:312
Marble::RoutingLayer::setInteractive
void setInteractive(bool interactive)
Determine whether the route can be edited by the user (via points added, route cleared) ...
Definition: RoutingLayer.cpp:789
QVariant
Qt::KeyboardModifiers
typedef KeyboardModifiers
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:41 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