QGIS API Documentation  2.14.0-Essen
qgsmaptoolcapture.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaptoolcapture.cpp - map tool for capturing points, lines, polygons
3  ---------------------
4  begin : January 2006
5  copyright : (C) 2006 by Martin Dobias
6  email : wonder.sk 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 "qgsmaptoolcapture.h"
17 
18 #include "qgscursors.h"
19 #include "qgsgeometryvalidator.h"
20 #include "qgslayertreeview.h"
21 #include "qgslinestringv2.h"
22 #include "qgslogger.h"
23 #include "qgsmapcanvas.h"
24 #include "qgsmapcanvastracer.h"
25 #include "qgsmapmouseevent.h"
26 #include "qgsmaprenderer.h"
27 #include "qgspolygonv2.h"
28 #include "qgsrubberband.h"
29 #include "qgsvectorlayer.h"
30 #include "qgsvertexmarker.h"
31 
32 #include <QCursor>
33 #include <QPixmap>
34 #include <QMouseEvent>
35 #include <QStatusBar>
36 
37 
39  : QgsMapToolAdvancedDigitizing( canvas, cadDockWidget )
40  , mRubberBand( nullptr )
41  , mTempRubberBand( nullptr )
42  , mValidator( nullptr )
43  , mSnappingMarker( nullptr )
44 #ifdef Q_OS_WIN
45  , mSkipNextContextMenuEvent( 0 )
46 #endif
47 {
49 
50  // enable the snapping on mouse move / release
51  mSnapOnMove = true;
52  mSnapOnRelease = true;
53  mSnapOnDoubleClick = false;
54  mSnapOnPress = false;
55 
56  mCaptureModeFromLayer = mode == CaptureNone;
57  mCapturing = false;
58 
59  QPixmap mySelectQPixmap = QPixmap(( const char ** ) capture_point_cursor );
60  setCursor( QCursor( mySelectQPixmap, 8, 8 ) );
61 
62  connect( canvas, SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
63  this, SLOT( currentLayerChanged( QgsMapLayer * ) ) );
64 }
65 
67 {
68  delete mSnappingMarker;
69 
70  stopCapturing();
71 
72  if ( mValidator )
73  {
74  mValidator->deleteLater();
75  mValidator = nullptr;
76  }
77 }
78 
80 {
81  if ( mTempRubberBand )
82  mTempRubberBand->show();
83 
85 }
86 
88 {
89  if ( mTempRubberBand )
90  mTempRubberBand->hide();
91 
92  delete mSnappingMarker;
93  mSnappingMarker = nullptr;
94 
96 }
97 
98 void QgsMapToolCapture::validationFinished()
99 {
100  emit messageDiscarded();
101  QString msgFinished = tr( "Validation finished" );
102  if ( !mValidationWarnings.isEmpty() )
103  {
104  emit messageEmitted( mValidationWarnings.join( "\n" ).append( "\n" ).append( msgFinished ), QgsMessageBar::WARNING );
105  }
106 }
107 
108 void QgsMapToolCapture::currentLayerChanged( QgsMapLayer *layer )
109 {
110  if ( !mCaptureModeFromLayer )
111  return;
112 
114 
115  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
116  if ( !vlayer )
117  {
118  return;
119  }
120 
121  switch ( vlayer->geometryType() )
122  {
123  case QGis::Point:
125  break;
126  case QGis::Line:
128  break;
129  case QGis::Polygon:
131  break;
132  default:
134  break;
135  }
136 }
137 
138 
139 bool QgsMapToolCapture::tracingEnabled()
140 {
142  return tracer && tracer->actionEnableTracing() && tracer->actionEnableTracing()->isChecked();
143 }
144 
145 
146 QgsPoint QgsMapToolCapture::tracingStartPoint()
147 {
148  try
149  {
150  QgsMapLayer* layer = mCanvas->currentLayer();
151  if ( !layer )
152  return QgsPoint();
153  QgsPointV2 v = mCaptureCurve.endPoint();
154  return toMapCoordinates( layer, QgsPoint( v.x(), v.y() ) );
155  }
156  catch ( QgsCsException & )
157  {
158  QgsDebugMsg( "transformation to layer coordinate failed" );
159  return QgsPoint();
160  }
161 }
162 
163 
164 bool QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent* e )
165 {
166  if ( !e->isSnapped() )
167  return false;
168 
169  QgsPoint pt0 = tracingStartPoint();
170  if ( pt0 == QgsPoint() )
171  return false;
172 
174  if ( !tracer )
175  return false; // this should not happen!
176 
177  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
178 
180  QVector<QgsPoint> points = tracer->findShortestPath( pt0, e->mapPoint(), &err );
181  if ( points.isEmpty() )
182  {
183  tracer->reportError( err, false );
184  return false;
185  }
186 
187  if ( mCaptureMode == CapturePolygon )
188  mTempRubberBand->addPoint( *mRubberBand->getPoint( 0, 0 ), false );
189 
190  // update rubberband
191  for ( int i = 0; i < points.count(); ++i )
192  mTempRubberBand->addPoint( points.at( i ), i == points.count() - 1 );
193 
194  tracer->reportError( QgsTracer::ErrNone, false ); // clear messagebar if there was any error
195  return true;
196 }
197 
198 
199 bool QgsMapToolCapture::tracingAddVertex( const QgsPoint& point )
200 {
202  if ( !tracer )
203  return false; // this should not happen!
204 
205  if ( mCaptureCurve.numPoints() == 0 )
206  {
207  if ( !tracer->init() )
208  {
210  return false;
211  }
212 
213  // only accept first point if it is snapped to the graph (to vertex or edge)
214  bool res = tracer->isPointSnapped( point );
215  if ( res )
216  {
217  QgsPointV2 layerPoint;
218  nextPoint( QgsPointV2( point ), layerPoint ); // assuming the transform went fine earlier
219 
220  mRubberBand->addPoint( point );
221  mCaptureCurve.addVertex( layerPoint );
222  }
223  return res;
224  }
225 
226  QgsPoint pt0 = tracingStartPoint();
227  if ( pt0 == QgsPoint() )
228  return false;
229 
231  QVector<QgsPoint> points = tracer->findShortestPath( pt0, point, &err );
232  if ( points.isEmpty() )
233  return false; // ignore the vertex - can't find path to the end point!
234 
235  // transform points
236  QgsPointSequenceV2 layerPoints;
237  QgsPointV2 lp; // in layer coords
238  for ( int i = 1; i < points.count(); ++i )
239  {
240  if ( nextPoint( QgsPointV2( points[i] ), lp ) != 0 )
241  return false;
242  layerPoints << lp;
243  }
244 
245  for ( int i = 1; i < points.count(); ++i )
246  {
247  if ( points[i] == points[i-1] )
248  continue; // avoid duplicate vertices if there are any
249  mRubberBand->addPoint( points[i], i == points.count() - 1 );
250  mCaptureCurve.addVertex( layerPoints[i-1] );
251  }
252 
253  tracer->reportError( QgsTracer::ErrNone, true ); // clear messagebar if there was any error
254  return true;
255 }
256 
257 
259 {
261  bool snapped = e->isSnapped();
262  QgsPoint point = e->mapPoint();
263 
264  if ( !snapped )
265  {
266  delete mSnappingMarker;
267  mSnappingMarker = nullptr;
268  }
269  else
270  {
271  if ( !mSnappingMarker )
272  {
273  mSnappingMarker = new QgsVertexMarker( mCanvas );
274  mSnappingMarker->setIconType( QgsVertexMarker::ICON_CROSS );
275  mSnappingMarker->setColor( Qt::magenta );
276  mSnappingMarker->setPenWidth( 3 );
277  }
278  mSnappingMarker->setCenter( point );
279  }
280 
281  if ( !mTempRubberBand && mCaptureCurve.numPoints() > 0 )
282  {
283  mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true );
284  QgsPointV2 pt = mCaptureCurve.endPoint();
285  mTempRubberBand->addPoint( QgsPoint( pt.x(), pt.y() ) );
286  mTempRubberBand->addPoint( point );
287  }
288 
289 
290  if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
291  {
292  bool hasTrace = false;
293  if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
294  {
295  hasTrace = tracingMouseMove( e );
296  }
297 
298  if ( !hasTrace )
299  {
300  if ( mCaptureCurve.numPoints() > 0 &&
301  (( mCaptureMode == CaptureLine && mTempRubberBand->numberOfVertices() != 2 ) ||
302  ( mCaptureMode == CapturePolygon && mTempRubberBand->numberOfVertices() != 3 ) ) )
303  {
304  // fix temporary rubber band after tracing which may have added multiple points
305  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
306  if ( mCaptureMode == CapturePolygon )
307  mTempRubberBand->addPoint( *mRubberBand->getPoint( 0, 0 ), false );
308  QgsPointV2 pt = mCaptureCurve.endPoint();
309  QgsPoint mapPt = toMapCoordinates( qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ), QgsPoint( pt.x(), pt.y() ) );
310  mTempRubberBand->addPoint( mapPt );
311  mTempRubberBand->addPoint( point );
312  }
313  else
314  mTempRubberBand->movePoint( point );
315  }
316  }
317 } // mouseMoveEvent
318 
319 int QgsMapToolCapture::nextPoint( const QgsPoint& mapPoint, QgsPoint& layerPoint )
320 {
321  QgsPointV2 p1( mapPoint.x(), mapPoint.y() );
322  QgsPointV2 p2;
323  int r = nextPoint( p1, p2 );
324  layerPoint.setX( p2.x() );
325  layerPoint.setY( p2.y() );
326  return r;
327 }
328 
329 int QgsMapToolCapture::nextPoint( const QgsPointV2& mapPoint, QgsPointV2& layerPoint )
330 {
331  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
332  if ( !vlayer )
333  {
334  QgsDebugMsg( "no vector layer" );
335  return 1;
336  }
337  try
338  {
339  QgsPoint mapP( mapPoint.x(), mapPoint.y() );
340  layerPoint = QgsPointV2( toLayerCoordinates( vlayer, mapP ) ); //transform snapped point back to layer crs
341  if ( QgsWKBTypes::hasZ( QGis::fromOldWkbType( vlayer->wkbType() ) ) )
342  layerPoint.addZValue( 0.0 );
343  if ( QgsWKBTypes::hasM( QGis::fromOldWkbType( vlayer->wkbType() ) ) )
344  layerPoint.addMValue( 0.0 );
345  }
346  catch ( QgsCsException &cse )
347  {
348  Q_UNUSED( cse );
349  QgsDebugMsg( "transformation to layer coordinate failed" );
350  return 2;
351  }
352 
353  return 0;
354 }
355 
357 {
358  mapPoint = QgsPointV2( toMapCoordinates( p ) );
359  return nextPoint( mapPoint, layerPoint );
360 }
361 
362 int QgsMapToolCapture::nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint )
363 {
364  mapPoint = toMapCoordinates( p );
366  return nextPoint( mapPoint, layerPoint );
368 }
369 
371 {
372  QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
373  QgsVectorLayer* sourceLayer = match.layer();
374  if ( match.isValid() && match.hasVertex() && sourceLayer &&
375  ( sourceLayer->crs() == vlayer->crs() ) )
376  {
377  QgsFeature f;
378  QgsFeatureRequest request;
379  request.setFilterFid( match.featureId() );
380  bool fetched = match.layer()->getFeatures( request ).nextFeature( f );
381  if ( fetched )
382  {
383  QgsVertexId vId;
384  if ( !f.geometry()->vertexIdFromVertexNr( match.vertexIndex(), vId ) )
385  return 2;
386  layerPoint = f.geometry()->geometry()->vertexAt( vId );
387  return 0;
388  }
389  else
390  {
391  return 2;
392  }
393  }
394  else
395  {
396  return 1;
397  }
398 }
399 
401 {
402  return addVertex( point, QgsPointLocator::Match() );
403 }
404 
406 {
407  if ( mode() == CaptureNone )
408  {
409  QgsDebugMsg( "invalid capture mode" );
410  return 2;
411  }
412 
413  int res;
414  QgsPointV2 layerPoint;
415  res = fetchLayerPoint( match, layerPoint );
416  if ( res != 0 )
417  {
418  res = nextPoint( QgsPointV2( point ), layerPoint );
419  if ( res != 0 )
420  {
421  return res;
422  }
423  }
424 
425  if ( !mRubberBand )
426  {
428  }
429 
430  if ( !mTempRubberBand )
431  {
432  mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true );
433  }
434  else
435  {
436  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
437  }
438 
439  bool traceCreated = false;
440  if ( tracingEnabled() )
441  {
442  traceCreated = tracingAddVertex( point );
443  }
444 
445  if ( !traceCreated )
446  {
447  // ordinary digitizing
448  mRubberBand->addPoint( point );
449  mCaptureCurve.addVertex( layerPoint );
450  }
451 
452  if ( mCaptureMode == CaptureLine )
453  {
454  mTempRubberBand->addPoint( point );
455  }
456  else if ( mCaptureMode == CapturePolygon )
457  {
458  const QgsPoint *firstPoint = mRubberBand->getPoint( 0, 0 );
459  mTempRubberBand->addPoint( *firstPoint );
460  mTempRubberBand->movePoint( point );
461  mTempRubberBand->addPoint( point );
462  }
463 
464  validateGeometry();
465 
466  return 0;
467 }
468 
470 {
471  if ( !c )
472  {
473  return 1;
474  }
475 
476  if ( !mRubberBand )
477  {
479  }
480 
481  QgsLineStringV2* lineString = c->curveToLine();
482  QgsPointSequenceV2 linePoints;
483  lineString->points( linePoints );
484  delete lineString;
486  for ( ; ptIt != linePoints.constEnd(); ++ptIt )
487  {
488  mRubberBand->addPoint( QgsPoint( ptIt->x(), ptIt->y() ) );
489  }
490 
491  if ( !mTempRubberBand )
492  {
493  mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true );
494  }
495  else
496  {
497  mTempRubberBand->reset();
498  }
499  QgsPointV2 endPt = c->endPoint();
500  mTempRubberBand->addPoint( QgsPoint( endPt.x(), endPt.y() ) ); //add last point of c
501 
502  //transform back to layer CRS in case map CRS and layer CRS are different
503  QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
504  const QgsCoordinateTransform* ct = mCanvas->mapSettings().layerTransform( vlayer );
505  if ( ct )
506  {
508  }
509  mCaptureCurve.addCurve( c );
510 
511  return 0;
512 }
513 
514 
516 {
517  if ( mRubberBand )
518  {
519  int rubberBandSize = mRubberBand->numberOfVertices();
520  int tempRubberBandSize = mTempRubberBand->numberOfVertices();
521  int captureListSize = size();
522 
523  if ( rubberBandSize < 1 || captureListSize < 1 )
524  {
525  return;
526  }
527 
528  mRubberBand->removePoint( -1 );
529 
530  if ( rubberBandSize > 1 )
531  {
532  if ( tempRubberBandSize > 1 )
533  {
534  const QgsPoint *point = mRubberBand->getPoint( 0, rubberBandSize - 2 );
535  mTempRubberBand->movePoint( tempRubberBandSize - 2, *point );
536  }
537  }
538  else
539  {
540  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line );
541  }
542 
543  QgsVertexId vertexToRemove;
544  vertexToRemove.part = 0;
545  vertexToRemove.ring = 0;
546  vertexToRemove.vertex = size() - 1;
547  mCaptureCurve.deleteVertex( vertexToRemove );
548 
549  validateGeometry();
550  }
551 }
552 
554 {
555  if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
556  {
557  undo();
558 
559  // Override default shortcut management in MapCanvas
560  e->ignore();
561  }
562  else if ( e->key() == Qt::Key_Escape )
563  {
564  stopCapturing();
565 
566  // Override default shortcut management in MapCanvas
567  e->ignore();
568  }
569 }
570 
572 {
573  mCapturing = true;
574 }
575 
577 {
578  return mCapturing;
579 }
580 
582 {
583  if ( mRubberBand )
584  {
585  delete mRubberBand;
586  mRubberBand = nullptr;
587  }
588 
589  if ( mTempRubberBand )
590  {
591  delete mTempRubberBand;
592  mTempRubberBand = nullptr;
593  }
594 
595  while ( !mGeomErrorMarkers.isEmpty() )
596  {
597  delete mGeomErrorMarkers.takeFirst();
598  }
599 
600  mGeomErrors.clear();
601 
602 #ifdef Q_OS_WIN
603  Q_FOREACH ( QWidget *w, qApp->topLevelWidgets() )
604  {
605  if ( w->objectName() == "QgisApp" )
606  {
607  if ( mSkipNextContextMenuEvent++ == 0 )
608  w->installEventFilter( this );
609  break;
610  }
611  }
612 #endif
613 
614  mCapturing = false;
615  mCaptureCurve.clear();
616  if ( currentVectorLayer() )
618 }
619 
621 {
622  if ( mTempRubberBand )
623  {
624  delete mTempRubberBand;
625  mTempRubberBand = nullptr;
626  }
627 }
628 
630 {
631  mCaptureCurve.close();
632 }
633 
634 void QgsMapToolCapture::validateGeometry()
635 {
636  QSettings settings;
637  if ( settings.value( "/qgis/digitizing/validate_geometries", 1 ).toInt() == 0 )
638  return;
639 
640  if ( mValidator )
641  {
642  mValidator->deleteLater();
643  mValidator = nullptr;
644  }
645 
646  mValidationWarnings.clear();
647  mGeomErrors.clear();
648  while ( !mGeomErrorMarkers.isEmpty() )
649  {
650  delete mGeomErrorMarkers.takeFirst();
651  }
652 
654 
655  switch ( mCaptureMode )
656  {
657  case CaptureNone:
658  case CapturePoint:
659  return;
660  case CaptureLine:
661  if ( size() < 2 )
662  return;
663  g.reset( new QgsGeometry( mCaptureCurve.curveToLine() ) );
664  break;
665  case CapturePolygon:
666  if ( size() < 3 )
667  return;
668  QgsLineStringV2* exteriorRing = mCaptureCurve.curveToLine();
669  exteriorRing->close();
670  QgsPolygonV2* polygon = new QgsPolygonV2();
671  polygon->setExteriorRing( exteriorRing );
672  g.reset( new QgsGeometry( polygon ) );
673  break;
674  }
675 
676  if ( !g.data() )
677  return;
678 
679  mValidator = new QgsGeometryValidator( g.data() );
680  connect( mValidator, SIGNAL( errorFound( QgsGeometry::Error ) ), this, SLOT( addError( QgsGeometry::Error ) ) );
681  connect( mValidator, SIGNAL( finished() ), this, SLOT( validationFinished() ) );
682  mValidator->start();
683  messageEmitted( tr( "Validation started" ) );
684 }
685 
686 void QgsMapToolCapture::addError( QgsGeometry::Error e )
687 {
688  mGeomErrors << e;
689  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
690  if ( !vlayer )
691  return;
692 
693  mValidationWarnings << e.what();
694 
695  if ( e.hasWhere() )
696  {
698  vm->setCenter( mCanvas->mapSettings().layerToMapCoordinates( vlayer, e.where() ) );
700  vm->setPenWidth( 2 );
701  vm->setToolTip( e.what() );
702  vm->setColor( Qt::green );
703  vm->setZValue( vm->zValue() + 1 );
704  mGeomErrorMarkers << vm;
705  }
706 
707  emit messageDiscarded();
708  emit messageEmitted( mValidationWarnings.join( "\n" ), QgsMessageBar::WARNING );
709 }
710 
712 {
713  return mCaptureCurve.numPoints();
714 }
715 
717 {
718  QgsPointSequenceV2 pts;
720  mCaptureCurve.points( pts );
721  QgsGeometry::convertPointList( pts, points );
722  return points;
723 }
724 
726 {
727  QgsPointSequenceV2 pts;
728  QgsGeometry::convertPointList( pointList, pts );
729 
730  QgsLineStringV2* line = new QgsLineStringV2();
731  line->setPoints( pts );
732 
733  mCaptureCurve.clear();
734  mCaptureCurve.addCurve( line );
735 }
736 
737 #ifdef Q_OS_WIN
739 {
740  if ( event->type() != QEvent::ContextMenu )
741  return false;
742 
743  if ( --mSkipNextContextMenuEvent == 0 )
744  obj->removeEventFilter( this );
745 
746  return mSkipNextContextMenuEvent >= 0;
747 }
748 #endif
virtual bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
void clear()
int addCurve(QgsCurveV2 *c)
Adds a whole curve (e.g.
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
Base class for all map layer types.
Definition: qgsmaplayer.h:49
QgsPoint layerToMapCoordinates(QgsMapLayer *theLayer, QgsPoint point) const
transform point coordinates from layer&#39;s CRS to output CRS
QString & append(QChar ch)
Type type() const
virtual QgsLineStringV2 * curveToLine() const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
QgsPoint mapPoint() const
mapPoint returns the point in coordinates
void close()
Appends first point if not already closed.
int size()
Number of points digitized.
double x() const
Returns the point&#39;s x-coordinate.
Definition: qgspointv2.h:68
const QgsCoordinateTransform * layerTransform(QgsMapLayer *layer) const
Return coordinate transform from layer&#39;s CRS to destination CRS.
void points(QgsPointSequenceV2 &pt) const override
Returns a list of points within the curve.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:703
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QgsAbstractGeometryV2 * geometry() const
Returns the underlying geometry store.
bool isChecked() const
virtual QgsPointV2 endPoint() const override
Returns the end point of the curve.
void movePoint(const QgsPoint &p, int geometryIndex=0)
Moves the rubber band point specified by index.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
const QgsPoint * getPoint(int i, int j=0) const
Return vertex.
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:407
void setPenWidth(int width)
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
QgsFeatureId featureId() const
virtual void activate() override
Registers this maptool with the cad dock widget.
int numberOfVertices() const
Returns count of vertices in all lists of mPoint.
QString join(const QString &separator) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:656
The QgsMapToolAdvancedDigitizing class is a QgsMapTool whcih gives event directly in map coordinates ...
bool mSnapOnDoubleClick
snap on double click
CaptureMode mode() const
The capture mode.
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:105
double x() const
Get the x value of the point.
Definition: qgspoint.h:128
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
void reset(T *other)
virtual bool event(QEvent *e)
double y() const
Returns the point&#39;s y-coordinate.
Definition: qgspointv2.h:74
Extension of QgsTracer that provides extra functionality:
void start(Priority priority)
QgsMapCanvas * mCanvas
pointer to map canvas
Definition: qgsmaptool.h:194
Polygon geometry type.
Definition: qgspolygonv2.h:29
static QgsWKBTypes::Type fromOldWkbType(QGis::WkbType type)
Converts from old (pre 2.10) WKB type (OGR) to new WKB type.
Definition: qgis.cpp:104
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
qreal zValue() const
void messageEmitted(const QString &message, QgsMessageBar::MessageLevel=QgsMessageBar::INFO)
emit a message
void ignore()
virtual void setExteriorRing(QgsCurveV2 *ring) override
Sets the exterior ring of the polygon.
void installEventFilter(QObject *filterObj)
static QgsMapCanvasTracer * tracerForCanvas(QgsMapCanvas *canvas)
Retrieve instance of this class associated with given canvas (if any).
QgsPoint toLayerCoordinates(QgsMapLayer *layer, QPoint point)
transformation from screen coordinates to layer&#39;s coordinates
Definition: qgsmaptool.cpp:54
int toInt(bool *ok) const
Utility class for identifying a unique vertex within a geometry.
Line string geometry type, with support for z-dimension and m-values.
Max feature count threshold was reached while reading features.
Definition: qgstracer.h:83
void addVertex(const QgsPointV2 &pt)
Adds a vertex to the end of the geometry.
void setPoints(const QgsPointSequenceV2 &points)
Resets the line string to match the specified list of points.
void removePoint(int index=0, bool doUpdate=true, int geometryIndex=0)
Remove a vertex from the rubberband and (optionally) update canvas.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspointv2.h:34
int vertexIndex() const
for vertex / edge match (first vertex of the edge)
bool isEmpty() const
void setToolTip(const QString &toolTip)
virtual void activate() override
active the tool
void setCenter(const QgsPoint &point)
PathError
Possible errors that may happen when calling findShortestPath()
Definition: qgstracer.h:80
void triggerRepaint()
Will advice the map canvas (and any other interested party) that this layer requires to be repainted...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void addPoint(const QgsPoint &p, bool doUpdate=true, int geometryIndex=0)
Add a vertex to the rubberband and update canvas.
void reset(QGis::GeometryType geometryType=QGis::Line)
Clears all the geometries in this rubberband.
QgsRubberBand * createRubberBand(QGis::GeometryType geometryType=QGis::Line, bool alternativeBand=false)
Creates a rubber band with the color/line width from the QGIS settings.
virtual void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform)=0
Transforms the geometry using a coordinate transform.
A class for marking vertices of features using e.g.
virtual bool eventFilter(QObject *watched, QEvent *event)
QGis::GeometryType geometryType() const
Returns point, line or polygon.
void deleteLater()
CaptureMode mCaptureMode
The capture mode in which this tool operates.
A class to represent a point.
Definition: qgspoint.h:65
void undo()
Removes the last vertex from mRubberBand and mCaptureList.
T * data() const
int key() const
void setX(double x)
Sets the x value of the point.
Definition: qgspoint.h:105
virtual void points(QgsPointSequenceV2 &pts) const override
Returns a list of points within the curve.
void setY(double y)
Sets the y value of the point.
Definition: qgspoint.h:113
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:76
void reportError(PathError err, bool addingVertex)
Report a path finding error to the user.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:408
const char * capture_point_cursor[]
Definition: qgscursors.cpp:87
bool vertexIdFromVertexNr(int nr, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsVectorLayer * layer() const
reference vector layer
QgsVectorLayer * currentVectorLayer()
Returns the current vector layer of the map canvas or 0.
void addCurve(QgsCurveV2 *c)
Adds a curve to the geometr (takes ownership)
void closePolygon()
Close an open polygon.
const T & at(int i) const
QVariant value(const QString &key, const QVariant &defaultValue) const
void deleteTempRubberBand()
Clean a temporary rubberband.
virtual QgsLineStringV2 * curveToLine() const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
virtual QgsPointV2 endPoint() const =0
Returns the end point of the curve.
virtual void deactivate() override
deactive the tool
void startCapturing()
Start capturing.
virtual void keyPressEvent(QKeyEvent *e) override
Intercept key events like Esc or Del to delete the last point.
QgsMapToolCapture(QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode=CaptureNone)
constructor
T takeFirst()
bool isSnapped() const
Returns true if there is a snapped point cached.
bool isEmpty() const
int count(const T &value) const
bool isPointSnapped(const QgsPoint &pt)
Find out whether the point is snapped to a vertex or edge (i.e. it can be used for tracing start/stop...
Definition: qgstracer.cpp:683
virtual ~QgsMapToolCapture()
destructor
Class for doing transforms between two map coordinate systems.
QList< QgsPoint > points()
List of digitized points.
int addVertex(const QgsPoint &point)
Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates) ...
void messageDiscarded()
emit signal to clear previous message
No error.
Definition: qgstracer.h:82
Q_DECL_DEPRECATED int nextPoint(const QgsPoint &mapPoint, QgsPoint &layerPoint)
Converts a map point to layer coordinates.
double y() const
Get the y value of the point.
Definition: qgspoint.h:136
const QgsCoordinateReferenceSystem & crs() const
Returns layer&#39;s spatial reference system.
virtual void cadCanvasMoveEvent(QgsMapMouseEvent *e)
Override this method when subclassing this class.
bool init()
Build the internal data structures.
Definition: qgstracer.cpp:596
virtual void setCursor(const QCursor &cursor)
Set a user defined cursor.
Definition: qgsmaptool.cpp:139
QgsPoint toMapCoordinates(QPoint point)
transformation from screen coordinates to map coordinates
Definition: qgsmaptool.cpp:42
void stopCapturing()
Stop capturing.
Custom exception class for Coordinate Reference System related exceptions.
const_iterator constEnd() const
bool nextFeature(QgsFeature &f)
const_iterator constBegin() const
virtual void cadCanvasMoveEvent(QgsMapMouseEvent *e) override
Update the rubberband according to mouse position.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
void setPoints(const QList< QgsPoint > &pointList)
Set the points on which to work.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
int fetchLayerPoint(QgsPointLocator::Match match, QgsPointV2 &layerPoint)
Fetches the original point from the source layer if it has the same CRS as the current layer...
The QgsAdvancedDigitizingDock class is a dockable widget used to handle the CAD tools on top of a sel...
void setColor(const QColor &color)
Represents a vector layer which manages a vector based data sets.
QAction * actionEnableTracing() const
Access to action that user may use to toggle tracing on/off. May be null if no action was associated...
bool isCapturing() const
Are we currently capturing?
virtual int numPoints() const override
Returns the number of points in the curve.
void setZValue(qreal z)
void setIconType(int iconType)
static void convertPointList(const QList< QgsPoint > &input, QgsPointSequenceV2 &output)
Upgrades a point list from QgsPoint to QgsPointV2.
void removeEventFilter(QObject *obj)
QVector< QgsPoint > findShortestPath(const QgsPoint &p1, const QgsPoint &p2, PathError *error=nullptr)
Given two points, find the shortest path and return points on the way.
Definition: qgstracer.cpp:640
virtual QgsPointV2 vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual void clear() override
Clears the geometry, ie reset it to a null geometry.
virtual void deactivate() override
Unregisters this maptool from the cad dock widget.