QGIS API Documentation  3.13.0-Master (788156190c)
qgssnaptogridcanvasitem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssnaptogridcanvasitem.cpp
3  ----------------------
4  begin : August 2018
5  copyright : (C) Matthias Kuhn
6  email : [email protected]ch
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 
17 #include "qgsmapcanvas.h"
18 
20  : QgsMapCanvasItem( mapCanvas )
21 {
22  updateMapCanvasCrs();
23  connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsSnapToGridCanvasItem::updateZoomFactor );
24  connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsSnapToGridCanvasItem::updateMapCanvasCrs );
25 }
26 
27 void QgsSnapToGridCanvasItem::paint( QPainter *painter )
28 {
29  if ( !mEnabled || !mAvailableByZoomFactor )
30  return;
31 
32  painter->save();
33  QgsRectangle mapRect = mMapCanvas->extent();
34 
35  painter->setRenderHints( QPainter::Antialiasing );
36  painter->setCompositionMode( QPainter::CompositionMode_Difference );
37 
38  double scaleFactor = painter->fontMetrics().xHeight() * .2;
39 
40  mGridPen.setWidth( scaleFactor );
41  mCurrentPointPen.setWidth( scaleFactor * 3 );
42  const int gridMarkerLength = scaleFactor * 3;
43 
44  try
45  {
46  const QgsRectangle layerExtent = mTransform.transformBoundingBox( mapRect, QgsCoordinateTransform::ReverseTransform );
47  const QgsPointXY layerPt = mTransform.transform( mPoint, QgsCoordinateTransform::ReverseTransform );
48 
49  const double gridXMin = std::ceil( layerExtent.xMinimum() / mPrecision ) * mPrecision;
50  const double gridXMax = std::ceil( layerExtent.xMaximum() / mPrecision ) * mPrecision;
51  const double gridYMin = std::ceil( layerExtent.yMinimum() / mPrecision ) * mPrecision;
52  const double gridYMax = std::ceil( layerExtent.yMaximum() / mPrecision ) * mPrecision;
53 
54  for ( double x = gridXMin ; x < gridXMax; x += mPrecision )
55  {
56  for ( double y = gridYMin ; y < gridYMax; y += mPrecision )
57  {
58  const QgsPointXY pt = mTransform.transform( x, y );
59  const QPointF canvasPt = toCanvasCoordinates( pt );
60 
61  if ( qgsDoubleNear( layerPt.x(), x, mPrecision / 2 ) && qgsDoubleNear( layerPt.y(), y, mPrecision / 2 ) )
62  {
63  painter->setPen( mCurrentPointPen );
64  }
65  else
66  {
67  painter->setPen( mGridPen );
68  }
69  painter->drawLine( canvasPt.x() - gridMarkerLength, canvasPt.y(), canvasPt.x() + gridMarkerLength, canvasPt.y() );
70  painter->drawLine( canvasPt.x(), canvasPt.y() - gridMarkerLength, canvasPt.x(), canvasPt.y() + gridMarkerLength );
71 
72  }
73  }
74  }
75  catch ( QgsCsException &e )
76  {
77  Q_UNUSED( e )
78  mAvailableByZoomFactor = false;
79  }
80 
81  painter->restore();
82 }
83 
85 {
86  return mPoint;
87 }
88 
90 {
91  mPoint = point;
92  update();
93 }
94 
96 {
97  return mPrecision;
98 }
99 
101 {
102  mPrecision = precision;
103  updateZoomFactor();
104 }
105 
107 {
108  return mTransform.sourceCrs();
109 }
110 
112 {
113  mTransform.setSourceCrs( crs );
114  updateZoomFactor();
115 }
116 
118 {
119  return mEnabled;
120 }
121 
123 {
124  mEnabled = enabled;
125  update();
126 }
127 
128 void QgsSnapToGridCanvasItem::updateMapCanvasCrs()
129 {
132  update();
133 }
134 
135 
136 
137 void QgsSnapToGridCanvasItem::updateZoomFactor()
138 {
139  if ( !isVisible() )
140  return;
141 
142  try
143  {
144  const int threshold = 5;
145 
146  const QgsRectangle extent = mMapCanvas->extent();
147  if ( extent != rect() )
148  setRect( extent );
149 
150  const QgsPointXY centerPoint = mMapCanvas->extent().center();
151  const QPointF canvasCenter = toCanvasCoordinates( centerPoint );
152 
153  const QgsPointXY pt1 = mMapCanvas->mapSettings().mapToPixel().toMapCoordinates( static_cast<int>( canvasCenter.x() - threshold ),
154  static_cast<int>( canvasCenter.y() - threshold ) );
155  const QgsPointXY pt2 = mMapCanvas->mapSettings().mapToPixel().toMapCoordinates( static_cast<int>( canvasCenter.x() + threshold ),
156  static_cast<int>( canvasCenter.y() + threshold ) );
157 
158  const QgsPointXY layerPt1 = mTransform.transform( pt1, QgsCoordinateTransform::ReverseTransform );
159  const QgsPointXY layerPt2 = mTransform.transform( pt2, QgsCoordinateTransform::ReverseTransform );
160 
161  const double dist = layerPt1.distance( layerPt2 );
162 
163  if ( dist < mPrecision )
164  mAvailableByZoomFactor = true;
165  else
166  mAvailableByZoomFactor = false;
167  }
168  catch ( QgsCsException & )
169  {
170  // transform errors?
171  // you've probably got worse problems than the grid with your digitizing operations in the current projection.
172  mAvailableByZoomFactor = false;
173  }
174 }
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:865
QgsSnapToGridCanvasItem::QgsSnapToGridCanvasItem
QgsSnapToGridCanvasItem(QgsMapCanvas *mapCanvas)
Will automatically be added to the mapCanvas.
Definition: qgssnaptogridcanvasitem.cpp:19
QgsMapCanvas::destinationCrsChanged
void destinationCrsChanged()
Emitted when map CRS has changed.
qgsmapcanvas.h
QgsMapCanvasItem::mMapCanvas
QgsMapCanvas * mMapCanvas
pointer to map canvas
Definition: qgsmapcanvasitem.h:82
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:380
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsCoordinateTransform::setContext
void setContext(const QgsCoordinateTransformContext &context)
Sets the context in which the coordinate transform should be calculated.
Definition: qgscoordinatetransform.cpp:198
QgsRectangle::xMaximum
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
QgsMapCanvas
Definition: qgsmapcanvas.h:78
QgsCoordinateTransform::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs)
Sets the source coordinate reference system.
Definition: qgscoordinatetransform.cpp:157
QgsMapToPixel::toMapCoordinates
QgsPointXY toMapCoordinates(int x, int y) const
Transform device coordinates to map (world) coordinates.
Definition: qgsmaptopixel.cpp:108
QgsCoordinateTransform::transform
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:237
QgsRectangle
Definition: qgsrectangle.h:41
QgsCoordinateTransform::ReverseTransform
@ ReverseTransform
Transform from destination to source CRS.
Definition: qgscoordinatetransform.h:61
QgsSnapToGridCanvasItem::setPrecision
void setPrecision(double precision)
The resolution of the grid in map units.
Definition: qgssnaptogridcanvasitem.cpp:100
QgsCoordinateTransform::transformBoundingBox
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:509
QgsMapCanvasItem::setRect
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
Definition: qgsmapcanvasitem.cpp:74
QgsSnapToGridCanvasItem::crs
QgsCoordinateReferenceSystem crs() const
The CRS in which the grid should be calculated.
Definition: qgssnaptogridcanvasitem.cpp:106
QgsCoordinateTransform::sourceCrs
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source coordinate reference system, which the transform will transform coordinates from.
Definition: qgscoordinatetransform.cpp:227
precision
int precision
Definition: qgswfsgetfeature.cpp:103
qgssnaptogridcanvasitem.h
QgsCsException
Definition: qgsexception.h:65
QgsMapCanvasItem
Definition: qgsmapcanvasitem.h:33
QgsMapSettings::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Definition: qgsmapsettings.cpp:400
QgsSnapToGridCanvasItem::enabled
bool enabled() const
Enable this item.
Definition: qgssnaptogridcanvasitem.cpp:117
QgsMapCanvasItem::toCanvasCoordinates
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
Definition: qgsmapcanvasitem.cpp:61
QgsCoordinateTransform::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination coordinate reference system.
Definition: qgscoordinatetransform.cpp:177
QgsSnapToGridCanvasItem::setEnabled
void setEnabled(bool enabled)
Enable this item.
Definition: qgssnaptogridcanvasitem.cpp:122
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsPointXY::distance
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate.
Definition: qgspointxy.h:196
QgsSnapToGridCanvasItem::point
QgsPointXY point() const
A point that will be highlighted on the map canvas.
Definition: qgssnaptogridcanvasitem.cpp:84
QgsMapCanvas::extentsChanged
void extentsChanged()
Emitted when the extents of the map change.
QgsSnapToGridCanvasItem::paint
void paint(QPainter *painter) override
function to be implemented by derived classes
Definition: qgssnaptogridcanvasitem.cpp:27
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:209
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsPointXY
Definition: qgspointxy.h:43
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
Definition: qgsmapsettings.cpp:317
QgsRectangle::center
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
QgsMapCanvasItem::rect
QgsRectangle rect() const
returns canvas item rectangle in map units
Definition: qgsmapcanvasitem.cpp:68
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsRectangle::yMinimum
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsSnapToGridCanvasItem::precision
double precision() const
The resolution of the grid in map units.
Definition: qgssnaptogridcanvasitem.cpp:95
QgsSnapToGridCanvasItem::setPoint
void setPoint(const QgsPointXY &point)
A point that will be highlighted on the map canvas.
Definition: qgssnaptogridcanvasitem.cpp:89
QgsMapSettings::mapToPixel
const QgsMapToPixel & mapToPixel() const
Definition: qgsmapsettings.h:432
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsSnapToGridCanvasItem::setCrs
void setCrs(const QgsCoordinateReferenceSystem &crs)
The CRS in which the grid should be calculated.
Definition: qgssnaptogridcanvasitem.cpp:111