QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsextentwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsextentwidget.cpp
3  ---------------------
4  begin : March 2020
5  copyright : (C) 2020 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
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 #include "qgsextentwidget.h"
17 
18 #include "qgslogger.h"
19 #include "qgscoordinatetransform.h"
20 #include "qgsmapcanvas.h"
21 #include "qgsmaplayermodel.h"
22 #include "qgsexception.h"
23 #include "qgsproject.h"
24 #include "qgsdoublevalidator.h"
25 
26 #include <QMenu>
27 #include <QAction>
28 #include <QRegularExpression>
29 
31  : QWidget( parent )
32 {
33  setupUi( this );
34  connect( mXMinLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );
35  connect( mXMaxLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );
36  connect( mYMinLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );
37  connect( mYMaxLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );
38 
39  mCondensedRe = QRegularExpression( QStringLiteral( "\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*,\\s*([\\d\\.\\-]+)\\s*(?:\\[(.*?)\\])?" ) );
40  mCondensedLineEdit->setValidator( new QRegularExpressionValidator( mCondensedRe, this ) );
41  mCondensedLineEdit->setShowClearButton( false );
42  connect( mCondensedLineEdit, &QgsFilterLineEdit::cleared, this, &QgsExtentWidget::clear );
43  connect( mCondensedLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromCondensedLineEdit );
44 
45  mLayerMenu = new QMenu( tr( "Calculate from Layer" ), this );
46  mButtonCalcFromLayer->setMenu( mLayerMenu );
47  connect( mLayerMenu, &QMenu::aboutToShow, this, &QgsExtentWidget::layerMenuAboutToShow );
48  mMapLayerModel = new QgsMapLayerModel( this );
49 
50  mMenu = new QMenu( this );
51  mUseCanvasExtentAction = new QAction( tr( "Use Map Canvas Extent" ), this );
52  connect( mUseCanvasExtentAction, &QAction::triggered, this, &QgsExtentWidget::setOutputExtentFromCurrent );
53 
54  mUseCurrentExtentAction = new QAction( tr( "Use Current Layer Extent" ), this );
55  connect( mUseCurrentExtentAction, &QAction::triggered, this, &QgsExtentWidget::setOutputExtentFromCurrent );
56 
57  mDrawOnCanvasAction = new QAction( tr( "Draw on Canvas" ), this );
58  connect( mDrawOnCanvasAction, &QAction::triggered, this, &QgsExtentWidget::setOutputExtentFromDrawOnCanvas );
59 
60  mMenu->addMenu( mLayerMenu );
61 
62  mCondensedToolButton->setMenu( mMenu );
63  mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );
64 
65  mXMinLineEdit->setValidator( new QgsDoubleValidator( this ) );
66  mXMaxLineEdit->setValidator( new QgsDoubleValidator( this ) );
67  mYMinLineEdit->setValidator( new QgsDoubleValidator( this ) );
68  mYMaxLineEdit->setValidator( new QgsDoubleValidator( this ) );
69 
70  mOriginalExtentButton->setVisible( false );
71  mButtonDrawOnCanvas->setVisible( false );
72  mCurrentExtentButton->setVisible( false );
73 
74  connect( mCurrentExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromCurrent );
75  connect( mOriginalExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromOriginal );
76  connect( mButtonDrawOnCanvas, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromDrawOnCanvas );
77 
78  switch ( style )
79  {
80  case CondensedStyle:
81  mExpandedWidget->hide();
82  break;
83 
84  case ExpandedStyle:
85  mCondensedFrame->hide();
86  break;
87  }
88 
89  setAcceptDrops( true );
90 }
91 
92 void QgsExtentWidget::setOriginalExtent( const QgsRectangle &originalExtent, const QgsCoordinateReferenceSystem &originalCrs )
93 {
94  mOriginalExtent = originalExtent;
95  mOriginalCrs = originalCrs;
96 
97  mOriginalExtentButton->setVisible( true );
98 }
99 
100 
101 void QgsExtentWidget::setCurrentExtent( const QgsRectangle &currentExtent, const QgsCoordinateReferenceSystem &currentCrs )
102 {
103  mCurrentExtent = currentExtent;
104  mCurrentCrs = currentCrs;
105 
106  mCurrentExtentButton->setVisible( true );
107  mMenu->addAction( mUseCurrentExtentAction );
108 }
109 
111 {
112  mHasFixedOutputCrs = true;
113  if ( mOutputCrs != outputCrs )
114  {
115  bool prevExtentEnabled = mIsValid;
116  switch ( mExtentState )
117  {
118  case CurrentExtent:
119  mOutputCrs = outputCrs;
121  break;
122 
123  case OriginalExtent:
124  mOutputCrs = outputCrs;
126  break;
127 
128  case ProjectLayerExtent:
129  mOutputCrs = outputCrs;
130  setOutputExtentFromLayer( mExtentLayer.data() );
131  break;
132 
133  case DrawOnCanvas:
134  mOutputCrs = outputCrs;
135  extentDrawn( outputExtent() );
136  break;
137 
138  case UserExtent:
139  try
140  {
143  mOutputCrs = outputCrs;
145  }
146  catch ( QgsCsException & )
147  {
148  // can't reproject
149  mOutputCrs = outputCrs;
150  }
151  break;
152  }
153 
154  if ( !prevExtentEnabled )
155  setValid( false );
156  }
157 }
158 
159 void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, ExtentState state )
160 {
161  QgsRectangle extent;
162  if ( !mHasFixedOutputCrs )
163  {
164  mOutputCrs = srcCrs;
165  extent = r;
166  }
167  else
168  {
169  if ( mOutputCrs == srcCrs )
170  {
171  extent = r;
172  }
173  else
174  {
175  try
176  {
177  QgsCoordinateTransform ct( srcCrs, mOutputCrs, QgsProject::instance() );
178  extent = ct.transformBoundingBox( r );
179  }
180  catch ( QgsCsException & )
181  {
182  // can't reproject
183  extent = r;
184  }
185  }
186  }
187 
188  int decimals = 4;
189  switch ( mOutputCrs.mapUnits() )
190  {
193  decimals = 9;
194  break;
203  decimals = 4;
204  break;
205  }
206  mXMinLineEdit->setText( QLocale().toString( extent.xMinimum(), 'f', decimals ) );
207  mXMaxLineEdit->setText( QLocale().toString( extent.xMaximum(), 'f', decimals ) );
208  mYMinLineEdit->setText( QLocale().toString( extent.yMinimum(), 'f', decimals ) );
209  mYMaxLineEdit->setText( QLocale().toString( extent.yMaximum(), 'f', decimals ) );
210 
211  QString condensed = QStringLiteral( "%1,%2,%3,%4" ).arg( QString::number( extent.xMinimum(), 'f', decimals ),
212  QString::number( extent.xMaximum(), 'f', decimals ),
213  QString::number( extent.yMinimum(), 'f', decimals ),
214  QString::number( extent.yMaximum(), 'f', decimals ) );
215  condensed += QStringLiteral( " [%1]" ).arg( mOutputCrs.userFriendlyIdentifier( QgsCoordinateReferenceSystem::ShortString ) );
216  mCondensedLineEdit->setText( condensed );
217 
218  mExtentState = state;
219 
220  if ( !mIsValid )
221  setValid( true );
222 
223  emit extentChanged( extent );
224 }
225 
226 void QgsExtentWidget::setOutputExtentFromLineEdit()
227 {
228  mExtentState = UserExtent;
229  emit extentChanged( outputExtent() );
230 }
231 
232 void QgsExtentWidget::setOutputExtentFromCondensedLineEdit()
233 {
234  const QString text = mCondensedLineEdit->text();
235  if ( text.isEmpty() )
236  {
237  clear();
238  }
239  else
240  {
241  const QRegularExpressionMatch match = mCondensedRe.match( text );
242  if ( match.hasMatch() )
243  {
244  whileBlocking( mXMinLineEdit )->setText( match.captured( 1 ) );
245  whileBlocking( mXMaxLineEdit )->setText( match.captured( 2 ) );
246  whileBlocking( mYMinLineEdit )->setText( match.captured( 3 ) );
247  whileBlocking( mYMaxLineEdit )->setText( match.captured( 4 ) );
248  if ( !match.captured( 5 ).isEmpty() )
249  {
250  mOutputCrs = QgsCoordinateReferenceSystem( match.captured( 5 ) );
251  }
252 
253  emit extentChanged( outputExtent() );
254  if ( !mIsValid )
255  setValid( true );
256  }
257  }
258 }
259 
261 {
262  bool prevWasNull = mIsValid;
263 
264  whileBlocking( mXMinLineEdit )->clear();
265  whileBlocking( mXMaxLineEdit )->clear();
266  whileBlocking( mYMinLineEdit )->clear();
267  whileBlocking( mYMaxLineEdit )->clear();
268  whileBlocking( mCondensedLineEdit )->clearValue();
269  setValid( false );
270 
271  if ( prevWasNull )
272  emit extentChanged( outputExtent() );
273 }
274 
276 {
277  return mExtentLayerName;
278 }
279 
281 {
282  return mIsValid;
283 }
284 
285 void QgsExtentWidget::setNullValueAllowed( bool allowed, const QString &notSetText )
286 {
287  mCondensedLineEdit->setShowClearButton( allowed );
288  mCondensedLineEdit->setNullValue( notSetText );
289 }
290 
291 void QgsExtentWidget::setValid( bool valid )
292 {
293  if ( valid == mIsValid )
294  return;
295 
296  mIsValid = valid;
297  emit validationChanged( mIsValid );
298 }
299 
300 void QgsExtentWidget::layerMenuAboutToShow()
301 {
302  qDeleteAll( mLayerMenuActions );
303  mLayerMenuActions.clear();
304  mLayerMenu->clear();
305  for ( int i = 0; i < mMapLayerModel->rowCount(); ++i )
306  {
307  QModelIndex index = mMapLayerModel->index( i, 0 );
308  QIcon icon = qvariant_cast<QIcon>( mMapLayerModel->data( index, Qt::DecorationRole ) );
309  QString text = mMapLayerModel->data( index, Qt::DisplayRole ).toString();
310  QAction *act = new QAction( icon, text, mLayerMenu );
311  act->setToolTip( mMapLayerModel->data( index, Qt::ToolTipRole ).toString() );
312  QString layerId = mMapLayerModel->data( index, QgsMapLayerModel::LayerIdRole ).toString();
313  if ( mExtentState == ProjectLayerExtent && mExtentLayer && mExtentLayer->id() == layerId )
314  {
315  act->setCheckable( true );
316  act->setChecked( true );
317  }
318  connect( act, &QAction::triggered, this, [this, layerId]
319  {
320  setExtentToLayerExtent( layerId );
321  } );
322  mLayerMenu->addAction( act );
323  mLayerMenuActions << act;
324  }
325 }
326 
327 void QgsExtentWidget::setExtentToLayerExtent( const QString &layerId )
328 {
329  QgsMapLayer *layer = QgsProject::instance()->mapLayer( layerId );
330  if ( !layer )
331  return;
332 
333  setOutputExtentFromLayer( layer );
334 }
335 
336 QgsMapLayer *QgsExtentWidget::mapLayerFromMimeData( const QMimeData *data ) const
337 {
339  for ( const QgsMimeDataUtils::Uri &u : uriList )
340  {
341  // is this uri from the current project?
342  if ( QgsMapLayer *layer = u.mapLayer() )
343  {
344  return layer;
345  }
346  }
347  return nullptr;
348 }
349 
351 {
352  if ( mCanvas )
353  {
354  // Use unrotated visible extent to insure output size and scale matches canvas
355  QgsMapSettings ms = mCanvas->mapSettings();
356  ms.setRotation( 0 );
357  setOutputExtent( ms.visibleExtent(), ms.destinationCrs(), CurrentExtent );
358  }
359  else
360  {
361  setOutputExtent( mCurrentExtent, mCurrentCrs, CurrentExtent );
362  }
363 }
364 
365 
367 {
368  setOutputExtent( mOriginalExtent, mOriginalCrs, OriginalExtent );
369 }
370 
372 {
373  setOutputExtent( extent, crs, UserExtent );
374 }
375 
377 {
378  if ( !layer )
379  return;
380 
381  mExtentLayer = layer;
382  mExtentLayerName = layer->name();
383 
384  setOutputExtent( layer->extent(), layer->crs(), ProjectLayerExtent );
385 }
386 
388 {
389  if ( mCanvas )
390  {
391  mMapToolPrevious = mCanvas->mapTool();
392  if ( !mMapToolExtent )
393  {
394  mMapToolExtent.reset( new QgsMapToolExtent( mCanvas ) );
395  connect( mMapToolExtent.get(), &QgsMapToolExtent::extentChanged, this, &QgsExtentWidget::extentDrawn );
396  connect( mMapToolExtent.get(), &QgsMapTool::deactivated, this, [ = ]
397  {
398  emit toggleDialogVisibility( true );
399  mMapToolPrevious = nullptr;
400  } );
401  }
402  mMapToolExtent->setRatio( mRatio );
403  mCanvas->setMapTool( mMapToolExtent.get() );
404 
405  emit toggleDialogVisibility( false );
406  }
407 }
408 
409 void QgsExtentWidget::extentDrawn( const QgsRectangle &extent )
410 {
411  setOutputExtent( extent, mCanvas->mapSettings().destinationCrs(), DrawOnCanvas );
412  mCanvas->setMapTool( mMapToolPrevious );
413  emit toggleDialogVisibility( true );
414  mMapToolPrevious = nullptr;
415 }
416 
418 {
419  return QgsRectangle( QgsDoubleValidator::toDouble( mXMinLineEdit->text() ), QgsDoubleValidator::toDouble( mYMinLineEdit->text() ),
420  QgsDoubleValidator::toDouble( mXMaxLineEdit->text() ), QgsDoubleValidator::toDouble( mYMaxLineEdit->text() ) );
421 }
422 
423 void QgsExtentWidget::setMapCanvas( QgsMapCanvas *canvas, bool drawOnCanvasOption )
424 {
425  if ( canvas )
426  {
427  mCanvas = canvas;
428  mButtonDrawOnCanvas->setVisible( drawOnCanvasOption );
429  mCurrentExtentButton->setVisible( true );
430 
431  mMenu->addAction( mUseCanvasExtentAction );
432  if ( drawOnCanvasOption )
433  mMenu->addAction( mDrawOnCanvasAction );
434  }
435  else
436  {
437  mButtonDrawOnCanvas->setVisible( false );
438  mCurrentExtentButton->setVisible( false );
439  mMenu->removeAction( mUseCanvasExtentAction );
440  mMenu->removeAction( mDrawOnCanvasAction );
441  }
442 }
443 
444 void QgsExtentWidget::dragEnterEvent( QDragEnterEvent *event )
445 {
446  if ( !( event->possibleActions() & Qt::CopyAction ) )
447  {
448  event->ignore();
449  return;
450  }
451 
452  if ( mapLayerFromMimeData( event->mimeData() ) )
453  {
454  // dragged an acceptable layer, phew
455  event->setDropAction( Qt::CopyAction );
456  event->accept();
457  mCondensedLineEdit->setHighlighted( true );
458  update();
459  }
460  else
461  {
462  event->ignore();
463  }
464 }
465 
466 void QgsExtentWidget::dragLeaveEvent( QDragLeaveEvent *event )
467 {
468  if ( mCondensedLineEdit->isHighlighted() )
469  {
470  event->accept();
471  mCondensedLineEdit->setHighlighted( false );
472  update();
473  }
474  else
475  {
476  event->ignore();
477  }
478 }
479 
480 void QgsExtentWidget::dropEvent( QDropEvent *event )
481 {
482  if ( !( event->possibleActions() & Qt::CopyAction ) )
483  {
484  event->ignore();
485  return;
486  }
487 
488  if ( QgsMapLayer *layer = mapLayerFromMimeData( event->mimeData() ) )
489  {
490  // dropped a map layer
491  setFocus( Qt::MouseFocusReason );
492  event->setDropAction( Qt::CopyAction );
493  event->accept();
494 
495  setOutputExtentFromLayer( layer );
496  }
497  else
498  {
499  event->ignore();
500  }
501  mCondensedLineEdit->setHighlighted( false );
502  update();
503 }
This class represents a coordinate reference system (CRS).
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Class for doing transforms between two map coordinate systems.
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.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
QgsCoordinateReferenceSystem currentCrs() const
Returns the coordinate reference system for the current extent set for the widget.
void setOutputExtentFromOriginal()
Sets the output extent to be the same as original extent (may be transformed to output CRS).
void setOutputExtentFromCurrent()
Sets the output extent to be the same as current extent (may be transformed to output CRS).
void setOutputExtentFromDrawOnCanvas()
Sets the output extent by dragging on the canvas.
void setOriginalExtent(const QgsRectangle &originalExtent, const QgsCoordinateReferenceSystem &originalCrs)
Sets the original extent and coordinate reference system for the widget.
void setCurrentExtent(const QgsRectangle &currentExtent, const QgsCoordinateReferenceSystem &currentCrs)
Sets the current extent to show in the widget - should be called as part of initialization (or whenev...
bool isValid() const
Returns true if the widget is in a valid state, i.e.
void toggleDialogVisibility(bool visible)
Emitted when the parent dialog visibility must be changed (e.g.
void setNullValueAllowed(bool allowed, const QString &notSetText=QString())
Sets whether the widget can be set to a "not set" (null) state.
QgsRectangle originalExtent() const
Returns the original extent set for the widget.
void dragEnterEvent(QDragEnterEvent *event) override
@ UserExtent
Extent manually entered/modified by the user.
@ OriginalExtent
Layer's extent.
@ ProjectLayerExtent
Extent taken from a layer within the project.
@ CurrentExtent
Map canvas extent.
@ DrawOnCanvas
Extent taken from a rectangled drawn onto the map canvas.
void validationChanged(bool valid)
Emitted when the widget's validation state changes.
void dropEvent(QDropEvent *event) override
void clear()
Clears the widget, setting it to a null value.
QgsCoordinateReferenceSystem outputCrs() const
Returns the current output CRS, used in the display.
void setMapCanvas(QgsMapCanvas *canvas, bool drawOnCanvasOption=true)
Sets the map canvas to enable dragging of extent on a canvas.
QgsRectangle currentExtent() const
Returns the current extent set for the widget.
void extentChanged(const QgsRectangle &r)
Emitted when the widget's extent is changed.
WidgetStyle
Widget styles.
@ CondensedStyle
Shows a compressed widget, for use when available space is minimal.
@ ExpandedStyle
Shows an expanded widget, for use when space is not constrained.
QgsExtentWidget(QWidget *parent=nullptr, WidgetStyle style=CondensedStyle)
Constructor for QgsExtentWidget.
QgsRectangle outputExtent() const
Returns the extent shown in the widget - in output CRS coordinates.
void dragLeaveEvent(QDragLeaveEvent *event) override
QgsCoordinateReferenceSystem originalCrs() const
Returns the original coordinate reference system set for the widget.
void setOutputCrs(const QgsCoordinateReferenceSystem &outputCrs)
Sets the output CRS - may need to be used for transformation from original/current extent.
void setOutputExtentFromLayer(const QgsMapLayer *layer)
Sets the output extent to match a layer's extent (may be transformed to output CRS).
void setOutputExtentFromUser(const QgsRectangle &extent, const QgsCoordinateReferenceSystem &crs)
Sets the output extent to a custom extent (may be transformed to output CRS).
QString extentLayerName() const
Returns the name of the extent layer.
void cleared()
Emitted when the widget is cleared.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:86
QgsMapTool * mapTool()
Returns the currently active tool.
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
The QgsMapLayerModel class is a model to display layers in widgets.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
@ LayerIdRole
Stores the map layer ID.
Base class for all map layer types.
Definition: qgsmaplayer.h:70
QString name
Definition: qgsmaplayer.h:73
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:76
The QgsMapSettings class contains configuration for rendering of the map.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
A map tool that emits an extent from a rectangle drawn onto the map canvas.
void extentChanged(const QgsRectangle &extent)
signal emitted on extent change
void deactivated()
signal emitted once the map tool is deactivated
QList< QgsMimeDataUtils::Uri > UriList
static UriList decodeUriList(const QMimeData *data)
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:467
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
@ DistanceMeters
Meters.
Definition: qgsunittypes.h:69
@ DistanceDegrees
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:75
@ DistanceKilometers
Kilometers.
Definition: qgsunittypes.h:70
@ DistanceMiles
Terrestrial miles.
Definition: qgsunittypes.h:74
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
@ DistanceMillimeters
Millimeters.
Definition: qgsunittypes.h:77
@ DistanceYards
Imperial yards.
Definition: qgsunittypes.h:73
@ DistanceFeet
Imperial feet.
Definition: qgsunittypes.h:71
@ DistanceNauticalMiles
Nautical miles.
Definition: qgsunittypes.h:72
@ DistanceCentimeters
Centimeters.
Definition: qgsunittypes.h:76
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:537
const QgsCoordinateReferenceSystem & outputCrs
const QgsCoordinateReferenceSystem & crs