QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 #include "qgsexception.h"
18 #include "qgsfeatureiterator.h"
19 #include "qgsgeometryvalidator.h"
20 #include "qgslayertreeview.h"
21 #include "qgslinestring.h"
22 #include "qgslogger.h"
23 #include "qgsmapcanvas.h"
24 #include "qgsmapcanvastracer.h"
25 #include "qgsmapmouseevent.h"
26 #include "qgspolygon.h"
27 #include "qgsrubberband.h"
28 #include "qgssnapindicator.h"
29 #include "qgsvectorlayer.h"
30 #include "qgsvertexmarker.h"
31 #include "qgssettings.h"
32 #include "qgsapplication.h"
34 #include "qgsproject.h"
35 
36 #include <QAction>
37 #include <QCursor>
38 #include <QPixmap>
39 #include <QStatusBar>
40 
41 
43  : QgsMapToolAdvancedDigitizing( canvas, cadDockWidget )
44  , mCaptureMode( mode )
45  , mCaptureModeFromLayer( mode == CaptureNone )
46 {
47  mSnapIndicator.reset( new QgsSnapIndicator( canvas ) );
48 
49  setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CapturePoint ) );
50 
52  this, &QgsMapToolCapture::currentLayerChanged );
53 
54  QgsVectorLayer::LayerOptions layerOptions;
55  layerOptions.skipCrsValidation = true;
56  mExtraSnapLayer = new QgsVectorLayer( QStringLiteral( "LineString?crs=" ), QStringLiteral( "extra snap" ), QStringLiteral( "memory" ), layerOptions );
57  mExtraSnapLayer->startEditing();
58  QgsFeature f;
59  mExtraSnapLayer->addFeature( f );
60  mExtraSnapFeatureId = f.id();
61 
63  this, &QgsMapToolCapture::updateExtraSnapLayer );
64 
65  currentLayerChanged( canvas->currentLayer() );
66 }
67 
69 {
70  stopCapturing();
71 
72  if ( mValidator )
73  {
74  mValidator->deleteLater();
75  mValidator = nullptr;
76  }
77  mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
78  mExtraSnapLayer->deleteLater();
79  mExtraSnapLayer = nullptr;
80 }
81 
82 QgsMapToolCapture::Capabilities QgsMapToolCapture::capabilities() const
83 {
85 }
86 
88 {
89  if ( mTempRubberBand )
90  mTempRubberBand->show();
91 
92  mCanvas->snappingUtils()->addExtraSnapLayer( mExtraSnapLayer );
94 }
95 
97 {
98  if ( mTempRubberBand )
99  mTempRubberBand->hide();
100 
101  mSnapIndicator->setMatch( QgsPointLocator::Match() );
102 
103  mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
105 }
106 
107 void QgsMapToolCapture::currentLayerChanged( QgsMapLayer *layer )
108 {
109  if ( !mCaptureModeFromLayer )
110  return;
111 
112  mCaptureMode = CaptureNone;
113 
114  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
115  if ( !vlayer )
116  {
117  return;
118  }
119 
120  switch ( vlayer->geometryType() )
121  {
123  mCaptureMode = CapturePoint;
124  break;
126  mCaptureMode = CaptureLine;
127  break;
129  mCaptureMode = CapturePolygon;
130  break;
131  default:
132  mCaptureMode = CaptureNone;
133  break;
134  }
135 }
136 
137 
138 bool QgsMapToolCapture::tracingEnabled()
139 {
141  return tracer && ( !tracer->actionEnableTracing() || tracer->actionEnableTracing()->isChecked() )
142  && ( !tracer->actionEnableSnapping() || tracer->actionEnableSnapping()->isChecked() );
143 }
144 
145 
146 QgsPointXY QgsMapToolCapture::tracingStartPoint()
147 {
148  try
149  {
150  QgsMapLayer *layer = mCanvas->currentLayer();
151  if ( !layer )
152  return QgsPointXY();
153 
154  // if we have starting point from previous trace, then preferably use that one
155  // (useful when tracing with offset)
156  if ( mTracingStartPoint != QgsPointXY() )
157  return mTracingStartPoint;
158 
159  QgsPoint v = mCaptureCurve.endPoint();
160  return toMapCoordinates( layer, QgsPointXY( v.x(), v.y() ) );
161  }
162  catch ( QgsCsException & )
163  {
164  QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
165  return QgsPointXY();
166  }
167 }
168 
169 
170 bool QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent *e )
171 {
172  if ( !e->isSnapped() )
173  return false;
174 
175  QgsPointXY pt0 = tracingStartPoint();
176  if ( pt0 == QgsPointXY() )
177  return false;
178 
180  if ( !tracer )
181  return false; // this should not happen!
182 
183  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
184 
186  QVector<QgsPointXY> points = tracer->findShortestPath( pt0, e->mapPoint(), &err );
187  if ( points.isEmpty() )
188  {
189  tracer->reportError( err, false );
190  return false;
191  }
192 
193  if ( mCaptureMode == CapturePolygon )
194  mTempRubberBand->addPoint( *mRubberBand->getPoint( 0, 0 ), false );
195 
196  // if there is offset, we need to fix the rubber bands to make sure they are aligned correctly.
197  // There are two cases we need to sort out:
198  // 1. the last point of mRubberBand may need to be moved off the traced curve to respect the offset
199  // 2. extra first point of mTempRubberBand may be needed if there is gap between where mRubberBand ends and trace starts
200  if ( mRubberBand->numberOfVertices() != 0 )
201  {
202  QgsPointXY lastPoint = *mRubberBand->getPoint( 0, mRubberBand->numberOfVertices() - 1 );
203  if ( lastPoint == pt0 && points[0] != lastPoint )
204  {
205  // if rubber band had just one point, for some strange reason it contains the point twice
206  // we only want to move the last point if there are multiple points already
207  if ( mRubberBand->numberOfVertices() > 2 || ( mRubberBand->numberOfVertices() == 2 && *mRubberBand->getPoint( 0, 0 ) != *mRubberBand->getPoint( 0, 1 ) ) )
208  mRubberBand->movePoint( points[0] );
209  }
210  else
211  {
212  mTempRubberBand->addPoint( lastPoint, false );
213  }
214  }
215 
216  // update rubberband
217  for ( int i = 0; i < points.count(); ++i )
218  mTempRubberBand->addPoint( points.at( i ), i == points.count() - 1 );
219 
220  tracer->reportError( QgsTracer::ErrNone, false ); // clear messagebar if there was any error
221  return true;
222 }
223 
224 
225 bool QgsMapToolCapture::tracingAddVertex( const QgsPointXY &point )
226 {
228  if ( !tracer )
229  return false; // this should not happen!
230 
231  if ( mCaptureCurve.numPoints() == 0 )
232  {
233  if ( !tracer->init() )
234  {
236  return false;
237  }
238 
239  // only accept first point if it is snapped to the graph (to vertex or edge)
240  bool res = tracer->isPointSnapped( point );
241  if ( res )
242  {
243  QgsPoint layerPoint;
244  nextPoint( QgsPoint( point ), layerPoint ); // assuming the transform went fine earlier
245 
246  mRubberBand->addPoint( point );
247  mCaptureCurve.addVertex( layerPoint );
248  mSnappingMatches.append( QgsPointLocator::Match() );
249  }
250  return res;
251  }
252 
253  QgsPointXY pt0 = tracingStartPoint();
254  if ( pt0 == QgsPointXY() )
255  return false;
256 
258  QVector<QgsPointXY> points = tracer->findShortestPath( pt0, point, &err );
259  if ( points.isEmpty() )
260  return false; // ignore the vertex - can't find path to the end point!
261 
262  if ( !mCaptureCurve.isEmpty() )
263  {
264  QgsPoint lp; // in layer coords
265  if ( nextPoint( QgsPoint( pt0 ), lp ) != 0 )
266  return false;
267  QgsPoint last;
269  mCaptureCurve.pointAt( mCaptureCurve.numPoints() - 1, last, type );
270  if ( last == lp )
271  {
272  // remove the last point in the curve if it is the same as our first point
273  if ( mCaptureCurve.numPoints() != 2 )
274  mCaptureCurve.deleteVertex( QgsVertexId( 0, 0, mCaptureCurve.numPoints() - 1 ) );
275  else
276  {
277  // there is a strange behavior in deleteVertex() that with just two points
278  // the whole curve is cleared - so we need to do this little dance to work it around
279  QgsPoint first = mCaptureCurve.startPoint();
280  mCaptureCurve.clear();
281  mCaptureCurve.addVertex( first );
282  }
283  // for unknown reasons, rubber band has 2 points even if only one point has been added - handle that case
284  if ( mRubberBand->numberOfVertices() == 2 && *mRubberBand->getPoint( 0, 0 ) == *mRubberBand->getPoint( 0, 1 ) )
285  mRubberBand->removeLastPoint();
286  mRubberBand->removeLastPoint();
287  mSnappingMatches.removeLast();
288  }
289  }
290 
291  // transform points
292  QgsPointSequence layerPoints;
293  QgsPoint lp; // in layer coords
294  for ( int i = 0; i < points.count(); ++i )
295  {
296  if ( nextPoint( QgsPoint( points[i] ), lp ) != 0 )
297  return false;
298  layerPoints << lp;
299  }
300 
301  for ( int i = 0; i < points.count(); ++i )
302  {
303  if ( i == 0 && !mCaptureCurve.isEmpty() && mCaptureCurve.endPoint() == layerPoints[0] )
304  continue; // avoid duplicate of the first vertex
305  if ( i > 0 && points[i] == points[i - 1] )
306  continue; // avoid duplicate vertices if there are any
307  mRubberBand->addPoint( points[i], i == points.count() - 1 );
308  mCaptureCurve.addVertex( layerPoints[i] );
309  mSnappingMatches.append( QgsPointLocator::Match() );
310  }
311 
312  // Curves de-approximation
313  QgsSettings settings;
314  if ( settings.value( QStringLiteral( "/qgis/digitizing/convert_to_curve" ), false ).toBool() )
315  {
316  // If the tool and the layer support curves
317  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
318  if ( capabilities().testFlag( QgsMapToolCapture::Capability::SupportsCurves ) && vlayer->dataProvider()->capabilities().testFlag( QgsVectorDataProvider::Capability::CircularGeometries ) )
319  {
320  QgsGeometry linear = QgsGeometry( mCaptureCurve.segmentize() );
321  QgsGeometry curved = linear.convertToCurves();
322  mCaptureCurve = *qgsgeometry_cast<QgsCompoundCurve *>( curved.constGet() );
323  }
324  }
325 
326  tracer->reportError( QgsTracer::ErrNone, true ); // clear messagebar if there was any error
327  return true;
328 }
329 
330 
332 {
333  return mRubberBand.release();
334 }
335 
336 
338 {
340  QgsPointXY point = e->mapPoint();
341 
342  mSnapIndicator->setMatch( e->mapPointMatch() );
343 
344  if ( !mTempRubberBand && mCaptureCurve.numPoints() > 0 )
345  {
346  mTempRubberBand.reset( createRubberBand( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ) );
347  QgsPoint pt = mCaptureCurve.endPoint();
348  mTempRubberBand->addPoint( QgsPointXY( pt.x(), pt.y() ) );
349  mTempRubberBand->addPoint( point );
350  }
351 
352 
353  if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
354  {
355  bool hasTrace = false;
356  if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
357  {
358  hasTrace = tracingMouseMove( e );
359  }
360 
361  if ( !hasTrace )
362  {
363  if ( mCaptureCurve.numPoints() > 0 )
364  {
365  // fix temporary rubber band after tracing which may have added multiple points
366  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
367  if ( mCaptureMode == CapturePolygon )
368  mTempRubberBand->addPoint( *mRubberBand->getPoint( 0, 0 ), false );
369  QgsPoint pt = mCaptureCurve.endPoint();
370  QgsPointXY mapPt = toMapCoordinates( qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ), QgsPointXY( pt.x(), pt.y() ) );
371  mTempRubberBand->addPoint( mapPt );
372  mTempRubberBand->addPoint( point );
373 
374  // fix existing rubber band after tracing - the last point may have been moved if using offset
375  if ( mRubberBand->numberOfVertices() )
376  mRubberBand->movePoint( mapPt );
377  }
378  else
379  mTempRubberBand->movePoint( point );
380  }
381  }
382 } // mouseMoveEvent
383 
384 
385 int QgsMapToolCapture::nextPoint( const QgsPoint &mapPoint, QgsPoint &layerPoint )
386 {
387  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
388  if ( !vlayer )
389  {
390  QgsDebugMsg( QStringLiteral( "no vector layer" ) );
391  return 1;
392  }
393  try
394  {
395  QgsPointXY mapP( mapPoint.x(), mapPoint.y() ); //#spellok
396  layerPoint = QgsPoint( toLayerCoordinates( vlayer, mapP ) ); //transform snapped point back to layer crs //#spellok
397  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) )
398  layerPoint.addZValue( defaultZValue() );
399  if ( QgsWkbTypes::hasM( vlayer->wkbType() ) )
400  layerPoint.addMValue( 0.0 );
401  }
402  catch ( QgsCsException &cse )
403  {
404  Q_UNUSED( cse )
405  QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
406  return 2;
407  }
408 
409  return 0;
410 }
411 
412 int QgsMapToolCapture::nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint )
413 {
415  return nextPoint( mapPoint, layerPoint );
416 }
417 
419 {
420  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
421  QgsVectorLayer *sourceLayer = match.layer();
422  if ( match.isValid() && ( match.hasVertex() || ( QgsProject::instance()->topologicalEditing() && match.hasEdge() ) ) && sourceLayer &&
423  ( sourceLayer->crs() == vlayer->crs() ) )
424  {
425  QgsFeature f;
426  QgsFeatureRequest request;
427  request.setFilterFid( match.featureId() );
428  bool fetched = match.layer()->getFeatures( request ).nextFeature( f );
429  if ( fetched )
430  {
431  QgsVertexId vId;
432  if ( !f.geometry().vertexIdFromVertexNr( match.vertexIndex(), vId ) )
433  return 2;
434 
435  const QgsGeometry geom( f.geometry() );
436  if ( QgsProject::instance()->topologicalEditing() && match.hasEdge() )
437  {
438  QgsVertexId vId2;
439  if ( !f.geometry().vertexIdFromVertexNr( match.vertexIndex() + 1, vId2 ) )
440  return 2;
441  QgsLineString line( geom.constGet()->vertexAt( vId ), geom.constGet()->vertexAt( vId2 ) );
442 
443  layerPoint = QgsGeometryUtils::closestPoint( line, QgsPoint( match.point() ) );
444  }
445  else
446  {
447  layerPoint = geom.constGet()->vertexAt( vId );
448  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) && !layerPoint.is3D() )
449  layerPoint.addZValue( defaultZValue() );
450  if ( QgsWkbTypes::hasM( vlayer->wkbType() ) && !layerPoint.isMeasure() )
451  layerPoint.addMValue( 0.0 );
452  }
453 
454  // ZM support depends on the target layer
455  if ( !QgsWkbTypes::hasZ( vlayer->wkbType() ) )
456  {
457  layerPoint.dropZValue();
458  }
459 
460  if ( !QgsWkbTypes::hasM( vlayer->wkbType() ) )
461  {
462  layerPoint.dropMValue();
463  }
464 
465  return 0;
466  }
467  else
468  {
469  return 2;
470  }
471  }
472  else
473  {
474  return 1;
475  }
476 }
477 
479 {
480  return addVertex( point, QgsPointLocator::Match() );
481 }
482 
484 {
485  if ( mode() == CaptureNone )
486  {
487  QgsDebugMsg( QStringLiteral( "invalid capture mode" ) );
488  return 2;
489  }
490 
491  int res;
492  QgsPoint layerPoint;
493  res = fetchLayerPoint( match, layerPoint );
494  if ( res != 0 )
495  {
496  res = nextPoint( QgsPoint( point ), layerPoint );
497  if ( res != 0 )
498  {
499  return res;
500  }
501  }
502 
503  if ( !mRubberBand )
504  {
506  }
507 
508  if ( !mTempRubberBand )
509  {
510  mTempRubberBand.reset( createRubberBand( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ) );
511  }
512  else
513  {
514  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
515  }
516 
517  bool traceCreated = false;
518  if ( tracingEnabled() )
519  {
520  traceCreated = tracingAddVertex( point );
521  }
522 
523  // keep new tracing start point if we created a trace. This is useful when tracing with
524  // offset so that the user stays "snapped"
525  mTracingStartPoint = traceCreated ? point : QgsPointXY();
526 
527  if ( !traceCreated )
528  {
529  // ordinary digitizing
530  mRubberBand->addPoint( point );
531  mCaptureCurve.addVertex( layerPoint );
532  mSnappingMatches.append( match );
533  }
534 
535  if ( mCaptureMode == CaptureLine )
536  {
537  mTempRubberBand->addPoint( point );
538  }
539  else if ( mCaptureMode == CapturePolygon )
540  {
541  const QgsPointXY *firstPoint = mRubberBand->getPoint( 0, 0 );
542  mTempRubberBand->addPoint( *firstPoint );
543  mTempRubberBand->movePoint( point );
544  mTempRubberBand->addPoint( point );
545  }
546 
547  updateExtraSnapLayer();
548  validateGeometry();
549 
550  return 0;
551 }
552 
554 {
555  if ( !c )
556  {
557  return 1;
558  }
559 
560  if ( !mRubberBand )
561  {
563  }
564 
565  QgsLineString *lineString = c->curveToLine();
566  QgsPointSequence linePoints;
567  lineString->points( linePoints );
568  delete lineString;
569  QgsPointSequence::const_iterator ptIt = linePoints.constBegin();
570  for ( ; ptIt != linePoints.constEnd(); ++ptIt )
571  {
572  mRubberBand->addPoint( QgsPointXY( ptIt->x(), ptIt->y() ) );
573  }
574 
575  if ( !mTempRubberBand )
576  {
577  mTempRubberBand.reset( createRubberBand( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ) );
578  }
579  else
580  {
581  mTempRubberBand->reset();
582  }
583  QgsPoint endPt = c->endPoint();
584  mTempRubberBand->addPoint( QgsPointXY( endPt.x(), endPt.y() ) ); //add last point of c
585 
586  //transform back to layer CRS in case map CRS and layer CRS are different
587  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
589  if ( ct.isValid() )
590  {
592  }
593  mCaptureCurve.addCurve( c );
594  updateExtraSnapLayer();
595  for ( int i = 0; i < c->length(); ++i )
596  mSnappingMatches.append( QgsPointLocator::Match() );
597 
598  return 0;
599 }
600 
602 {
603  mCaptureCurve.clear();
604  updateExtraSnapLayer();
605 }
606 
607 QList<QgsPointLocator::Match> QgsMapToolCapture::snappingMatches() const
608 {
609  return mSnappingMatches;
610 }
611 
612 
614 {
615  mTracingStartPoint = QgsPointXY();
616 
617  if ( mRubberBand )
618  {
619  int rubberBandSize = mRubberBand->numberOfVertices();
620  int tempRubberBandSize = mTempRubberBand->numberOfVertices();
621  int captureListSize = size();
622 
623  if ( rubberBandSize < 1 || captureListSize < 1 )
624  {
625  return;
626  }
627 
628  mRubberBand->removePoint( -1 );
629 
630  if ( rubberBandSize > 1 )
631  {
632  if ( tempRubberBandSize > 1 )
633  {
634  const QgsPointXY *point = mRubberBand->getPoint( 0, rubberBandSize - 2 );
635  mTempRubberBand->movePoint( tempRubberBandSize - 2, *point );
636  }
637  }
638  else
639  {
640  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
641  }
642 
643  QgsVertexId vertexToRemove;
644  vertexToRemove.part = 0;
645  vertexToRemove.ring = 0;
646  vertexToRemove.vertex = size() - 1;
647  mCaptureCurve.deleteVertex( vertexToRemove );
648  mSnappingMatches.removeAt( vertexToRemove.vertex );
649  updateExtraSnapLayer();
650 
652 
653  validateGeometry();
654  }
655 }
656 
658 {
659  if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
660  {
661  undo();
662 
663  // Override default shortcut management in MapCanvas
664  e->ignore();
665  }
666  else if ( e->key() == Qt::Key_Escape )
667  {
668  stopCapturing();
669 
670  // Override default shortcut management in MapCanvas
671  e->ignore();
672  }
673 }
674 
676 {
677  mCapturing = true;
678 }
679 
681 {
682  return mCapturing;
683 }
684 
686 {
687  mRubberBand.reset();
688 
690 
691  qDeleteAll( mGeomErrorMarkers );
692  mGeomErrorMarkers.clear();
693  mGeomErrors.clear();
694 
695  mTracingStartPoint = QgsPointXY();
696 
697  mCapturing = false;
698  mCaptureCurve.clear();
699  updateExtraSnapLayer();
700  mSnappingMatches.clear();
701  if ( currentVectorLayer() )
703 }
704 
706 {
707  mTempRubberBand.reset();
708 }
709 
711 {
712  stopCapturing();
713  clearCurve();
714 }
715 
717 {
718  mCaptureCurve.close();
719  updateExtraSnapLayer();
720 }
721 
722 void QgsMapToolCapture::validateGeometry()
723 {
724  QgsSettings settings;
725  if ( settings.value( QStringLiteral( "qgis/digitizing/validate_geometries" ), 1 ).toInt() == 0 )
726  return;
727 
728  if ( mValidator )
729  {
730  mValidator->deleteLater();
731  mValidator = nullptr;
732  }
733 
734  mGeomErrors.clear();
735  while ( !mGeomErrorMarkers.isEmpty() )
736  {
737  delete mGeomErrorMarkers.takeFirst();
738  }
739 
740  QgsGeometry geom;
741 
742  switch ( mCaptureMode )
743  {
744  case CaptureNone:
745  case CapturePoint:
746  return;
747  case CaptureLine:
748  if ( size() < 2 )
749  return;
750  geom = QgsGeometry( mCaptureCurve.curveToLine() );
751  break;
752  case CapturePolygon:
753  if ( size() < 3 )
754  return;
755  QgsLineString *exteriorRing = mCaptureCurve.curveToLine();
756  exteriorRing->close();
757  QgsPolygon *polygon = new QgsPolygon();
758  polygon->setExteriorRing( exteriorRing );
759  geom = QgsGeometry( polygon );
760  break;
761  }
762 
763  if ( geom.isNull() )
764  return;
765 
767  if ( settings.value( QStringLiteral( "qgis/digitizing/validate_geometries" ), 1 ).toInt() == 2 )
769  mValidator = new QgsGeometryValidator( geom, nullptr, method );
770  connect( mValidator, &QgsGeometryValidator::errorFound, this, &QgsMapToolCapture::addError );
771  mValidator->start();
772  QgsDebugMsgLevel( QStringLiteral( "Validation started" ), 4 );
773 }
774 
775 void QgsMapToolCapture::addError( const QgsGeometry::Error &e )
776 {
777  mGeomErrors << e;
778  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
779  if ( !vlayer )
780  return;
781 
782  if ( e.hasWhere() )
783  {
785  vm->setCenter( mCanvas->mapSettings().layerToMapCoordinates( vlayer, e.where() ) );
787  vm->setPenWidth( 2 );
788  vm->setToolTip( e.what() );
789  vm->setColor( Qt::green );
790  vm->setZValue( vm->zValue() + 1 );
791  mGeomErrorMarkers << vm;
792  }
793 }
794 
796 {
797  return mCaptureCurve.numPoints();
798 }
799 
800 QVector<QgsPointXY> QgsMapToolCapture::points() const
801 {
802  QVector<QgsPointXY> pointsXY;
804 
805  return pointsXY;
806 }
807 
809 {
810  QgsPointSequence pts;
811  mCaptureCurve.points( pts );
812  return pts;
813 }
814 
815 void QgsMapToolCapture::setPoints( const QVector<QgsPointXY> &pointList )
816 {
817  QgsLineString *line = new QgsLineString( pointList );
818  mCaptureCurve.clear();
819  mCaptureCurve.addCurve( line );
820  updateExtraSnapLayer();
821  mSnappingMatches.clear();
822  for ( int i = 0; i < line->length(); ++i )
823  mSnappingMatches.append( QgsPointLocator::Match() );
824 }
825 
827 {
828  QgsLineString *line = new QgsLineString( pointList );
829  mCaptureCurve.clear();
830  mCaptureCurve.addCurve( line );
831  updateExtraSnapLayer();
832  mSnappingMatches.clear();
833  for ( int i = 0; i < line->length(); ++i )
834  mSnappingMatches.append( QgsPointLocator::Match() );
835 }
836 
838 {
839  QgsPoint newPoint( QgsWkbTypes::Point, point.x(), point.y() );
840 
841  // get current layer
842  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
843  if ( !vlayer )
844  {
845  return newPoint;
846  }
847 
848  // convert to the corresponding type for a full ZM support
849  const QgsWkbTypes::Type type = vlayer->wkbType();
850  if ( QgsWkbTypes::hasZ( type ) && !QgsWkbTypes::hasM( type ) )
851  {
852  newPoint.convertTo( QgsWkbTypes::PointZ );
853  }
854  else if ( !QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
855  {
856  newPoint.convertTo( QgsWkbTypes::PointM );
857  }
858  else if ( QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
859  {
860  newPoint.convertTo( QgsWkbTypes::PointZM );
861  }
862 
863  // set z value if necessary
864  if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) )
865  {
866  newPoint.setZ( defaultZValue() );
867  }
868 
869  return newPoint;
870 }
871 
873 {
874  QgsPoint newPoint = mapPoint( e.mapPoint() );
875 
876  // set z value from snapped point if necessary
877  if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) )
878  {
879  // if snapped, z dimension is taken from the corresponding snapped
880  // point.
881  if ( e.isSnapped() )
882  {
883  const QgsPointLocator::Match match = e.mapPointMatch();
884 
885  if ( match.layer() && QgsWkbTypes::hasZ( match.layer()->wkbType() ) )
886  {
887  const QgsFeature ft = match.layer()->getFeature( match.featureId() );
888  newPoint.setZ( ft.geometry().vertexAt( match.vertexIndex() ).z() );
889  }
890  }
891  }
892 
893  return newPoint;
894 }
895 
896 void QgsMapToolCapture::updateExtraSnapLayer()
897 {
898  if ( canvas()->snappingUtils()->config().selfSnapping() && mCanvas->currentLayer() && mCaptureCurve.numPoints() >= 2 )
899  {
900  // the current layer may have changed
901  mExtraSnapLayer->setCrs( mCanvas->currentLayer()->crs() );
902  QgsGeometry geom = QgsGeometry( mCaptureCurve.clone() );
903  // we close the curve to allow snapping on last segment
904  if ( mCaptureMode == CapturePolygon && mCaptureCurve.numPoints() >= 3 )
905  {
906  qgsgeometry_cast<QgsCompoundCurve *>( geom.get() )->close();
907  }
908  mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
909  }
910  else
911  {
912  QgsGeometry geom;
913  mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
914  }
915 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
qgspolygon.h
QgsMapTool::mCanvas
QgsMapCanvas * mCanvas
pointer to map canvas
Definition: qgsmaptool.h:259
QgsVertexId::part
int part
Definition: qgsabstractgeometry.h:1080
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:993
QgsGeometry::ValidatorGeos
@ ValidatorGeos
Use GEOS validation methods.
Definition: qgsgeometry.h:2071
QgsMapToolCapture::clearCurve
void clearCurve()
Clear capture curve.
Definition: qgsmaptoolcapture.cpp:601
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:88
QgsMapCanvas::currentLayerChanged
void currentLayerChanged(QgsMapLayer *layer)
Emitted when the current layer is changed.
QgsMapToolCapture::QgsMapToolCapture
QgsMapToolCapture(QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode)
constructor
Definition: qgsmaptoolcapture.cpp:42
QgsVertexId::vertex
int vertex
Definition: qgsabstractgeometry.h:1082
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsAdvancedDigitizingDockWidget::removePreviousPoint
void removePreviousPoint()
Remove previous point in the CAD point list.
Definition: qgsadvanceddigitizingdockwidget.cpp:1164
QgsRubberBand::removePoint
void removePoint(int index=0, bool doUpdate=true, int geometryIndex=0, int ringIndex=0)
Removes a vertex from the rubberband and (optionally) updates canvas.
Definition: qgsrubberband.cpp:191
QObjectUniquePtr::reset
void reset(T *p=nullptr)
Will reset the managed pointer to p.
Definition: qobjectuniqueptr.h:176
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:189
QgsVectorLayer::wkbType
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Definition: qgsvectorlayer.cpp:664
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:71
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
QgsMapMouseEvent::mapPoint
QgsPointXY mapPoint() const
mapPoint returns the point in coordinates
Definition: qgsmapmouseevent.h:88
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:33
qgslinestring.h
QgsMapToolCapture::NoCapabilities
@ NoCapabilities
No specific capabilities.
Definition: qgsmaptoolcapture.h:59
QgsMapSettings::layerTransform
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
Definition: qgsmapsettings.cpp:418
QgsCompoundCurve::endPoint
QgsPoint endPoint() const override
Returns the end point of the curve.
Definition: qgscompoundcurve.cpp:331
QgsVertexMarker::setIconType
void setIconType(int iconType)
Definition: qgsvertexmarker.cpp:25
QgsMapToolAdvancedDigitizing::mCadDockWidget
QgsAdvancedDigitizingDockWidget * mCadDockWidget
Definition: qgsmaptooladvanceddigitizing.h:111
QgsTracer::findShortestPath
QVector< QgsPointXY > findShortestPath(const QgsPointXY &p1, const QgsPointXY &p2, PathError *error=nullptr)
Given two points, find the shortest path and return points on the way.
Definition: qgstracer.cpp:738
qgsmapcanvas.h
QgsSnappingUtils::addExtraSnapLayer
void addExtraSnapLayer(QgsVectorLayer *vl)
Supply an extra snapping layer (typically a memory layer).
Definition: qgssnappingutils.h:200
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsPoint::addZValue
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:511
QgsMapToolCapture::CaptureMode
CaptureMode
Different capture modes.
Definition: qgsmaptoolcapture.h:48
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:390
QgsRubberBand::removeLastPoint
void removeLastPoint(int geometryIndex=0, bool doUpdate=true, int ringIndex=0)
Removes the last point.
Definition: qgsrubberband.cpp:218
QgsTracer::init
bool init()
Build the internal data structures.
Definition: qgstracer.cpp:677
QgsRubberBand
Definition: qgsrubberband.h:49
QgsMapToolCapture::addVertex
int addVertex(const QgsPointXY &point)
Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates)
Definition: qgsmaptoolcapture.cpp:478
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:635
QgsPolygon::setExteriorRing
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
Definition: qgspolygon.cpp:214
qgsfeatureiterator.h
QgsCompoundCurve::addCurve
void addCurve(QgsCurve *c)
Adds a curve to the geometry (takes ownership)
Definition: qgscompoundcurve.cpp:457
QgsMapTool::setCursor
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:149
QgsMapCanvas
Definition: qgsmapcanvas.h:83
QgsMapToolAdvancedDigitizing::activate
void activate() override
Registers this maptool with the cad dock widget.
Definition: qgsmaptooladvanceddigitizing.cpp:121
QgsGeometry::Error
Definition: qgsgeometry.h:2014
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsPoint::z
double z
Definition: qgspoint.h:60
QgsRubberBand::getPoint
const QgsPointXY * getPoint(int i, int j=0, int ringIndex=0) const
Returns a vertex.
Definition: qgsrubberband.cpp:673
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
QgsCompoundCurve::curveToLine
QgsLineString * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve.
Definition: qgscompoundcurve.cpp:388
QgsCompoundCurve::close
void close()
Appends first point if not already closed.
Definition: qgscompoundcurve.cpp:825
QgsGeometryUtils::closestPoint
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
Definition: qgsgeometryutils.cpp:101
QgsMapToolCapture::mode
CaptureMode mode() const
The capture mode.
Definition: qgsmaptoolcapture.h:83
QgsSettings
Definition: qgssettings.h:61
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsVectorLayer::startEditing
Q_INVOKABLE bool startEditing()
Makes the layer editable.
Definition: qgsvectorlayer.cpp:1411
QgsWkbTypes::hasZ
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1042
QgsMapToolCapture::size
int size()
Number of points digitized.
Definition: qgsmaptoolcapture.cpp:795
QgsMapTool::canvas
QgsMapCanvas * canvas() const
returns pointer to the tool's map canvas
Definition: qgsmaptool.cpp:198
QgsPointLocator::Match::point
QgsPointXY point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords,...
Definition: qgspointlocator.h:228
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:43
QgsCoordinateTransform::isValid
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Definition: qgscoordinatetransform.cpp:876
QgsRubberBand::movePoint
void movePoint(const QgsPointXY &p, int geometryIndex=0, int ringIndex=0)
Moves the rubber band point specified by index.
Definition: qgsrubberband.cpp:223
QgsMapLayer::setCrs
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Definition: qgsmaplayer.cpp:769
QgsCoordinateTransform::ReverseTransform
@ ReverseTransform
Transform from destination to source CRS.
Definition: qgscoordinatetransform.h:61
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
QgsMapToolEdit::currentVectorLayer
QgsVectorLayer * currentVectorLayer()
Returns the current vector layer of the map canvas or 0.
Definition: qgsmaptooledit.cpp:89
QgsPointLocator::Match::hasVertex
bool hasVertex() const
Returns true if the Match is a vertex.
Definition: qgspointlocator.h:208
qgssnapindicator.h
QgsSnapIndicator
Definition: qgssnapindicator.h:32
QgsMapCanvasTracer::actionEnableTracing
QAction * actionEnableTracing() const
Access to action that user may use to toggle tracing on/off. May be nullptr if no action was associat...
Definition: qgsmapcanvastracer.h:51
QgsMapCanvas::snappingUtils
QgsSnappingUtils * snappingUtils() const
Returns snapping utility class that is associated with map canvas.
Definition: qgsmapcanvas.cpp:2378
QgsRubberBand::reset
void reset(QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry)
Clears all the geometries in this rubberband.
Definition: qgsrubberband.cpp:102
QgsFeatureRequest::setFilterFid
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets feature ID that should be fetched.
Definition: qgsfeaturerequest.cpp:103
qgsrubberband.h
QgsPoint::dropMValue
bool dropMValue() override
Drops any measure values which exist in the geometry.
Definition: qgspoint.cpp:563
QgsAbstractGeometry::vertexAt
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
QgsMapTool::toLayerCoordinates
QgsPointXY toLayerCoordinates(const QgsMapLayer *layer, QPoint point)
transformation from screen coordinates to layer's coordinates
Definition: qgsmaptool.cpp:54
qgsapplication.h
QgsWkbTypes::PointM
@ PointM
Definition: qgswkbtypes.h:98
QObjectUniquePtr::release
T * release()
Clears the pointer and returns it.
Definition: qobjectuniqueptr.h:164
QgsMapLayer::triggerRepaint
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
Definition: qgsmaplayer.cpp:1817
qgsmapcanvastracer.h
QgsVertexMarker
Definition: qgsvertexmarker.h:36
QgsVectorLayer::changeGeometry
bool changeGeometry(QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue=false)
Changes a feature's geometry within the layer's edit buffer (but does not immediately commit the chan...
Definition: qgsvectorlayer.cpp:2941
QgsPointLocator::Match::vertexIndex
int vertexIndex() const
for vertex / edge match (first vertex of the edge)
Definition: qgspointlocator.h:231
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsPoint::y
double y
Definition: qgspoint.h:59
QgsPointLocator::Match::hasEdge
bool hasEdge() const
Returns true if the Match is an edge.
Definition: qgspointlocator.h:210
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
QgsMapToolCapture::addCurve
int addCurve(QgsCurve *c)
Adds a whole curve (e.g. circularstring) to the captured geometry. Curve must be in map CRS.
Definition: qgsmaptoolcapture.cpp:553
QgsVectorDataProvider::capabilities
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Definition: qgsvectordataprovider.cpp:191
QgsMapMouseEvent::mapPointMatch
QgsPointLocator::Match mapPointMatch() const
Returns the matching data from the most recently snapped point.
Definition: qgsmapmouseevent.h:97
QgsWkbTypes::PointZM
@ PointZM
Definition: qgswkbtypes.h:111
QgsCsException
Definition: qgsexception.h:65
QgsMapToolCapture::~QgsMapToolCapture
~QgsMapToolCapture() override
Definition: qgsmaptoolcapture.cpp:68
QgsPoint::addMValue
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:522
QgsProject::topologicalEditing
bool topologicalEditing
Definition: qgsproject.h:109
QgsMapToolCapture::activate
void activate() override
Registers this maptool with the cad dock widget.
Definition: qgsmaptoolcapture.cpp:87
QgsMapToolCapture::undo
void undo()
Removes the last vertex from mRubberBand and mCaptureList.
Definition: qgsmaptoolcapture.cpp:613
QgsCompoundCurve::addVertex
void addVertex(const QgsPoint &pt)
Adds a vertex to the end of the geometry.
Definition: qgscompoundcurve.cpp:499
QgsMapCanvasTracer
Definition: qgsmapcanvastracer.h:41
qgsvertexmarker.h
QgsTracer::ErrTooManyFeatures
@ ErrTooManyFeatures
Max feature count threshold was reached while reading features.
Definition: qgstracer.h:135
QgsMapToolCapture::capabilities
virtual QgsMapToolCapture::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Definition: qgsmaptoolcapture.cpp:82
QgsGeometry::ValidatorQgisInternal
@ ValidatorQgisInternal
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:2070
QgsPoint::dropZValue
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
Definition: qgspoint.cpp:552
QgsVertexMarker::setPenWidth
void setPenWidth(int width)
Definition: qgsvertexmarker.cpp:54
QgsMapToolCapture::deleteTempRubberBand
void deleteTempRubberBand()
Clean a temporary rubberband.
Definition: qgsmaptoolcapture.cpp:705
QgsMapToolCapture::snappingMatches
QList< QgsPointLocator::Match > snappingMatches() const
Returns a list of matches for each point on the captureCurve.
Definition: qgsmaptoolcapture.cpp:607
QgsCompoundCurve::points
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
Definition: qgscompoundcurve.cpp:340
QgsMapToolCapture::setPoints
Q_DECL_DEPRECATED void setPoints(const QVector< QgsPointXY > &pointList)
Set the points on which to work.
Definition: qgsmaptoolcapture.cpp:815
QgsVertexMarker::setCenter
void setCenter(const QgsPointXY &point)
Definition: qgsvertexmarker.cpp:35
QgsPointLocator::Match::isValid
bool isValid() const
Definition: qgspointlocator.h:206
QgsWkbTypes::PointZ
@ PointZ
Definition: qgswkbtypes.h:85
QgsMapCanvasTracer::actionEnableSnapping
QAction * actionEnableSnapping() const
Access to action that user may use to toggle snapping on/off.
Definition: qgsmapcanvastracer.h:63
QgsVertexMarker::setColor
void setColor(const QColor &color)
Sets the stroke color for the marker.
Definition: qgsvertexmarker.cpp:42
QgsMapToolCapture::startCapturing
void startCapturing()
Start capturing.
Definition: qgsmaptoolcapture.cpp:675
QgsRubberBand::numberOfVertices
int numberOfVertices() const
Returns count of vertices in all lists of mPoint.
Definition: qgsrubberband.cpp:660
QgsAbstractGeometry::is3D
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:202
QgsMapToolCapture::CapturePolygon
@ CapturePolygon
Capture polygons.
Definition: qgsmaptoolcapture.h:53
QgsMapToolCapture::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Intercept key events like Esc or Del to delete the last point.
Definition: qgsmaptoolcapture.cpp:657
QgsPointLocator::Match::layer
QgsVectorLayer * layer() const
The vector layer where the snap occurred.
Definition: qgspointlocator.h:237
QgsMapToolEdit::createRubberBand
QgsRubberBand * createRubberBand(QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry, bool alternativeBand=false)
Creates a rubber band with the color/line width from the QGIS settings.
Definition: qgsmaptooledit.cpp:68
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:125
QgsCompoundCurve::numPoints
int numPoints() const override
Returns the number of points in the curve.
Definition: qgscompoundcurve.cpp:358
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsRubberBand::addPoint
void addPoint(const QgsPointXY &p, bool doUpdate=true, int geometryIndex=0, int ringIndex=0)
Adds a vertex to the rubberband and update canvas.
Definition: qgsrubberband.cpp:110
QgsMapToolCapture::CaptureLine
@ CaptureLine
Capture lines.
Definition: qgsmaptoolcapture.h:52
QgsAdvancedDigitizingDockWidget
The QgsAdvancedDigitizingDockWidget class is a dockable widget used to handle the CAD tools on top of...
Definition: qgsadvanceddigitizingdockwidget.h:48
QgsPoint::setZ
void setZ(double z)
Sets the point's z-coordinate.
Definition: qgspoint.h:311
QgsMapCanvasTracer::tracerForCanvas
static QgsMapCanvasTracer * tracerForCanvas(QgsMapCanvas *canvas)
Retrieve instance of this class associated with given canvas (if any).
Definition: qgsmapcanvastracer.cpp:60
QgsCompoundCurve::clear
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgscompoundcurve.cpp:108
QgsMapToolCapture::isCapturing
bool isCapturing() const
Are we currently capturing?
Definition: qgsmaptoolcapture.cpp:680
QgsGeometry::vertexAt
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Definition: qgsgeometry.cpp:588
QgsPointLocator::Match
Definition: qgspointlocator.h:184
qgsvectorlayer.h
QgsPointXY
Definition: qgspointxy.h:43
QgsCompoundCurve::startPoint
QgsPoint startPoint() const override
Returns the starting point of the curve.
Definition: qgscompoundcurve.cpp:322
QgsMapToolCapture::clean
void clean() override
convenient method to clean members
Definition: qgsmaptoolcapture.cpp:710
QgsGeometry::convertToCurves
QgsGeometry convertToCurves(double distanceTolerance=1e-8, double angleTolerance=1e-8) const
Attempts to convert a non-curved geometry into a curved geometry type (e.g.
Definition: qgsgeometry.cpp:2146
QgsVectorLayer::LayerOptions
Setting options for loading vector layers.
Definition: qgsvectorlayer.h:423
QgsCompoundCurve::isEmpty
bool isEmpty() const override
Returns true if the geometry is empty.
Definition: qgscompoundcurve.cpp:375
QgsWkbTypes::hasM
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1092
QgsGeometry::get
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:133
QgsMapMouseEvent
Definition: qgsmapmouseevent.h:35
QgsPointLocator::Match::featureId
QgsFeatureId featureId() const
The id of the feature to which the snapped geometry belongs.
Definition: qgspointlocator.h:242
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:142
qgslayertreeview.h
qgsadvanceddigitizingdockwidget.h
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:141
QgsCompoundCurve::clone
QgsCompoundCurve * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgscompoundcurve.cpp:103
QgsGeometry::convertPointList
static void convertPointList(const QVector< QgsPointXY > &input, QgsPointSequence &output)
Upgrades a point list from QgsPointXY to QgsPoint.
Definition: qgsgeometry.cpp:3043
QgsTracer::ErrNone
@ ErrNone
No error.
Definition: qgstracer.h:134
QgsMapToolCapture::takeRubberBand
QgsRubberBand * takeRubberBand()
Returns the rubberBand currently owned by this map tool and transfers ownership to the caller.
Definition: qgsmaptoolcapture.cpp:331
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:373
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:44
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsGeometry
Definition: qgsgeometry.h:122
QgsLineString::close
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
Definition: qgslinestring.cpp:1488
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsMapLayer
Definition: qgsmaplayer.h:81
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1033
qgssettings.h
QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent
virtual void cadCanvasMoveEvent(QgsMapMouseEvent *e)
Override this method when subclassing this class.
Definition: qgsmaptooladvanceddigitizing.h:145
QgsMapToolCapture::points
Q_DECL_DEPRECATED QVector< QgsPointXY > points() const
List of digitized points.
Definition: qgsmaptoolcapture.cpp:800
QgsMapToolCapture::CaptureNone
@ CaptureNone
Do not capture / determine mode from layer geometry type.
Definition: qgsmaptoolcapture.h:50
QgsMapToolCapture::CapturePoint
@ CapturePoint
Capture points.
Definition: qgsmaptoolcapture.h:51
qgsmaptoolcapture.h
QgsVertexId::ring
int ring
Definition: qgsabstractgeometry.h:1081
QgsMapToolCapture::stopCapturing
void stopCapturing()
Stop capturing.
Definition: qgsmaptoolcapture.cpp:685
QgsAbstractGeometry::isMeasure
bool isMeasure() const
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:211
QgsMapToolCapture::mapPoint
QgsPoint mapPoint(const QgsMapMouseEvent &e) const
Creates a QgsPoint with ZM support if necessary (according to the WkbType of the current layer).
Definition: qgsmaptoolcapture.cpp:872
QgsMapToolCapture::fetchLayerPoint
int fetchLayerPoint(const QgsPointLocator::Match &match, QgsPoint &layerPoint)
Fetches the original point from the source layer if it has the same CRS as the current layer.
Definition: qgsmaptoolcapture.cpp:418
QgsVertexId::VertexType
VertexType
Definition: qgsabstractgeometry.h:1035
QgsMapCanvasTracer::reportError
void reportError(PathError err, bool addingVertex)
Report a path finding error to the user.
Definition: qgsmapcanvastracer.cpp:65
QgsPoint::convertTo
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
Definition: qgspoint.cpp:580
QgsGeometry::ValidationMethod
ValidationMethod
Available methods for validating geometries.
Definition: qgsgeometry.h:2068
QgsGeometry::vertexIdFromVertexNr
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
Definition: qgsgeometry.cpp:2973
qgsexception.h
QgsFeature
Definition: qgsfeature.h:55
QgsMapToolCapture::closePolygon
void closePolygon()
Close an open polygon.
Definition: qgsmaptoolcapture.cpp:716
QgsMapCanvas::currentLayer
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
Definition: qgsmapcanvas.cpp:511
QgsMapToolAdvancedDigitizing::deactivate
void deactivate() override
Unregisters this maptool from the cad dock widget.
Definition: qgsmaptooladvanceddigitizing.cpp:136
QgsMapToolCapture::deactivate
void deactivate() override
Unregisters this maptool from the cad dock widget.
Definition: qgsmaptoolcapture.cpp:96
QgsVectorLayer::getFeature
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
Definition: qgsvectorlayer.h:1183
QgsMapToolCapture::nextPoint
int nextPoint(const QgsPoint &mapPoint, QgsPoint &layerPoint)
Converts a map point to layer coordinates.
Definition: qgsmaptoolcapture.cpp:385
qgslogger.h
QgsCurve::segmentize
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
Definition: qgscurve.cpp:159
QgsCompoundCurve::deleteVertex
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Definition: qgscompoundcurve.cpp:616
QgsTracer::PathError
PathError
Possible errors that may happen when calling findShortestPath()
Definition: qgstracer.h:132
QgsSnappingUtils::removeExtraSnapLayer
void removeExtraSnapLayer(QgsVectorLayer *vl)
Removes an extra snapping layer.
Definition: qgssnappingutils.h:213
QgsVertexMarker::ICON_X
@ ICON_X
Definition: qgsvertexmarker.h:54
QgsTracer::isPointSnapped
bool isPointSnapped(const QgsPointXY &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:805
QgsLineString::points
void points(QgsPointSequence &pt) const override
Returns a list of points within the curve.
Definition: qgslinestring.cpp:745
QgsCoordinateTransform
Definition: qgscoordinatetransform.h:52
qgsmapmouseevent.h
QgsLineString::length
double length() const override
Returns the planar, 2-dimensional length of the geometry.
Definition: qgslinestring.cpp:583
QgsGeometryValidator
Definition: qgsgeometryvalidator.h:28
QgsProject::snappingConfigChanged
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsMapSettings::layerToMapCoordinates
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:482
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:659
QgsVectorLayer::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
Definition: qgsvectorlayer.cpp:1011
QgsMapToolAdvancedDigitizing
The QgsMapToolAdvancedDigitizing class is a QgsMapTool which gives event directly in map coordinates ...
Definition: qgsmaptooladvanceddigitizing.h:36
QgsMapToolCapture::cadCanvasMoveEvent
void cadCanvasMoveEvent(QgsMapMouseEvent *e) override
Override this method when subclassing this class.
Definition: qgsmaptoolcapture.cpp:337
QgsVectorLayer::LayerOptions::skipCrsValidation
bool skipCrsValidation
Controls whether the layer is allowed to have an invalid/unknown CRS.
Definition: qgsvectorlayer.h:502
QgsPoint::x
double x
Definition: qgspoint.h:58
qgsproject.h
QgsGeometryValidator::errorFound
void errorFound(const QgsGeometry::Error &error)
Sent when an error has been found during the validation process.
QgsMapTool::toMapCoordinates
QgsPointXY toMapCoordinates(QPoint point)
transformation from screen coordinates to map coordinates
Definition: qgsmaptool.cpp:42
qgsgeometryvalidator.h
QgsMapMouseEvent::isSnapped
bool isSnapped() const
Returns true if there is a snapped point cached.
Definition: qgsmapmouseevent.h:82
QgsCompoundCurve::pointAt
bool pointAt(int node, QgsPoint &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
Definition: qgscompoundcurve.cpp:754
QgsMapToolCapture::pointsZM
QgsPointSequence pointsZM() const
List of digitized points.
Definition: qgsmaptoolcapture.cpp:808
QgsMapToolEdit::defaultZValue
double defaultZValue() const
Returns default Z value Use for set Z coordinate to new vertex for 2.5d geometries.
Definition: qgsmaptooledit.cpp:32