QGIS API Documentation  2.12.0-Lyon
qgsmapmouseevent.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapmouseevent.cpp - mouse event in map coordinates and ability to snap
3  ----------------------
4  begin : October 2014
5  copyright : (C) Denis Rouzaud
6  email : [email protected]
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 
17 #include "qgsmapmouseevent.h"
18 #include "qgsmapcanvas.h"
19 
20 #include "qgssnappingutils.h"
21 
24 {
25  bool acceptMatch( const QgsPointLocator::Match& m ) override { return m.hasEdge(); }
26 };
28 
30  : QMouseEvent( event->type(), event->pos(), event->button(), event->buttons(), event->modifiers() )
31  , mSnappingMode( NoSnapping )
32  , mOriginalMapPoint( mapCanvas ? mapCanvas->mapSettings().mapToPixel().toMapCoordinates( event->pos() ) : QgsPoint() )
33  , mMapPoint( mOriginalMapPoint )
34  , mPixelPoint( event->pos() )
35  , mMapCanvas( mapCanvas )
36 {
37 }
38 
39 QgsMapMouseEvent::QgsMapMouseEvent( QgsMapCanvas* mapCanvas, QEvent::Type type, const QPoint& pos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers )
40  : QMouseEvent( type, pos, button, buttons, modifiers )
41  , mSnappingMode( NoSnapping )
42  , mOriginalMapPoint( mapCanvas ? mapCanvas->mapSettings().mapToPixel().toMapCoordinates( pos ) : QgsPoint() )
43  , mMapPoint( mOriginalMapPoint )
44  , mPixelPoint( pos )
45  , mMapCanvas( mapCanvas )
46 {
47 }
48 
50 {
51  // Use cached result
52  if ( mSnappingMode == snappingMode )
53  return mMapPoint;
54 
55  mSnappingMode = snappingMode;
56 
57  if ( snappingMode == NoSnapping )
58  {
59  mMapPoint = mOriginalMapPoint;
60  mPixelPoint = pos();
61  return mMapPoint;
62  }
63 
64  QgsSnappingUtils* snappingUtils = mMapCanvas->snappingUtils();
65  QgsSnappingUtils::SnapToMapMode canvasMode = snappingUtils->snapToMapMode();
66  if ( snappingMode == SnapAllLayers )
67  {
68  int type;
69  double tolerance;
71  snappingUtils->defaultSettings( type, tolerance, unit );
73  snappingUtils->setDefaultSettings( QgsPointLocator::Vertex | QgsPointLocator::Edge, tolerance, unit );
74  mSnapMatch = snappingUtils->snapToMap( mMapPoint );
75  snappingUtils->setSnapToMapMode( canvasMode );
76  snappingUtils->setDefaultSettings( type, tolerance, unit );
77  }
78  else
79  {
80  mSnapMatch = snappingUtils->snapToMap( mMapPoint );
81  }
82 
83  if ( mSnapMatch.isValid() )
84  {
85  mMapPoint = mSnapMatch.point();
86  mPixelPoint = mapToPixelCoordinates( mMapPoint );
87  }
88  else
89  {
90  mMapPoint = mOriginalMapPoint;
91  mPixelPoint = pos();
92  }
93 
94  return mMapPoint;
95 }
96 
97 QList<QgsPoint> QgsMapMouseEvent::snapSegment( SnappingMode snappingMode, bool* snapped , bool allLayers ) const
98 {
99  QList<QgsPoint> segment;
100  QgsPoint pt1, pt2;
101 
102  // If there's a cached snapping result we use it
103  if ( snappingMode == mSnappingMode && mSnapMatch.hasEdge() )
104  {
105  mSnapMatch.edgePoints( pt1, pt2 );
106  segment << pt1 << pt2;
107  }
108 
109  else if ( snappingMode != NoSnapping )
110  {
112  if ( snappingMode == SnapProjectConfig && !allLayers )
113  {
114  // run snapToMap with only segments
115  EdgesOnlyFilter filter;
116  match = mMapCanvas->snappingUtils()->snapToMap( mOriginalMapPoint, &filter );
117  }
118  else if ( snappingMode == SnapAllLayers || allLayers )
119  {
120  // run snapToMap with only edges on all layers
121  QgsSnappingUtils* snappingUtils = mMapCanvas->snappingUtils();
122  QgsSnappingUtils::SnapToMapMode canvasMode = snappingUtils->snapToMapMode();
123  int type;
124  double tolerance;
126  snappingUtils->defaultSettings( type, tolerance, unit );
128  snappingUtils->setDefaultSettings( QgsPointLocator::Edge, tolerance, unit );
129  match = snappingUtils->snapToMap( mOriginalMapPoint );
130  snappingUtils->setSnapToMapMode( canvasMode );
131  snappingUtils->setDefaultSettings( type, tolerance, unit );
132  }
133  if ( match.isValid() && match.hasEdge() )
134  {
135  match.edgePoints( pt1, pt2 );
136  segment << pt1 << pt2;
137  }
138  }
139 
140  if ( snapped )
141  {
142  *snapped = segment.count() == 2;
143  }
144 
145  return segment;
146 }
147 
149 {
150  mMapPoint = point;
151  mPixelPoint = mapToPixelCoordinates( point );
152 }
153 
154 QPoint QgsMapMouseEvent::mapToPixelCoordinates( const QgsPoint& point )
155 {
156  double x = point.x(), y = point.y();
157 
158  mMapCanvas->mapSettings().mapToPixel().transformInPlace( x, y );
159 
160  return QPoint( qRound( x ), qRound( y ) );
161 }
SnapToMapMode snapToMapMode() const
Find out how the snapping to map is done.
Type type() const
snap to all rendered layers (tolerance and type from defaultSettings())
snap to all rendered layers (tolerance and type from defaultSettings())
QgsPointLocator::Match snapToMap(const QPoint &point, QgsPointLocator::MatchFilter *filter=0)
Snap to map according to the current configuration (mode).
bool acceptMatch(const QgsPointLocator::Match &m) override
int x() const
int y() const
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
const QgsMapToPixel & mapToPixel() const
QgsMapMouseEvent(QgsMapCanvas *mapCanvas, QMouseEvent *event)
Creates a new QgsMapMouseEvent.
Interface that allows rejection of some matches in intersection queries (e.g.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:107
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
void transformInPlace(double &x, double &y) const
Transform device coordinates to map (world) coordinates.
int count(const T &value) const
snap according to the configuration set in the snapping settings
QgsSnappingUtils * snappingUtils() const
Return snapping utility class that is associated with map canvas.
void setSnapToMapMode(SnapToMapMode mode)
Set how the snapping to map is done.
A class to represent a point.
Definition: qgspoint.h:63
void setMapPoint(const QgsPoint &point)
Set the (snapped) point this event points to in map coordinates.
QList< QgsPoint > snapSegment(SnappingMode snappingMode, bool *snapped=0, bool allLayers=false) const
Returns the first snapped segment.
typedef MouseButtons
This class has all the configuration of snapping and can return answers to snapping queries...
void edgePoints(QgsPoint &pt1, QgsPoint &pt2) const
Only for a valid edge match - obtain endpoints of the edge.
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
QgsPoint point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords...
const QPoint & pos() const
UnitType
Type of unit of tolerance value from settings.
Definition: qgstolerance.h:33
QgsPoint snapPoint(SnappingMode snappingMode)
snapPoint will snap the points using the map canvas snapping utils configuration
void setDefaultSettings(int type, double tolerance, QgsTolerance::UnitType unit)
Configure options used when the mode is snap to current layer.
void defaultSettings(int &type, double &tolerance, QgsTolerance::UnitType &unit)
Query options used when the mode is snap to current layer.
typedef KeyboardModifiers
SnapToMapMode
modes for "snap to background"