QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
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())
bool acceptMatch(const QgsPointLocator::Match &m) override
int x() const
int y() const
UnitType
Type of unit of tolerance value from settings.
Definition: qgstolerance.h:33
QgsMapMouseEvent(QgsMapCanvas *mapCanvas, QMouseEvent *event)
Creates a new QgsMapMouseEvent.
Qt::MouseButtons buttons() const
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:109
double y() const
Get the y value of the point.
Definition: qgspoint.h:193
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
int count(const T &value) const
snap according to the configuration set in the snapping settings
void setSnapToMapMode(SnapToMapMode mode)
Set how the snapping to map is done.
QList< QgsPoint > snapSegment(SnappingMode snappingMode, bool *snapped=nullptr, bool allLayers=false) const
Returns the first snapped segment.
Qt::MouseButton button() const
Snapped to a vertex. Can be a vertex of the geometry or an intersection.
A class to represent a point.
Definition: qgspoint.h:117
const QgsMapToPixel & mapToPixel() const
Qt::KeyboardModifiers modifiers() const
void setMapPoint(const QgsPoint &point)
Set the (snapped) point this event points to in map coordinates.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
typedef MouseButtons
This class has all the configuration of snapping and can return answers to snapping queries...
Snapped to an edge.
void edgePoints(QgsPoint &pt1, QgsPoint &pt2) const
Only for a valid edge match - obtain endpoints of the edge.
const QPoint & pos() const
QgsPoint point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords...
QgsPointLocator::Match snapToMap(QPoint point, QgsPointLocator::MatchFilter *filter=nullptr)
Snap to map according to the current configuration (mode).
QgsPoint snapPoint(SnappingMode snappingMode)
snapPoint will snap the points using the map canvas snapping utils configuration
QgsSnappingUtils * snappingUtils() const
Return snapping utility class that is associated with map canvas.
void setDefaultSettings(int type, double tolerance, QgsTolerance::UnitType unit)
Configure options used when the mode is snap to current layer or to all layers.
double x() const
Get the x value of the point.
Definition: qgspoint.h:185
void defaultSettings(int &type, double &tolerance, QgsTolerance::UnitType &unit)
Query options used when the mode is snap to current layer or to all layers.
typedef KeyboardModifiers
SnapToMapMode
modes for "snap to background"