QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 #include "qgsgeometryrubberband.h"
36 
37 #include <QAction>
38 #include <QCursor>
39 #include <QPixmap>
40 #include <QStatusBar>
41 
42 
44  : QgsMapToolAdvancedDigitizing( canvas, cadDockWidget )
45  , mCaptureMode( mode )
46  , mCaptureModeFromLayer( mode == CaptureNone )
47 {
48  mSnapIndicator.reset( new QgsSnapIndicator( canvas ) );
49 
50  setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CapturePoint ) );
51 
53  this, &QgsMapToolCapture::currentLayerChanged );
54 
55  QgsVectorLayer::LayerOptions layerOptions;
56  layerOptions.skipCrsValidation = true;
57  mExtraSnapLayer = new QgsVectorLayer( QStringLiteral( "LineString?crs=" ), QStringLiteral( "extra snap" ), QStringLiteral( "memory" ), layerOptions );
58  mExtraSnapLayer->startEditing();
59  QgsFeature f;
60  mExtraSnapLayer->addFeature( f );
61  mExtraSnapFeatureId = f.id();
62 
64  this, &QgsMapToolCapture::updateExtraSnapLayer );
65 
66  currentLayerChanged( canvas->currentLayer() );
67 }
68 
70 {
71  stopCapturing();
72 
73  if ( mValidator )
74  {
75  mValidator->deleteLater();
76  mValidator = nullptr;
77  }
78  mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
79  mExtraSnapLayer->deleteLater();
80  mExtraSnapLayer = nullptr;
81 }
82 
83 QgsMapToolCapture::Capabilities QgsMapToolCapture::capabilities() const
84 {
86 }
87 
89 {
90  if ( mTempRubberBand )
91  mTempRubberBand->show();
92 
93  mCanvas->snappingUtils()->addExtraSnapLayer( mExtraSnapLayer );
95 }
96 
98 {
99  if ( mTempRubberBand )
100  mTempRubberBand->hide();
101 
102  mSnapIndicator->setMatch( QgsPointLocator::Match() );
103 
104  mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
106 }
107 
108 void QgsMapToolCapture::currentLayerChanged( QgsMapLayer *layer )
109 {
110  if ( !mCaptureModeFromLayer )
111  return;
112 
113  mCaptureMode = CaptureNone;
114 
115  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
116  if ( !vlayer )
117  {
118  return;
119  }
120 
121  switch ( vlayer->geometryType() )
122  {
124  mCaptureMode = CapturePoint;
125  break;
127  mCaptureMode = CaptureLine;
128  break;
130  mCaptureMode = CapturePolygon;
131  break;
132  default:
133  mCaptureMode = CaptureNone;
134  break;
135  }
136 
137  if ( mTempRubberBand )
138  mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
139 
140  resetRubberBand();
141 }
142 
143 
144 bool QgsMapToolCapture::tracingEnabled()
145 {
147  return tracer && ( !tracer->actionEnableTracing() || tracer->actionEnableTracing()->isChecked() )
148  && ( !tracer->actionEnableSnapping() || tracer->actionEnableSnapping()->isChecked() );
149 }
150 
151 
152 QgsPointXY QgsMapToolCapture::tracingStartPoint()
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  return lastCapturedMapPoint();
160 }
161 
162 
163 bool QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent *e )
164 {
165  if ( !e->isSnapped() )
166  return false;
167 
168  QgsPointXY pt0 = tracingStartPoint();
169  if ( pt0 == QgsPointXY() )
170  return false;
171 
173  if ( !tracer )
174  return false; // this should not happen!
175 
177  QVector<QgsPointXY> points = tracer->findShortestPath( pt0, e->mapPoint(), &err );
178  if ( points.isEmpty() )
179  {
180  tracer->reportError( err, false );
181  return false;
182  }
183 
184  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, QgsWkbTypes::LineString, firstCapturedMapPoint() );
185  mTempRubberBand->addPoint( lastCapturedMapPoint() );
186 
187  // if there is offset, we need to fix the rubber bands to make sure they are aligned correctly.
188  // There are two cases we need to sort out:
189  // 1. the last point of mRubberBand may need to be moved off the traced curve to respect the offset
190  // 2. first point of mTempRubberBand may be needed to be moved to the beginning of the offset trace
191  QgsPoint lastPoint = lastCapturedMapPoint();
192  QgsPointXY lastPointXY( lastPoint );
193  if ( lastPointXY == pt0 && points[0] != lastPointXY )
194  {
195  if ( mRubberBand->numberOfVertices() != 0 )
196  {
197  // if rubber band had just one point, for some strange reason it contains the point twice
198  // we only want to move the last point if there are multiple points already
199  if ( mRubberBand->numberOfVertices() > 2 || ( mRubberBand->numberOfVertices() == 2 && *mRubberBand->getPoint( 0, 0 ) != *mRubberBand->getPoint( 0, 1 ) ) )
200  mRubberBand->movePoint( points[0] );
201  }
202 
203  mTempRubberBand->movePoint( 0, QgsPoint( points[0] ) );
204  }
205 
206  mTempRubberBand->movePoint( QgsPoint( points[0] ) );
207 
208  // update temporary rubberband
209  for ( int i = 1; i < points.count(); ++i ) //points added in the rubber band are 2D but will not be added to the capture curve
210  mTempRubberBand->addPoint( QgsPoint( points.at( i ) ), i == points.count() - 1 );
211 
212 
213  mTempRubberBand->addPoint( QgsPoint( points[points.size() - 1] ) );
214 
215  tracer->reportError( QgsTracer::ErrNone, false ); // clear messagebar if there was any error
216  return true;
217 }
218 
219 
220 bool QgsMapToolCapture::tracingAddVertex( const QgsPointXY &point )
221 {
223  if ( !tracer )
224  return false; // this should not happen!
225 
226  if ( mTempRubberBand->pointsCount() == 0 )
227  {
228  if ( !tracer->init() )
229  {
231  return false;
232  }
233 
234  // only accept first point if it is snapped to the graph (to vertex or edge)
235  bool res = tracer->isPointSnapped( point );
236  if ( res )
237  {
238  mTracingStartPoint = point;
239  }
240  return false;
241  }
242 
243  QgsPointXY pt0 = tracingStartPoint();
244  if ( pt0 == QgsPointXY() )
245  return false;
246 
248  QVector<QgsPointXY> points = tracer->findShortestPath( pt0, point, &err );
249  if ( points.isEmpty() )
250  return false; // ignore the vertex - can't find path to the end point!
251 
252  // transform points
253  QgsPointSequence layerPoints;
254  QgsPoint lp; // in layer coords
255  for ( int i = 0; i < points.count(); ++i )
256  {
257  if ( nextPoint( QgsPoint( points[i] ), lp ) != 0 )
258  return false;
259  layerPoints << lp;
260  }
261 
262  // Move the last point of the captured curve to the first point on the trace string (necessary if there is offset)
263  QgsVertexId lastVertexId( 0, 0, mCaptureCurve.numPoints() - 1 );
264  mCaptureCurve.moveVertex( lastVertexId, layerPoints.first() );
265  mSnappingMatches.removeLast();
266  mSnappingMatches.append( QgsPointLocator::Match() );
267 
268  int pointBefore = mCaptureCurve.numPoints();
269  mCaptureCurve.addCurve( new QgsLineString( layerPoints ) );
270 
271  resetRubberBand();
272 
273  // Curves de-approximation
274  QgsSettings settings;
275  if ( settings.value( QStringLiteral( "/qgis/digitizing/convert_to_curve" ), false ).toBool() )
276  {
277  // If the tool and the layer support curves
278  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
279  if ( capabilities().testFlag( QgsMapToolCapture::Capability::SupportsCurves ) && vlayer->dataProvider()->capabilities().testFlag( QgsVectorDataProvider::Capability::CircularGeometries ) )
280  {
281  QgsGeometry linear = QgsGeometry( mCaptureCurve.segmentize() );
282  QgsGeometry curved = linear.convertToCurves(
283  settings.value( QStringLiteral( "/qgis/digitizing/convert_to_curve_angle_tolerance" ), 1e-6 ).toDouble(),
284  settings.value( QStringLiteral( "/qgis/digitizing/convert_to_curve_distance_tolerance" ), 1e-6 ).toDouble()
285  );
286  mCaptureCurve = *qgsgeometry_cast<QgsCompoundCurve *>( curved.constGet() );
287  }
288  }
289 
290  // sync the snapping matches list
291  int pointAfter = mCaptureCurve.numPoints();
292  for ( ; pointBefore < pointAfter; ++pointBefore )
293  mSnappingMatches.append( QgsPointLocator::Match() );
294 
295  tracer->reportError( QgsTracer::ErrNone, true ); // clear messagebar if there was any error
296 
297  // adjust last captured point
298  const QgsPoint lastPt = mCaptureCurve.endPoint();
299  mCaptureLastPoint = toMapCoordinates( qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ), lastPt );
300 
301  return true;
302 }
303 
304 QgsMapToolCaptureRubberBand *QgsMapToolCapture::createCurveRubberBand() const
305 {
306  QgsSettings settings;
307  QgsMapToolCaptureRubberBand *rb = new QgsMapToolCaptureRubberBand( mCanvas );
308  rb->setStrokeWidth( digitizingStrokeWidth() );
309  QColor color = digitizingStrokeColor();
310 
311  double alphaScale = settings.value( QStringLiteral( "qgis/digitizing/line_color_alpha_scale" ), 0.75 ).toDouble();
312  color.setAlphaF( color.alphaF() * alphaScale );
313  rb->setLineStyle( Qt::DotLine );
314  rb->setStrokeColor( color );
315 
316  QColor fillColor = digitizingFillColor();
317  rb->setFillColor( fillColor );
318  rb->show();
319  return rb;
320 }
321 
322 QgsPoint QgsMapToolCapture::firstCapturedMapPoint()
323 {
324  return mCaptureFirstPoint;
325 }
326 
327 QgsPoint QgsMapToolCapture::lastCapturedMapPoint()
328 {
329  return mCaptureLastPoint;
330 }
331 
332 void QgsMapToolCapture::resetRubberBand()
333 {
334  if ( !mRubberBand )
335  return;
336  QgsLineString *lineString = mCaptureCurve.curveToLine();
338  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
339  mRubberBand->addGeometry( QgsGeometry( lineString ), vlayer );
340 }
341 
343 {
344  return mRubberBand.release();
345 }
346 
348 {
349  mDigitizingType = enable ? QgsWkbTypes::CircularString : QgsWkbTypes::LineString;
350  if ( mTempRubberBand )
351  mTempRubberBand->setStringType( mDigitizingType );
352 }
353 
354 
356 {
358  QgsPointXY point = e->mapPoint();
359 
360  mSnapIndicator->setMatch( e->mapPointMatch() );
361 
362  QgsPoint mapPoint = QgsPoint( point );
363 
364  if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
365  {
366  bool hasTrace = false;
367 
368 
369  if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
370  {
371  // Store the intermediate point for circular string to retrieve after tracing mouse move if
372  // the digitizing type is circular and the temp rubber band is effectivly circular and if this point is existing
373  // Store an empty point if the digitizing type is linear ot the point is not existing (curve not complete)
374  if ( mDigitizingType == QgsWkbTypes::CircularString &&
375  mTempRubberBand->stringType() == QgsWkbTypes::CircularString &&
376  mTempRubberBand->curveIsComplete() )
377  mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 );
378  else if ( mDigitizingType == QgsWkbTypes::LineString ||
379  !mTempRubberBand->curveIsComplete() )
380  mCircularItermediatePoint = QgsPoint();
381 
382  hasTrace = tracingMouseMove( e );
383 
384  if ( !hasTrace )
385  {
386  // Restore the temp rubber band
387  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, firstCapturedMapPoint() );
388  mTempRubberBand->addPoint( lastCapturedMapPoint() );
389  if ( !mCircularItermediatePoint.isEmpty() )
390  {
391  mTempRubberBand->movePoint( mCircularItermediatePoint );
392  mTempRubberBand->addPoint( mCircularItermediatePoint );
393  }
394  }
395  }
396 
397  if ( !hasTrace )
398  {
399  if ( mCaptureCurve.numPoints() > 0 )
400  {
401  const QgsPoint mapPt = lastCapturedMapPoint();
402 
403  if ( mTempRubberBand )
404  {
405  mTempRubberBand->movePoint( mapPoint );
406  mTempRubberBand->movePoint( 0, mapPt );
407  }
408 
409  // fix existing rubber band after tracing - the last point may have been moved if using offset
410  if ( mRubberBand->numberOfVertices() )
411  mRubberBand->movePoint( mapPt );
412  }
413  else if ( mTempRubberBand )
414  mTempRubberBand->movePoint( mapPoint );
415  }
416  }
417 } // mouseMoveEvent
418 
419 
420 int QgsMapToolCapture::nextPoint( const QgsPoint &mapPoint, QgsPoint &layerPoint )
421 {
422  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
423  if ( !vlayer )
424  {
425  QgsDebugMsg( QStringLiteral( "no vector layer" ) );
426  return 1;
427  }
428  try
429  {
430  QgsPointXY mapP( mapPoint.x(), mapPoint.y() ); //#spellok
431  layerPoint = QgsPoint( toLayerCoordinates( vlayer, mapP ) ); //transform snapped point back to layer crs //#spellok
432  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) )
433  layerPoint.addZValue( defaultZValue() );
434  if ( QgsWkbTypes::hasM( vlayer->wkbType() ) )
435  layerPoint.addMValue( 0.0 );
436  }
437  catch ( QgsCsException &cse )
438  {
439  Q_UNUSED( cse )
440  QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
441  return 2;
442  }
443 
444  return 0;
445 }
446 
447 int QgsMapToolCapture::nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint )
448 {
450  return nextPoint( mapPoint, layerPoint );
451 }
452 
454 {
455  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
456  QgsVectorLayer *sourceLayer = match.layer();
457  if ( match.isValid() && ( match.hasVertex() || ( QgsProject::instance()->topologicalEditing() && match.hasEdge() ) ) && sourceLayer &&
458  ( sourceLayer->crs() == vlayer->crs() ) )
459  {
460  QgsFeature f;
461  QgsFeatureRequest request;
462  request.setFilterFid( match.featureId() );
463  bool fetched = match.layer()->getFeatures( request ).nextFeature( f );
464  if ( fetched )
465  {
466  QgsVertexId vId;
467  if ( !f.geometry().vertexIdFromVertexNr( match.vertexIndex(), vId ) )
468  return 2;
469 
470  const QgsGeometry geom( f.geometry() );
471  if ( QgsProject::instance()->topologicalEditing() && match.hasEdge() )
472  {
473  QgsVertexId vId2;
474  if ( !f.geometry().vertexIdFromVertexNr( match.vertexIndex() + 1, vId2 ) )
475  return 2;
476  QgsLineString line( geom.constGet()->vertexAt( vId ), geom.constGet()->vertexAt( vId2 ) );
477 
478  layerPoint = QgsGeometryUtils::closestPoint( line, QgsPoint( match.point() ) );
479  }
480  else
481  {
482  layerPoint = geom.constGet()->vertexAt( vId );
483  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) && !layerPoint.is3D() )
484  layerPoint.addZValue( defaultZValue() );
485  if ( QgsWkbTypes::hasM( vlayer->wkbType() ) && !layerPoint.isMeasure() )
486  layerPoint.addMValue( 0.0 );
487  }
488 
489  // ZM support depends on the target layer
490  if ( !QgsWkbTypes::hasZ( vlayer->wkbType() ) )
491  {
492  layerPoint.dropZValue();
493  }
494 
495  if ( !QgsWkbTypes::hasM( vlayer->wkbType() ) )
496  {
497  layerPoint.dropMValue();
498  }
499 
500  return 0;
501  }
502  else
503  {
504  return 2;
505  }
506  }
507  else
508  {
509  return 1;
510  }
511 }
512 
514 {
515  return addVertex( point, QgsPointLocator::Match() );
516 }
517 
519 {
520  if ( mode() == CaptureNone )
521  {
522  QgsDebugMsg( QStringLiteral( "invalid capture mode" ) );
523  return 2;
524  }
525 
526  int res;
527  QgsPoint layerPoint;
528  res = fetchLayerPoint( match, layerPoint );
529  if ( res != 0 )
530  {
531  res = nextPoint( QgsPoint( point ), layerPoint );
532  if ( res != 0 )
533  {
534  return res;
535  }
536  }
537  QgsPoint mapPoint = toMapCoordinates( canvas()->currentLayer(), layerPoint );
538 
539  if ( mCaptureMode == CapturePoint )
540  {
541  mCaptureCurve.addVertex( layerPoint );
542  mSnappingMatches.append( match );
543  }
544  else
545  {
546  if ( mCaptureFirstPoint.isEmpty() )
547  {
548  mCaptureFirstPoint = mapPoint;
549  }
550 
551  if ( !mRubberBand )
553 
554  if ( !mTempRubberBand )
555  {
556  mTempRubberBand.reset( createCurveRubberBand() );
557  mTempRubberBand->setStringType( mDigitizingType );
558  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mapPoint );
559  }
560 
561  bool traceCreated = false;
562  if ( tracingEnabled() )
563  {
564  traceCreated = tracingAddVertex( mapPoint );
565  }
566 
567  // keep new tracing start point if we created a trace. This is useful when tracing with
568  // offset so that the user stays "snapped"
569  mTracingStartPoint = traceCreated ? point : QgsPointXY();
570 
571  if ( !traceCreated )
572  {
573  // ordinary digitizing
574  mTempRubberBand->movePoint( mapPoint ); //move the last point of the temp rubberband before operating with it
575  if ( mTempRubberBand->curveIsComplete() ) //2 points for line and 3 points for circular
576  {
577  const QgsCurve *curve = mTempRubberBand->curve();
578  if ( curve )
579  {
580  addCurve( curve->clone() );
581  // add curve append only invalid match to mSnappingMatches,
582  // so we need to remove them and add the one from here if it is valid
583  if ( match.isValid() && mSnappingMatches.count() > 0 && !mSnappingMatches.last().isValid() )
584  {
585  mSnappingMatches.removeLast();
586  if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString )
587  {
588  // for circular string two points are added and match for intermediate point is stored
589  mSnappingMatches.removeLast();
590  mSnappingMatches.append( mCircularIntermediateMatch );
591  }
592  mSnappingMatches.append( match );
593  }
594  }
595  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, firstCapturedMapPoint() );
596  }
597  else if ( mCaptureCurve.numPoints() == 0 )
598  {
599  mCaptureCurve.addVertex( layerPoint );
600  mSnappingMatches.append( match );
601  }
602  else
603  {
604  if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString )
605  {
606  mCircularIntermediateMatch = match;
607  }
608  }
609 
610  mTempRubberBand->addPoint( mapPoint );
611  mCaptureLastPoint = mapPoint;
612  }
613  else
614  {
615  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, firstCapturedMapPoint() );
616  mTempRubberBand->addPoint( lastCapturedMapPoint() );
617  }
618  }
619 
620  updateExtraSnapLayer();
621  validateGeometry();
622 
623  return 0;
624 }
625 
627 {
628  if ( !c )
629  {
630  return 1;
631  }
632 
633  if ( !mRubberBand )
634  {
636  }
637 
638  if ( mTempRubberBand )
639  {
640  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, firstCapturedMapPoint() );
641  QgsPoint endPt = c->endPoint();
642  mTempRubberBand->addPoint( endPt ); //add last point of c
643  }
644 
645  //transform back to layer CRS in case map CRS and layer CRS are different
646  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
648  if ( ct.isValid() )
649  {
651  }
652  int countBefore = mCaptureCurve.vertexCount();
653  mCaptureCurve.addCurve( c );
654  int countAfter = mCaptureCurve.vertexCount();
655  int addedPoint = countAfter - countBefore;
656 
657  updateExtraSnapLayer();
658 
659  for ( int i = 0; i < addedPoint; ++i )
660  mSnappingMatches.append( QgsPointLocator::Match() );
661 
662  resetRubberBand();
663 
664  return 0;
665 }
666 
668 {
669  mCaptureCurve.clear();
670  updateExtraSnapLayer();
671 }
672 
673 QList<QgsPointLocator::Match> QgsMapToolCapture::snappingMatches() const
674 {
675  return mSnappingMatches;
676 }
677 
679 {
680  mTracingStartPoint = QgsPointXY();
681 
682  if ( mTempRubberBand )
683  {
684  if ( size() <= 1 && mTempRubberBand->pointsCount() != 0 )
685  return;
686 
687  QgsPoint lastPoint = mTempRubberBand->lastPoint();
688 
689  if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString && mTempRubberBand->pointsCount() > 2 )
690  {
691  mTempRubberBand->removeLastPoint();
692  mTempRubberBand->movePoint( lastPoint );
693  return;
694  }
695 
696  QgsVertexId vertexToRemove;
697  vertexToRemove.part = 0;
698  vertexToRemove.ring = 0;
699  vertexToRemove.vertex = size() - 1;
700  if ( mCaptureCurve.numPoints() == 2 && mCaptureCurve.nCurves() == 1 )
701  {
702  // store the first vertex to restore if after deleting the curve
703  // because when only two vertices, removing a point remove all the curve
704  QgsPoint fp = mCaptureCurve.startPoint();
705  mCaptureCurve.deleteVertex( vertexToRemove );
706  mCaptureCurve.addVertex( fp );
707  }
708  else
709  {
710  int pointsCountBefore = mCaptureCurve.numPoints();
711  mCaptureCurve.deleteVertex( vertexToRemove );
712  int pointsCountAfter = mCaptureCurve.numPoints();
713  for ( ; pointsCountAfter < pointsCountBefore; pointsCountAfter++ )
714  if ( !mSnappingMatches.empty() )
715  mSnappingMatches.removeLast();
716  }
717 
718  updateExtraSnapLayer();
719 
720  resetRubberBand();
721 
722  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, firstCapturedMapPoint() );
723 
724  if ( mCaptureCurve.numPoints() > 0 )
725  {
726  const QgsPoint lastPt = mCaptureCurve.endPoint();
727  mCaptureLastPoint = toMapCoordinates( qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ), lastPt );
728  mTempRubberBand->addPoint( lastCapturedMapPoint() );
729  mTempRubberBand->movePoint( lastPoint );
730  }
731 
733  validateGeometry();
734  }
735 }
736 
738 {
739  if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
740  {
741  undo();
742 
743  // Override default shortcut management in MapCanvas
744  e->ignore();
745  }
746  else if ( e->key() == Qt::Key_Escape )
747  {
748  stopCapturing();
749 
750  // Override default shortcut management in MapCanvas
751  e->ignore();
752  }
753 }
754 
756 {
757  mCapturing = true;
758 }
759 
761 {
762  return mCapturing;
763 }
764 
766 {
767  mRubberBand.reset();
768 
770 
771  qDeleteAll( mGeomErrorMarkers );
772  mGeomErrorMarkers.clear();
773  mGeomErrors.clear();
774 
775  mCaptureFirstPoint = QgsPoint();
776  mCaptureLastPoint = QgsPoint();
777 
778  mTracingStartPoint = QgsPointXY();
779 
780  mCapturing = false;
781  mCaptureCurve.clear();
782  updateExtraSnapLayer();
783  mSnappingMatches.clear();
784  if ( auto *lCurrentVectorLayer = currentVectorLayer() )
785  lCurrentVectorLayer->triggerRepaint();
786 }
787 
789 {
790  mTempRubberBand.reset();
791 }
792 
794 {
795  stopCapturing();
796  clearCurve();
797 }
798 
800 {
801  mCaptureCurve.close();
802  updateExtraSnapLayer();
803 }
804 
805 void QgsMapToolCapture::validateGeometry()
806 {
807  QgsSettings settings;
808  if ( settings.value( QStringLiteral( "qgis/digitizing/validate_geometries" ), 1 ).toInt() == 0 )
809  return;
810 
811  if ( mValidator )
812  {
813  mValidator->deleteLater();
814  mValidator = nullptr;
815  }
816 
817  mGeomErrors.clear();
818  while ( !mGeomErrorMarkers.isEmpty() )
819  {
820  delete mGeomErrorMarkers.takeFirst();
821  }
822 
823  QgsGeometry geom;
824 
825  switch ( mCaptureMode )
826  {
827  case CaptureNone:
828  case CapturePoint:
829  return;
830  case CaptureLine:
831  if ( size() < 2 )
832  return;
833  geom = QgsGeometry( mCaptureCurve.curveToLine() );
834  break;
835  case CapturePolygon:
836  if ( size() < 3 )
837  return;
838  QgsLineString *exteriorRing = mCaptureCurve.curveToLine();
839  exteriorRing->close();
840  QgsPolygon *polygon = new QgsPolygon();
841  polygon->setExteriorRing( exteriorRing );
842  geom = QgsGeometry( polygon );
843  break;
844  }
845 
846  if ( geom.isNull() )
847  return;
848 
850  if ( settings.value( QStringLiteral( "qgis/digitizing/validate_geometries" ), 1 ).toInt() == 2 )
852  mValidator = new QgsGeometryValidator( geom, nullptr, method );
853  connect( mValidator, &QgsGeometryValidator::errorFound, this, &QgsMapToolCapture::addError );
854  mValidator->start();
855  QgsDebugMsgLevel( QStringLiteral( "Validation started" ), 4 );
856 }
857 
858 void QgsMapToolCapture::addError( const QgsGeometry::Error &e )
859 {
860  mGeomErrors << e;
861  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
862  if ( !vlayer )
863  return;
864 
865  if ( e.hasWhere() )
866  {
868  vm->setCenter( mCanvas->mapSettings().layerToMapCoordinates( vlayer, e.where() ) );
870  vm->setPenWidth( 2 );
871  vm->setToolTip( e.what() );
872  vm->setColor( Qt::green );
873  vm->setZValue( vm->zValue() + 1 );
874  mGeomErrorMarkers << vm;
875  }
876 }
877 
879 {
880  return mCaptureCurve.numPoints();
881 }
882 
883 QVector<QgsPointXY> QgsMapToolCapture::points() const
884 {
885  QVector<QgsPointXY> pointsXY;
887 
888  return pointsXY;
889 }
890 
892 {
893  QgsPointSequence pts;
894  mCaptureCurve.points( pts );
895  return pts;
896 }
897 
898 void QgsMapToolCapture::setPoints( const QVector<QgsPointXY> &pointList )
899 {
900  QgsLineString *line = new QgsLineString( pointList );
901  mCaptureCurve.clear();
902  mCaptureCurve.addCurve( line );
903  updateExtraSnapLayer();
904  mSnappingMatches.clear();
905  for ( int i = 0; i < line->length(); ++i )
906  mSnappingMatches.append( QgsPointLocator::Match() );
907  resetRubberBand();
908 }
909 
911 {
912  QgsLineString *line = new QgsLineString( pointList );
913  mCaptureCurve.clear();
914  mCaptureCurve.addCurve( line );
915  updateExtraSnapLayer();
916  mSnappingMatches.clear();
917  for ( int i = 0; i < line->length(); ++i )
918  mSnappingMatches.append( QgsPointLocator::Match() );
919  resetRubberBand();
920 }
921 
923 {
924  QgsPoint newPoint( QgsWkbTypes::Point, point.x(), point.y() );
925 
926  // get current layer
927  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
928  if ( !vlayer )
929  {
930  return newPoint;
931  }
932 
933  // convert to the corresponding type for a full ZM support
934  const QgsWkbTypes::Type type = vlayer->wkbType();
935  if ( QgsWkbTypes::hasZ( type ) && !QgsWkbTypes::hasM( type ) )
936  {
937  newPoint.convertTo( QgsWkbTypes::PointZ );
938  }
939  else if ( !QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
940  {
941  newPoint.convertTo( QgsWkbTypes::PointM );
942  }
943  else if ( QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
944  {
945  newPoint.convertTo( QgsWkbTypes::PointZM );
946  }
947 
948  // set z value if necessary
949  if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) )
950  {
951  newPoint.setZ( defaultZValue() );
952  }
953 
954  return newPoint;
955 }
956 
958 {
959  QgsPoint newPoint = mapPoint( e.mapPoint() );
960 
961  // set z value from snapped point if necessary
962  if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) )
963  {
964  // if snapped, z dimension is taken from the corresponding snapped
965  // point.
966  if ( e.isSnapped() )
967  {
968  const QgsPointLocator::Match match = e.mapPointMatch();
969 
970  if ( match.layer() && QgsWkbTypes::hasZ( match.layer()->wkbType() ) )
971  {
972  const QgsFeature ft = match.layer()->getFeature( match.featureId() );
973  newPoint.setZ( ft.geometry().vertexAt( match.vertexIndex() ).z() );
974  }
975  }
976  }
977 
978  return newPoint;
979 }
980 
981 void QgsMapToolCapture::updateExtraSnapLayer()
982 {
983  if ( canvas()->snappingUtils()->config().selfSnapping() && mCanvas->currentLayer() && mCaptureCurve.numPoints() >= 2 )
984  {
985  // the current layer may have changed
986  mExtraSnapLayer->setCrs( mCanvas->currentLayer()->crs() );
987  QgsGeometry geom = QgsGeometry( mCaptureCurve.clone() );
988  // we close the curve to allow snapping on last segment
989  if ( mCaptureMode == CapturePolygon && mCaptureCurve.numPoints() >= 3 )
990  {
991  qgsgeometry_cast<QgsCompoundCurve *>( geom.get() )->close();
992  }
993  mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
994  }
995  else
996  {
997  QgsGeometry geom;
998  mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
999  }
1000 }
1001 
1002 QgsMapToolCaptureRubberBand::QgsMapToolCaptureRubberBand( QgsMapCanvas *mapCanvas, QgsWkbTypes::GeometryType geomType ):
1003  QgsGeometryRubberBand( mapCanvas, geomType )
1004 {
1005  setVertexDrawingEnabled( false );
1006 }
1007 
1008 QgsCurve *QgsMapToolCaptureRubberBand::curve()
1009 {
1010  if ( mPoints.empty() )
1011  return nullptr;
1012 
1013  switch ( mStringType )
1014  {
1016  return new QgsLineString( mPoints ) ;
1017  break;
1019  if ( mPoints.count() != 3 )
1020  return nullptr;
1021  return new QgsCircularString(
1022  mPoints[0],
1023  mPoints[1],
1024  mPoints[2] ) ;
1025  break;
1026  default:
1027  return nullptr;
1028  }
1029 }
1030 
1031 bool QgsMapToolCaptureRubberBand::curveIsComplete() const
1032 {
1033  return ( mStringType == QgsWkbTypes::LineString && mPoints.count() > 1 ) ||
1034  ( mStringType == QgsWkbTypes::CircularString && mPoints.count() > 2 );
1035 }
1036 
1037 void QgsMapToolCaptureRubberBand::reset( QgsWkbTypes::GeometryType geomType, QgsWkbTypes::Type stringType, const QgsPoint &firstPolygonPoint )
1038 {
1039  if ( !( geomType == QgsWkbTypes::LineGeometry || geomType == QgsWkbTypes::PolygonGeometry ) )
1040  return;
1041 
1042  mPoints.clear();
1043  mFirstPolygonPoint = firstPolygonPoint;
1044  setStringType( stringType );
1045  setRubberBandGeometryType( geomType );
1046 }
1047 
1048 void QgsMapToolCaptureRubberBand::setRubberBandGeometryType( QgsWkbTypes::GeometryType geomType )
1049 {
1051  updateCurve();
1052 }
1053 
1054 void QgsMapToolCaptureRubberBand::addPoint( const QgsPoint &point, bool doUpdate )
1055 {
1056  if ( mPoints.count() == 0 )
1057  mPoints.append( point );
1058 
1059  mPoints.append( point );
1060 
1061  if ( doUpdate )
1062  updateCurve();
1063 }
1064 
1065 void QgsMapToolCaptureRubberBand::movePoint( const QgsPoint &point )
1066 {
1067  if ( mPoints.count() > 0 )
1068  mPoints.last() = point ;
1069 
1070  updateCurve();
1071 }
1072 
1073 void QgsMapToolCaptureRubberBand::movePoint( int index, const QgsPoint &point )
1074 {
1075  if ( mPoints.count() > 0 && mPoints.size() > index )
1076  mPoints[index] = point;
1077 
1078  updateCurve();
1079 }
1080 
1081 int QgsMapToolCaptureRubberBand::pointsCount()
1082 {
1083  return mPoints.size();
1084 }
1085 
1086 QgsWkbTypes::Type QgsMapToolCaptureRubberBand::stringType() const
1087 {
1088  return mStringType;
1089 }
1090 
1091 void QgsMapToolCaptureRubberBand::setStringType( const QgsWkbTypes::Type &type )
1092 {
1093  if ( ( type != QgsWkbTypes::CircularString && type != QgsWkbTypes::LineString ) || type == mStringType )
1094  return;
1095 
1096  mStringType = type;
1097  if ( type == QgsWkbTypes::LineString && mPoints.count() == 3 )
1098  {
1099  mPoints.removeAt( 1 );
1100  }
1101 
1102  setVertexDrawingEnabled( type == QgsWkbTypes::CircularString );
1103  updateCurve();
1104 }
1105 
1106 QgsPoint QgsMapToolCaptureRubberBand::lastPoint() const
1107 {
1108  if ( mPoints.empty() )
1109  return QgsPoint();
1110 
1111  return mPoints.last();
1112 }
1113 
1114 QgsPoint QgsMapToolCaptureRubberBand::pointFromEnd( int posFromEnd ) const
1115 {
1116  if ( posFromEnd < mPoints.size() )
1117  return mPoints.at( mPoints.size() - 1 - posFromEnd );
1118  else
1119  return QgsPoint();
1120 }
1121 
1122 void QgsMapToolCaptureRubberBand::removeLastPoint()
1123 {
1124  if ( mPoints.count() > 1 )
1125  mPoints.removeLast();
1126 
1127  updateCurve();
1128 }
1129 
1130 void QgsMapToolCaptureRubberBand::setGeometry( QgsAbstractGeometry *geom )
1131 {
1133 }
1134 
1135 void QgsMapToolCaptureRubberBand::updateCurve()
1136 {
1137  std::unique_ptr<QgsCurve> curve;
1138  switch ( mStringType )
1139  {
1141  curve.reset( createLinearString() );
1142  break;
1144  curve.reset( createCircularString() );
1145  break;
1146  default:
1147  return;
1148  break;
1149  }
1150 
1151  if ( geometryType() == QgsWkbTypes::PolygonGeometry )
1152  {
1153  std::unique_ptr<QgsCurvePolygon> geom( new QgsCurvePolygon );
1154  geom->setExteriorRing( curve.release() );
1155  setGeometry( geom.release() );
1156  }
1157  else
1158  {
1159  setGeometry( curve.release() );
1160  }
1161 }
1162 
1163 QgsCurve *QgsMapToolCaptureRubberBand::createLinearString()
1164 {
1165  std::unique_ptr<QgsLineString> curve( new QgsLineString );
1166  if ( geometryType() == QgsWkbTypes::PolygonGeometry )
1167  {
1168  QgsPointSequence points = mPoints;
1169  points.prepend( mFirstPolygonPoint );
1170  curve->setPoints( points );
1171  }
1172  else
1173  curve->setPoints( mPoints );
1174 
1175  return curve.release();
1176 }
1177 
1178 QgsCurve *QgsMapToolCaptureRubberBand::createCircularString()
1179 {
1180  std::unique_ptr<QgsCircularString> curve( new QgsCircularString );
1181  curve->setPoints( mPoints );
1182  if ( geometryType() == QgsWkbTypes::PolygonGeometry )
1183  {
1184  // add a linear string to close the polygon
1185  std::unique_ptr<QgsCompoundCurve> polygonCurve( new QgsCompoundCurve );
1186  polygonCurve->addVertex( mFirstPolygonPoint );
1187  if ( !mPoints.empty() )
1188  polygonCurve->addVertex( mPoints.first() );
1189  polygonCurve->addCurve( curve.release() );
1190  return polygonCurve.release();
1191  }
1192  else
1193  return curve.release();
1194 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
QgsMapToolEdit::digitizingStrokeWidth
static int digitizingStrokeWidth()
Returns stroke width for rubber bands (from global settings)
Definition: qgsmaptooledit.cpp:54
qgspolygon.h
QgsMapTool::mCanvas
QgsMapCanvas * mCanvas
pointer to map canvas
Definition: qgsmaptool.h:264
QgsVertexId::part
int part
Part number.
Definition: qgsabstractgeometry.h:1131
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:2115
QgsMapToolCapture::clearCurve
void clearCurve()
Clear capture curve.
Definition: qgsmaptoolcapture.cpp:667
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:89
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:43
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsabstractgeometry.h:1137
QgsFeature::id
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsAdvancedDigitizingDockWidget::removePreviousPoint
void removePreviousPoint()
Remove previous point in the CAD point list.
Definition: qgsadvanceddigitizingdockwidget.cpp:1164
QObjectUniquePtr::reset
void reset(T *p=nullptr)
Will reset the managed pointer to p.
Definition: qobjectuniqueptr.h:176
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:72
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:34
QgsLineString::length
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
Definition: qgslinestring.cpp:636
qgslinestring.h
QgsMapToolCapture::NoCapabilities
@ NoCapabilities
No specific capabilities.
Definition: qgsmaptoolcapture.h:140
QgsMapSettings::layerTransform
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
Definition: qgsmapsettings.cpp:419
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:38
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:541
QgsMapToolCapture::CaptureMode
CaptureMode
Different capture modes.
Definition: qgsmaptoolcapture.h:130
qgsgeometryrubberband.h
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:391
QgsTracer::init
bool init()
Build the internal data structures.
Definition: qgstracer.cpp:677
QgsRubberBand
A class for drawing transient features (e.g.
Definition: qgsrubberband.h:50
QgsGeometry::isNull
Q_GADGET bool isNull
Definition: qgsgeometry.h:126
QgsPointXY::x
Q_GADGET double x
Definition: qgspointxy.h:47
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:513
QgsCompoundCurve::nCurves
int nCurves() const SIP_HOLDGIL
Returns the number of curves in the geometry.
Definition: qgscompoundcurve.h:78
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:656
QgsCurvePolygon
Curve polygon geometry type.
Definition: qgscurvepolygon.h:35
QgsPolygon::setExteriorRing
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
Definition: qgspolygon.cpp:219
QgsWkbTypes::LineString
@ LineString
Definition: qgswkbtypes.h:73
qgsfeatureiterator.h
QgsCompoundCurve::addCurve
void addCurve(QgsCurve *c)
Adds a curve to the geometry (takes ownership)
Definition: qgscompoundcurve.cpp:460
QgsMapTool::setCursor
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:146
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:85
QgsMapToolAdvancedDigitizing::activate
void activate() override
Registers this maptool with the cad dock widget.
Definition: qgsmaptooladvanceddigitizing.cpp:121
QgsGeometry::Error
Definition: qgsgeometry.h:2059
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsPoint::z
double z
Definition: qgspoint.h:43
QgsRubberBand::getPoint
const QgsPointXY * getPoint(int i, int j=0, int ringIndex=0) const
Returns a vertex.
Definition: qgsrubberband.cpp:674
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
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:391
QgsCompoundCurve::close
void close()
Appends first point if not already closed.
Definition: qgscompoundcurve.cpp:828
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:164
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
QgsVectorLayer::startEditing
Q_INVOKABLE bool startEditing()
Makes the layer editable.
Definition: qgsvectorlayer.cpp:1428
QgsCompoundCurve::numPoints
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
Definition: qgscompoundcurve.cpp:361
QgsMapToolCapture::size
int size()
Number of points digitized.
Definition: qgsmaptoolcapture.cpp:878
QgsMapTool::canvas
QgsMapCanvas * canvas() const
returns pointer to the tool's map canvas
Definition: qgsmaptool.cpp:195
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:44
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:892
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:771
QgsCoordinateTransform::ReverseTransform
@ ReverseTransform
Transform from destination to source CRS.
Definition: qgscoordinatetransform.h:61
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsMapToolEdit::currentVectorLayer
QgsVectorLayer * currentVectorLayer()
Returns the current vector layer of the map canvas or 0.
Definition: qgsmaptooledit.cpp:94
QgsPointLocator::Match::hasVertex
bool hasVertex() const
Returns true if the Match is a vertex.
Definition: qgspointlocator.h:208
qgssnapindicator.h
QgsSnapIndicator
Class that shows snapping marker on map canvas for the current snapping match.
Definition: qgssnapindicator.h:33
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:2419
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:98
QgsCompoundCurve::startPoint
QgsPoint startPoint() const override SIP_HOLDGIL
Returns the starting point of the curve.
Definition: qgscompoundcurve.cpp:325
qgsrubberband.h
QgsPoint::dropMValue
bool dropMValue() override
Drops any measure values which exist in the geometry.
Definition: qgspoint.cpp:593
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:51
qgsapplication.h
QgsAbstractGeometry::isMeasure
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:215
QgsWkbTypes::PointM
@ PointM
Definition: qgswkbtypes.h:99
QObjectUniquePtr::release
T * release()
Clears the pointer and returns it.
Definition: qobjectuniqueptr.h:164
qgsmapcanvastracer.h
QgsVertexMarker
A class for marking vertices of features using e.g.
Definition: qgsvertexmarker.h:37
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:2942
QgsPointLocator::Match::vertexIndex
int vertexIndex() const
for vertex / edge match (first vertex of the edge)
Definition: qgspointlocator.h:231
QgsPoint::y
double y
Definition: qgspoint.h:42
QgsPointLocator::Match::hasEdge
bool hasEdge() const
Returns true if the Match is an edge.
Definition: qgspointlocator.h:210
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
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:626
QgsVectorDataProvider::capabilities
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Definition: qgsvectordataprovider.cpp:198
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:112
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
QgsMapToolCapture::~QgsMapToolCapture
~QgsMapToolCapture() override
Definition: qgsmaptoolcapture.cpp:69
QgsPoint::addMValue
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:552
QgsProject::topologicalEditing
bool topologicalEditing
Definition: qgsproject.h:111
QgsCircularString
Circular string geometry type.
Definition: qgscircularstring.h:35
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:193
QgsMapToolCapture::activate
void activate() override
Registers this maptool with the cad dock widget.
Definition: qgsmaptoolcapture.cpp:88
QgsMapToolCapture::undo
void undo()
Removes the last vertex from mRubberBand and mCaptureList.
Definition: qgsmaptoolcapture.cpp:678
QgsCompoundCurve::endPoint
QgsPoint endPoint() const override SIP_HOLDGIL
Returns the end point of the curve.
Definition: qgscompoundcurve.cpp:334
QgsCompoundCurve::addVertex
void addVertex(const QgsPoint &pt)
Adds a vertex to the end of the geometry.
Definition: qgscompoundcurve.cpp:502
QgsMapCanvasTracer
Extension of QgsTracer that provides extra functionality:
Definition: qgsmapcanvastracer.h:42
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:83
QgsGeometry::ValidatorQgisInternal
@ ValidatorQgisInternal
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:2114
QgsPoint::dropZValue
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
Definition: qgspoint.cpp:582
QgsVertexMarker::setPenWidth
void setPenWidth(int width)
Definition: qgsvertexmarker.cpp:54
QgsMapToolCapture::deleteTempRubberBand
void deleteTempRubberBand()
Clean a temporary rubberband.
Definition: qgsmaptoolcapture.cpp:788
QgsMapToolCapture::snappingMatches
QList< QgsPointLocator::Match > snappingMatches() const
Returns a list of matches for each point on the captureCurve.
Definition: qgsmaptoolcapture.cpp:673
QgsCompoundCurve::points
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
Definition: qgscompoundcurve.cpp:343
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1093
QgsMapToolCapture::setPoints
Q_DECL_DEPRECATED void setPoints(const QVector< QgsPointXY > &pointList)
Set the points on which to work.
Definition: qgsmaptoolcapture.cpp:898
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:86
QgsPoint::x
Q_GADGET double x
Definition: qgspoint.h:41
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:755
QgsRubberBand::numberOfVertices
int numberOfVertices() const
Returns count of vertices in all lists of mPoint.
Definition: qgsrubberband.cpp:661
QgsMapToolCapture::CapturePolygon
@ CapturePolygon
Capture polygons.
Definition: qgsmaptoolcapture.h:134
QgsMapToolCapture::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Intercept key events like Esc or Del to delete the last point.
Definition: qgsmaptoolcapture.cpp:737
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:73
QgsMapToolCapture::CaptureLine
@ CaptureLine
Capture lines.
Definition: qgsmaptoolcapture.h:133
QgsAdvancedDigitizingDockWidget
The QgsAdvancedDigitizingDockWidget class is a dockable widget used to handle the CAD tools on top of...
Definition: qgsadvanceddigitizingdockwidget.h:49
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsGeometryRubberBand::setGeometry
virtual void setGeometry(QgsAbstractGeometry *geom)
Sets geometry (takes ownership). Geometry is expected to be in map coordinates.
Definition: qgsgeometryrubberband.cpp:119
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:74
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
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:206
QgsMapToolCapture::isCapturing
bool isCapturing() const
Are we currently capturing?
Definition: qgsmaptoolcapture.cpp:760
QgsGeometry::vertexAt
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Definition: qgsgeometry.cpp:588
QgsMapToolEdit::digitizingFillColor
static QColor digitizingFillColor()
Returns fill color for rubber bands (from global settings)
Definition: qgsmaptooledit.cpp:60
QgsPointLocator::Match
Definition: qgspointlocator.h:185
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsCurve::clone
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
QgsMapToolCapture::clean
void clean() override
convenient method to clean members
Definition: qgsmaptoolcapture.cpp:793
QgsGeometryRubberBand
A rubberband class for QgsAbstractGeometry (considering curved geometries).
Definition: qgsgeometryrubberband.h:49
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:2131
QgsCompoundCurve::moveVertex
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
Definition: qgscompoundcurve.cpp:602
QgsVectorLayer::LayerOptions
Setting options for loading vector layers.
Definition: qgsvectorlayer.h:425
QgsGeometryRubberBand::setGeometryType
void setGeometryType(const QgsWkbTypes::GeometryType &geometryType)
Sets which geometry is handled by the rubber band, polygon or line.
Definition: qgsgeometryrubberband.cpp:78
QgsGeometry::get
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:133
QgsMapMouseEvent
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
Definition: qgsmapmouseevent.h:36
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:143
qgslayertreeview.h
QgsWkbTypes::CircularString
@ CircularString
Definition: qgswkbtypes.h:80
qgsadvanceddigitizingdockwidget.h
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
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:3020
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
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:342
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsCurve::vertexCount
int vertexCount(int part=0, int ring=0) const override
Returns the number of vertices of which this geometry is built.
Definition: qgscurve.cpp:171
QgsMapToolCapture::setCircularDigitizingEnabled
void setCircularDigitizingEnabled(bool enable)
Enable the digitizing with curve.
Definition: qgsmaptoolcapture.cpp:347
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:46
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
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
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:1541
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
QgsRubberBand::addGeometry
void addGeometry(const QgsGeometry &geometry, QgsVectorLayer *layer)
Adds the geometry of an existing feature to a rubberband This is useful for multi feature highlightin...
Definition: qgsrubberband.cpp:279
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
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:883
QgsMapToolCapture::CaptureNone
@ CaptureNone
Do not capture / determine mode from layer geometry type.
Definition: qgsmaptoolcapture.h:131
QgsMapToolCapture::CapturePoint
@ CapturePoint
Capture points.
Definition: qgsmaptoolcapture.h:132
qgsmaptoolcapture.h
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:627
QgsVertexId::ring
int ring
Ring number.
Definition: qgsabstractgeometry.h:1134
QgsMapToolCapture::stopCapturing
void stopCapturing()
Stop capturing.
Definition: qgsmaptoolcapture.cpp:765
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:957
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:453
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:610
QgsGeometry::ValidationMethod
ValidationMethod
Available methods for validating geometries.
Definition: qgsgeometry.h:2113
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1043
QgsGeometry::vertexIdFromVertexNr
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
Definition: qgsgeometry.cpp:2950
qgsexception.h
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsPoint::isEmpty
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspoint.cpp:742
QgsMapToolCapture::closePolygon
void closePolygon()
Close an open polygon.
Definition: qgsmaptoolcapture.cpp:799
QgsMapCanvas::currentLayer
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
Definition: qgsmapcanvas.cpp:512
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:97
QgsVectorLayer::getFeature
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
Definition: qgsvectorlayer.h:1194
QgsMapToolCapture::nextPoint
int nextPoint(const QgsPoint &mapPoint, QgsPoint &layerPoint)
Converts a map point to layer coordinates.
Definition: qgsmaptoolcapture.cpp:420
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:166
QgsCompoundCurve::deleteVertex
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Definition: qgscompoundcurve.cpp:619
QgsTracer::PathError
PathError
Possible errors that may happen when calling findShortestPath()
Definition: qgstracer.h:133
QgsSnappingUtils::removeExtraSnapLayer
void removeExtraSnapLayer(QgsVectorLayer *vl)
Removes an extra snapping layer.
Definition: qgssnappingutils.h:213
QgsPoint::setZ
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
Definition: qgspoint.h:293
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
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:53
qgsmapmouseevent.h
QgsGeometryValidator
Definition: qgsgeometryvalidator.h:29
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:483
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:37
QgsMapToolCapture::cadCanvasMoveEvent
void cadCanvasMoveEvent(QgsMapMouseEvent *e) override
Override this method when subclassing this class.
Definition: qgsmaptoolcapture.cpp:355
QgsVectorLayer::LayerOptions::skipCrsValidation
bool skipCrsValidation
Controls whether the layer is allowed to have an invalid/unknown CRS.
Definition: qgsvectorlayer.h:503
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:41
qgsgeometryvalidator.h
QgsCompoundCurve
Compound curve geometry type.
Definition: qgscompoundcurve.h:32
QgsMapToolEdit::digitizingStrokeColor
static QColor digitizingStrokeColor()
Returns stroke color for rubber bands (from global settings)
Definition: qgsmaptooledit.cpp:42
QgsMapMouseEvent::isSnapped
bool isSnapped() const
Returns true if there is a snapped point cached.
Definition: qgsmapmouseevent.h:82
QgsMapToolCapture::pointsZM
QgsPointSequence pointsZM() const
List of digitized points.
Definition: qgsmaptoolcapture.cpp:891
QgsMapToolEdit::defaultZValue
double defaultZValue() const
Returns default Z value Use for set Z coordinate to new vertex for 2.5d geometries.
Definition: qgsmaptooledit.cpp:37