Results 1 to 3 of 3

Thread: Google Maps mousewheel zoom (How To)

  1. #1
    Join Date
    Dec 2011
    Posts
    60
    Thanks
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Google Maps mousewheel zoom (How To)

    In case this is of some use to others who desire a similar feature, here's some code to zoom in Qwt like Google Maps.

    Behavior
    The mousewheel in Google Maps, Photoshop, Bing Maps, Mapquest, and others, zooms toward the cursor location. This allows the user to hover over a point/area of interest and keep that point under the cursor when zooming in/out. This is highly desirable in a plotter as well, since it generally removes the need to subsequently pan the display.

    Wheel direction
    The wheel direction matches the zoom direction in Google Maps, Photoshop, Bing Maps, and Mapquest. Most everyone is familiar with one or more of these. If you prefer the current Qwt mousewheel direction, this can be easily reversed in the code.

    Rolling mousewheel AWAY from you zooms IN
    Rolling mousewheel TOWARD you zooms OUT

    Implementation
    I handled the mouse events entirely in a subclass of QwtPlot(), which fit my needs, but I'm sure there are many other different ways to do it. If there's clearly a better way, please let me know.

    Aside from the event handling, the key part is the math algorithm to aim the zoom toward the mouse cursor. For this, I found various code snippets online and adjusted them for Qwt.

    Issues
    Occasionally when zooming in the underlying waveform will move slightly away from the mouse pointer. Judging by the behavior, I would guess that this is a result of the axis scale being adjusted to provide round numbers, and thus not delivering the exact zoom rectangle that was requested.

    Cheers.

    QwtPlot subclass
    Qt Code:
    1. QwtPlotX::QwtPlotX( QWidget *widget )
    2. : QwtPlot(widget), m_ctrlKeyDown(false)
    3. {
    4. setFocusPolicy(Qt::StrongFocus); // Needed to catch keyReleaseEvent()
    5.  
    6. // Set plot title
    7. setCanvasBackground( Qt::white );
    8. setAxisScale( QwtPlot::yLeft, 0.0, 10.0 );
    9. insertLegend( new QwtLegend() );
    10. setMinimumHeight(150);
    11.  
    12. // Grid
    13. QPen pen;
    14. pen.setColor(QColor(128, 128, 128, 128));//Qt::gray);
    15. pen.setWidth(0);
    16. pen.setStyle(Qt::DotLine);
    17. QwtPlotGrid *trendGrid = new QwtPlotGrid();
    18. trendGrid->setPen(pen);
    19. trendGrid->attach(this);
    20.  
    21. // Zoom control
    22. m_zoomer = new QwtPlotZoomerX( QwtPlot::xBottom, QwtPlot::yLeft, this->canvas() );
    23.  
    24. // Plot zooming with mouse wheel
    25. this->canvas()->setMouseTracking(true);
    26.  
    27. // Install event filter to catch mouse presses
    28. this->canvas()->installEventFilter(this);
    29. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. bool QwtPlotX::eventFilter( QObject *object, QEvent *event )
    2. {
    3. if ( object == this->canvas() )
    4. {
    5. if (event->type() == QEvent::MouseButtonPress)
    6. {
    7. QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    8. if (mouseEvent->button() == Qt::LeftButton)
    9. {
    10. // qDebug() << "Left button";
    11. }
    12. if (mouseEvent->button() == Qt::MiddleButton)
    13. {
    14. // qDebug() << "Middle button";
    15. }
    16. if (mouseEvent->button() == Qt::RightButton)
    17. {
    18. // qDebug() << "Right button";
    19. }
    20. }
    21. // Google Maps zoom
    22. if (event->type() == QEvent::Wheel)
    23. {
    24. QMouseEvent *mEvent = (QMouseEvent *)event;
    25. QWheelEvent *wEvent = (QWheelEvent *)event;
    26. QPointF mousePos;
    27. QPointF plotPos;
    28. QRectF zoomRect;
    29. float xw, yw, xhw, yhw, xz, yz;
    30. float slideFactor;
    31. float scaleFactor;
    32.  
    33. // Zoom IN
    34. if (wEvent->delta() > 0)
    35. {
    36. scaleFactor = 1.2;
    37. }
    38. else
    39. {
    40. scaleFactor = 0.8;
    41. }
    42.  
    43. // Mouse position
    44. mousePos.setX(mEvent->x());
    45. mousePos.setY(mEvent->y());
    46.  
    47. // How much to slide the zoom toward the mouse
    48. slideFactor = 1.0 - (1.0 / scaleFactor);
    49.  
    50. // Get current zoom rectangle
    51. zoomRect = m_zoomer->zoomRect();
    52.  
    53. // Calculate current widths
    54. xw = zoomRect.width();
    55. yw = zoomRect.height();
    56.  
    57. // Calculate mid-points (half-widths)
    58. xhw = xw/2.0 + zoomRect.left();
    59. yhw = yw/2.0 + zoomRect.top(); // Note: QRect top is actually the bottom of the plot.
    60.  
    61. // Calculate widths after zoom
    62. xz = xw / scaleFactor;
    63. yz = yw / scaleFactor;
    64.  
    65. // To zoom purely to the center
    66. zoomRect.setLeft (zoomRect.left() +(xw - xz)/2.0);
    67. zoomRect.setBottom(zoomRect.bottom()-(yw - yz)/2.0);
    68. zoomRect.setRight (zoomRect.right() -(xw - xz)/2.0);
    69. zoomRect.setTop (zoomRect.top() +(yw - yz)/2.0);
    70.  
    71. // Aim the zoom toward the mouse location
    72. // Get distance of mouse from center
    73. float mx = (this->invTransform(QwtPlot::xBottom, mousePos.x()) - xhw) * slideFactor;
    74. float my = (this->invTransform(QwtPlot::yLeft, mousePos.y()) - yhw) * slideFactor;
    75.  
    76. // Correct zoom for mouse position
    77. zoomRect.setLeft (zoomRect.left() + mx);
    78. zoomRect.setRight (zoomRect.right() + mx);
    79. zoomRect.setBottom(zoomRect.bottom()+ my);
    80. zoomRect.setTop (zoomRect.top() + my);
    81.  
    82. m_zoomer->zoom(zoomRect);
    83. }
    84. }
    85.  
    86. return QwtPlot::eventFilter( object, event );
    87. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by alketi; 20th May 2013 at 20:20.

  2. #2
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Google Maps mousewheel zoom (How To)

    Rolling mousewheel AWAY from you zooms IN
    Rolling mousewheel TOWARD you zooms OUT
    I also prefer this this mode of zooming. Its supported in Qwt already, just set a negative wheel factor with QwtMagnifier::setMouseFactor().

  3. #3
    Join Date
    Dec 2011
    Posts
    60
    Thanks
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Google Maps mousewheel zoom (How To)

    Quote Originally Posted by Seamus View Post
    I also prefer this this mode of zooming. Its supported in Qwt already, just set a negative wheel factor with QwtMagnifier::setMouseFactor().
    Thank you! I wasn't aware of that.

Similar Threads

  1. QWebView, Google maps
    By Viper666 in forum Qt Programming
    Replies: 15
    Last Post: 20th October 2012, 13:45
  2. how the Google maps get direction
    By MKSPulok in forum General Discussion
    Replies: 1
    Last Post: 16th June 2012, 21:52
  3. Google Maps API and QWebKit
    By QFreeCamellia in forum Qt Programming
    Replies: 1
    Last Post: 18th January 2012, 05:42
  4. Map is not displayed from maps.google.com
    By abhilashajha in forum Qt Programming
    Replies: 2
    Last Post: 11th June 2009, 14:19

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.