QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
32 #include "qgsapplication.h"
34 #include "qgsproject.h"
38 #include "qgsgui.h"
39 
40 #include <QAction>
41 #include <QCursor>
42 #include <QPixmap>
43 #include <QStatusBar>
44 
45 
47  : QgsMapToolAdvancedDigitizing( canvas, cadDockWidget )
48  , mCaptureMode( mode )
49  , mCaptureModeFromLayer( mode == CaptureNone )
50 {
51  mTempRubberBand.setParentOwner( canvas );
52 
53  mSnapIndicator.reset( new QgsSnapIndicator( canvas ) );
54 
55  setCursor( QgsApplication::getThemeCursor( QgsApplication::Cursor::CapturePoint ) );
56 
58  this, &QgsMapToolCapture::currentLayerChanged );
59 
60  QgsVectorLayer::LayerOptions layerOptions;
61  layerOptions.skipCrsValidation = true;
62  layerOptions.loadDefaultStyle = false;
63  mExtraSnapLayer = new QgsVectorLayer( QStringLiteral( "LineString?crs=" ), QStringLiteral( "extra snap" ), QStringLiteral( "memory" ), layerOptions );
64  mExtraSnapLayer->startEditing();
65  QgsFeature f;
66  mExtraSnapLayer->addFeature( f );
67  mExtraSnapFeatureId = f.id();
68 
70  this, &QgsMapToolCapture::updateExtraSnapLayer );
71 
72  currentLayerChanged( canvas->currentLayer() );
73 }
74 
76 {
77  // during tear down we have to clean up mExtraSnapLayer first, before
78  // we call stop capturing. Otherwise stopCapturing tries to access members
79  // from the mapcanvas, which is likely already being destroyed and triggering
80  // the deletion of this object...
81  if ( mCanvas )
82  {
83  mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
84  }
85  mExtraSnapLayer->deleteLater();
86  mExtraSnapLayer = nullptr;
87 
88  stopCapturing();
89 
90  if ( mValidator )
91  {
92  mValidator->deleteLater();
93  mValidator = nullptr;
94  }
95 }
96 
97 QgsMapToolCapture::Capabilities QgsMapToolCapture::capabilities() const
98 {
100 }
101 
103 {
104  switch ( technique )
105  {
107  return true;
111  return false;
112  }
114 }
115 
117 {
118  if ( mTempRubberBand )
119  mTempRubberBand->show();
120 
121  mCanvas->snappingUtils()->addExtraSnapLayer( mExtraSnapLayer );
123 
124  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool )
125  mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
126 }
127 
129 {
130  if ( mTempRubberBand )
131  mTempRubberBand->hide();
132 
133  mSnapIndicator->setMatch( QgsPointLocator::Match() );
134 
135  mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
136 
137  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool )
138  mCurrentShapeMapTool->deactivate();
139 
141 }
142 
143 void QgsMapToolCapture::currentLayerChanged( QgsMapLayer *layer )
144 {
145  if ( !mCaptureModeFromLayer )
146  return;
147 
148  mCaptureMode = CaptureNone;
149 
150  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
151  if ( !vlayer )
152  {
153  return;
154  }
155 
156  switch ( vlayer->geometryType() )
157  {
159  mCaptureMode = CapturePoint;
160  break;
162  mCaptureMode = CaptureLine;
163  break;
165  mCaptureMode = CapturePolygon;
166  break;
167  default:
168  mCaptureMode = CaptureNone;
169  break;
170  }
171 
172  if ( mTempRubberBand )
173  mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
174 
175  resetRubberBand();
176  cadDockWidget()->switchZM();
177 }
178 
179 
180 bool QgsMapToolCapture::tracingEnabled()
181 {
183  return tracer && ( !tracer->actionEnableTracing() || tracer->actionEnableTracing()->isChecked() )
184  && ( !tracer->actionEnableSnapping() || tracer->actionEnableSnapping()->isChecked() );
185 }
186 
187 
188 QgsPointXY QgsMapToolCapture::tracingStartPoint()
189 {
190  // if we have starting point from previous trace, then preferably use that one
191  // (useful when tracing with offset)
192  if ( mTracingStartPoint != QgsPointXY() )
193  return mTracingStartPoint;
194 
195  return mCaptureLastPoint;
196 }
197 
198 
199 bool QgsMapToolCapture::tracingMouseMove( QgsMapMouseEvent *e )
200 {
201  if ( !e->isSnapped() )
202  return false;
203 
204  QgsPointXY pt0 = tracingStartPoint();
205  if ( pt0 == QgsPointXY() )
206  return false;
207 
209  if ( !tracer )
210  return false; // this should not happen!
211 
213  QVector<QgsPointXY> points = tracer->findShortestPath( pt0, e->mapPoint(), &err );
214  if ( points.isEmpty() )
215  {
216  tracer->reportError( err, false );
217  return false;
218  }
219 
220  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, QgsWkbTypes::LineString, mCaptureFirstPoint );
221  mTempRubberBand->addPoint( mCaptureLastPoint );
222 
223  // if there is offset, we need to fix the rubber bands to make sure they are aligned correctly.
224  // There are two cases we need to sort out:
225  // 1. the last point of mRubberBand may need to be moved off the traced curve to respect the offset
226  // 2. first point of mTempRubberBand may be needed to be moved to the beginning of the offset trace
227  const QgsPoint lastPoint = mCaptureLastPoint;
228  QgsPointXY lastPointXY( lastPoint );
229  if ( lastPointXY == pt0 && points[0] != lastPointXY )
230  {
231  if ( mRubberBand->numberOfVertices() != 0 )
232  {
233  // if rubber band had just one point, for some strange reason it contains the point twice
234  // we only want to move the last point if there are multiple points already
235  if ( mRubberBand->numberOfVertices() > 2 || ( mRubberBand->numberOfVertices() == 2 && *mRubberBand->getPoint( 0, 0 ) != *mRubberBand->getPoint( 0, 1 ) ) )
236  mRubberBand->movePoint( points[0] );
237  }
238 
239  mTempRubberBand->movePoint( 0, QgsPoint( points[0] ) );
240  }
241 
242  mTempRubberBand->movePoint( QgsPoint( points[0] ) );
243 
244  // update temporary rubberband
245  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
246  mTempRubberBand->addPoint( QgsPoint( points.at( i ) ), i == points.count() - 1 );
247 
248 
249  mTempRubberBand->addPoint( QgsPoint( points[points.size() - 1] ) );
250 
251  tracer->reportError( QgsTracer::ErrNone, false ); // clear messagebar if there was any error
252  return true;
253 }
254 
255 
256 bool QgsMapToolCapture::tracingAddVertex( const QgsPointXY &point )
257 {
259  if ( !tracer )
260  return false; // this should not happen!
261 
262  if ( mTempRubberBand->pointsCount() == 0 )
263  {
264  if ( !tracer->init() )
265  {
267  return false;
268  }
269 
270  // only accept first point if it is snapped to the graph (to vertex or edge)
271  const bool res = tracer->isPointSnapped( point );
272  if ( res )
273  {
274  mTracingStartPoint = point;
275  }
276  return false;
277  }
278 
279  QgsPointXY pt0 = tracingStartPoint();
280  if ( pt0 == QgsPointXY() )
281  return false;
282 
284  QVector<QgsPointXY> points = tracer->findShortestPath( pt0, point, &err );
285  if ( points.isEmpty() )
286  return false; // ignore the vertex - can't find path to the end point!
287 
288  // transform points
289  QgsPointSequence layerPoints;
290  QgsPoint lp; // in layer coords
291  for ( int i = 0; i < points.count(); ++i )
292  {
293  if ( nextPoint( QgsPoint( points[i] ), lp ) != 0 )
294  return false;
295  layerPoints << lp;
296  }
297 
298  // Move the last point of the captured curve to the first point on the trace string (necessary if there is offset)
299  const QgsVertexId lastVertexId( 0, 0, mCaptureCurve.numPoints() - 1 );
300  mCaptureCurve.moveVertex( lastVertexId, layerPoints.first() );
301  mSnappingMatches.removeLast();
302  mSnappingMatches.append( QgsPointLocator::Match() );
303 
304  int pointBefore = mCaptureCurve.numPoints();
305  addCurve( new QgsLineString( layerPoints ) );
306 
307  resetRubberBand();
308 
309  // Curves de-approximation
311  {
312  // If the tool and the layer support curves
313  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer() );
314  if ( vlayer && capabilities().testFlag( QgsMapToolCapture::Capability::SupportsCurves ) && vlayer->dataProvider()->capabilities().testFlag( QgsVectorDataProvider::Capability::CircularGeometries ) )
315  {
316  const QgsGeometry linear = QgsGeometry( mCaptureCurve.segmentize() );
317  const QgsGeometry curved = linear.convertToCurves(
320  );
322  {
323  mCaptureCurve.clear();
324  mCaptureCurve.addCurve( qgsgeometry_cast< const QgsCurve * >( curved.constGet() )->clone() );
325  }
326  else
327  {
328  mCaptureCurve = *qgsgeometry_cast<QgsCompoundCurve *>( curved.constGet() );
329  }
330  }
331  }
332 
333  // sync the snapping matches list
334  const int pointAfter = mCaptureCurve.numPoints();
335  for ( ; pointBefore < pointAfter; ++pointBefore )
336  mSnappingMatches.append( QgsPointLocator::Match() );
337 
338  tracer->reportError( QgsTracer::ErrNone, true ); // clear messagebar if there was any error
339 
340  // adjust last captured point
341  const QgsPoint lastPt = mCaptureCurve.endPoint();
342  mCaptureLastPoint = toMapCoordinates( layer(), lastPt );
343 
344  return true;
345 }
346 
347 QgsMapToolCaptureRubberBand *QgsMapToolCapture::createCurveRubberBand() const
348 {
349  QgsMapToolCaptureRubberBand *rb = new QgsMapToolCaptureRubberBand( mCanvas );
350  rb->setStrokeWidth( digitizingStrokeWidth() );
351  QColor color = digitizingStrokeColor();
352 
354  color.setAlphaF( color.alphaF() * alphaScale );
355  rb->setLineStyle( Qt::DotLine );
356  rb->setStrokeColor( color );
357 
358  const QColor fillColor = digitizingFillColor();
359  rb->setFillColor( fillColor );
360  rb->show();
361  return rb;
362 }
363 
364 void QgsMapToolCapture::resetRubberBand()
365 {
366  if ( !mRubberBand )
367  return;
368  QgsLineString *lineString = mCaptureCurve.curveToLine();
369 
371  mRubberBand->addGeometry( QgsGeometry( lineString ), layer() );
372 }
373 
375 {
376  return mRubberBand.release();
377 }
378 
380 {
381  if ( enable )
383  else
385 }
386 
388 {
389  if ( enable )
391  else
393 }
394 
396 {
397  if ( mCurrentCaptureTechnique == technique )
398  return;
399 
400  mStartNewCurve = true;
401 
402  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool )
403  {
404  mCurrentShapeMapTool->deactivate();
405  clean();
406  }
407 
408  switch ( technique )
409  {
411  mLineDigitizingType = QgsWkbTypes::LineString;
412  break;
414  mLineDigitizingType = QgsWkbTypes::CircularString;
415  break;
417  mLineDigitizingType = QgsWkbTypes::LineString;
419  break;
421  mLineDigitizingType = QgsWkbTypes::LineString;
422  break;
423 
424  }
425 
426  if ( mTempRubberBand )
427  mTempRubberBand->setStringType( mLineDigitizingType );
428 
429  mCurrentCaptureTechnique = technique;
430 
431  if ( technique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool && isActive() )
432  {
433  clean();
434  mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
435  }
436 }
437 
439 {
440  if ( mCurrentShapeMapTool )
441  {
442  if ( shapeMapToolMetadata && mCurrentShapeMapTool->id() == shapeMapToolMetadata->id() )
443  return;
444  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape )
445  mCurrentShapeMapTool->deactivate();
446  mCurrentShapeMapTool->deleteLater();
447  }
448 
449  mCurrentShapeMapTool.reset( shapeMapToolMetadata ? shapeMapToolMetadata->factory( this ) : nullptr );
450 
451  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && isActive() )
452  {
453  clean();
454  if ( mCurrentShapeMapTool )
455  mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
456  }
457 }
458 
460 {
462 
463  const QgsPointXY point = e->mapPoint();
464 
465  mSnapIndicator->setMatch( e->mapPointMatch() );
466 
467  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape )
468  {
469  if ( !mCurrentShapeMapTool )
470  {
471  emit messageEmitted( tr( "Select an option from the Shape Digitizing Toolbar in order to capture shapes" ), Qgis::MessageLevel::Warning );
472  }
473  else
474  {
475  if ( !mTempRubberBand )
476  {
477  mTempRubberBand.reset( createCurveRubberBand() );
478  mTempRubberBand->setStringType( mLineDigitizingType );
479  mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
480  }
481 
482  mCurrentShapeMapTool->cadCanvasMoveEvent( e, mCaptureMode );
483  return;
484  }
485  }
486  else
487  {
488  const QgsPoint mapPoint = QgsPoint( point );
489 
490  if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
491  {
492  bool hasTrace = false;
493 
494  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Streaming )
495  {
496  if ( !mCaptureCurve.isEmpty() )
497  {
498  const QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint();
499  if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( layer(), prevPoint ) ) ).distance( toCanvasCoordinates( point ) ) < mStreamingToleranceInPixels )
500  return;
501  }
502 
503  mAllowAddingStreamingPoints = true;
504  addVertex( mapPoint );
505  mAllowAddingStreamingPoints = false;
506  }
507  else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
508  {
509  // Store the intermediate point for circular string to retrieve after tracing mouse move if
510  // the digitizing type is circular and the temp rubber band is effectivly circular and if this point is existing
511  // Store an empty point if the digitizing type is linear ot the point is not existing (curve not complete)
512  if ( mLineDigitizingType == QgsWkbTypes::CircularString &&
513  mTempRubberBand->stringType() == QgsWkbTypes::CircularString &&
514  mTempRubberBand->curveIsComplete() )
515  mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 );
516  else if ( mLineDigitizingType == QgsWkbTypes::LineString ||
517  !mTempRubberBand->curveIsComplete() )
518  mCircularItermediatePoint = QgsPoint();
519 
520  hasTrace = tracingMouseMove( e );
521 
522  if ( !hasTrace )
523  {
524  // Restore the temp rubber band
525  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
526  mTempRubberBand->addPoint( mCaptureLastPoint );
527  if ( !mCircularItermediatePoint.isEmpty() )
528  {
529  mTempRubberBand->movePoint( mCircularItermediatePoint );
530  mTempRubberBand->addPoint( mCircularItermediatePoint );
531  }
532  }
533  }
534 
535  if ( mCurrentCaptureTechnique != Qgis::CaptureTechnique::Streaming && !hasTrace )
536  {
537  if ( mCaptureCurve.numPoints() > 0 )
538  {
539  const QgsPoint mapPt = mCaptureLastPoint;
540 
541  if ( mTempRubberBand )
542  {
543  mTempRubberBand->movePoint( mapPoint );
544  mTempRubberBand->movePoint( 0, mapPt );
545  }
546 
547  // fix existing rubber band after tracing - the last point may have been moved if using offset
548  if ( mRubberBand->numberOfVertices() )
549  mRubberBand->movePoint( mapPt );
550  }
551  else if ( mTempRubberBand )
552  mTempRubberBand->movePoint( mapPoint );
553  }
554  }
555  }
556 } // mouseMoveEvent
557 
558 
559 int QgsMapToolCapture::nextPoint( const QgsPoint &mapPoint, QgsPoint &layerPoint )
560 {
561  if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer() ) )
562  {
563  try
564  {
565  const QgsPointXY mapP( mapPoint.x(), mapPoint.y() ); //#spellok
566  layerPoint = QgsPoint( toLayerCoordinates( vlayer, mapP ) ); //transform snapped point back to layer crs //#spellok
567  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) && !layerPoint.is3D() )
569  if ( QgsWkbTypes::hasM( vlayer->wkbType() ) && !layerPoint.isMeasure() )
571  }
572  catch ( QgsCsException & )
573  {
574  QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
575  return 2;
576  }
577  }
578  else
579  {
580  layerPoint = QgsPoint( toLayerCoordinates( layer(), mapPoint ) );
581  }
582 
583  return 0;
584 }
585 
586 int QgsMapToolCapture::nextPoint( QPoint p, QgsPoint &layerPoint, QgsPoint &mapPoint )
587 {
589  return nextPoint( mapPoint, layerPoint );
590 }
591 
593 {
594  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer() );
595  QgsVectorLayer *sourceLayer = match.layer();
597  {
599  return 0;
600  }
601  else if ( !vlayer )
602  {
603  return 1;
604  }
605  else
606  {
607  if ( match.isValid() && ( match.hasVertex() || match.hasLineEndpoint() || ( QgsProject::instance()->topologicalEditing() && ( match.hasEdge() || match.hasMiddleSegment() ) ) ) && sourceLayer &&
608  ( sourceLayer->crs() == vlayer->crs() ) )
609  {
610  QgsFeature f;
611  QgsFeatureRequest request;
612  request.setFilterFid( match.featureId() );
613  const bool fetched = match.layer()->getFeatures( request ).nextFeature( f );
614  if ( fetched )
615  {
616  QgsVertexId vId;
617  if ( !f.geometry().vertexIdFromVertexNr( match.vertexIndex(), vId ) )
618  return 2;
619 
620  const QgsGeometry geom( f.geometry() );
621  if ( QgsProject::instance()->topologicalEditing() && ( match.hasEdge() || match.hasMiddleSegment() ) )
622  {
623  QgsVertexId vId2;
624  if ( !f.geometry().vertexIdFromVertexNr( match.vertexIndex() + 1, vId2 ) )
625  return 2;
626  const QgsLineString line( geom.constGet()->vertexAt( vId ), geom.constGet()->vertexAt( vId2 ) );
627 
628  layerPoint = QgsGeometryUtils::closestPoint( line, QgsPoint( match.point() ) );
629  }
630  else
631  {
632  layerPoint = geom.constGet()->vertexAt( vId );
633  if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) && !layerPoint.is3D() )
634  layerPoint.addZValue( defaultZValue() );
635  if ( QgsWkbTypes::hasM( vlayer->wkbType() ) && !layerPoint.isMeasure() )
636  layerPoint.addMValue( defaultMValue() );
637  }
638 
639  // ZM support depends on the target layer
640  if ( !QgsWkbTypes::hasZ( vlayer->wkbType() ) )
641  {
642  layerPoint.dropZValue();
643  }
644 
645  if ( !QgsWkbTypes::hasM( vlayer->wkbType() ) )
646  {
647  layerPoint.dropMValue();
648  }
649 
650  return 0;
651  }
652  else
653  {
654  return 2;
655  }
656  }
657  else
658  {
659  return 1;
660  }
661  }
662 }
663 
665 {
666  return addVertex( point, QgsPointLocator::Match() );
667 }
668 
670 {
671  if ( mode() == CaptureNone )
672  {
673  QgsDebugMsg( QStringLiteral( "invalid capture mode" ) );
674  return 2;
675  }
676 
677  if ( mCapturing && mCurrentCaptureTechnique == Qgis::CaptureTechnique::Streaming && !mAllowAddingStreamingPoints )
678  return 0;
679 
680  QgsPoint layerPoint;
681  if ( layer() )
682  {
683  int res = fetchLayerPoint( match, layerPoint );
684  if ( res != 0 )
685  {
686  res = nextPoint( QgsPoint( point ), layerPoint );
687  if ( res != 0 )
688  {
689  return res;
690  }
691  }
692  }
693  else
694  {
695  layerPoint = QgsPoint( point );
696  }
697  const QgsPoint mapPoint = toMapCoordinates( layer(), layerPoint );
698 
699  if ( mCaptureMode == CapturePoint )
700  {
701  mCaptureCurve.addVertex( layerPoint );
702  mSnappingMatches.append( match );
703  }
704  else
705  {
706  if ( mCaptureFirstPoint.isEmpty() )
707  {
708  mCaptureFirstPoint = mapPoint;
709  }
710 
711  if ( !mRubberBand )
713 
714  if ( !mTempRubberBand )
715  {
716  mTempRubberBand.reset( createCurveRubberBand() );
717  mTempRubberBand->setStringType( mLineDigitizingType );
718  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mapPoint );
719  }
720 
721  bool traceCreated = false;
722  if ( tracingEnabled() )
723  {
724  traceCreated = tracingAddVertex( mapPoint );
725  }
726 
727  // keep new tracing start point if we created a trace. This is useful when tracing with
728  // offset so that the user stays "snapped"
729  mTracingStartPoint = traceCreated ? point : QgsPointXY();
730 
731  if ( !traceCreated )
732  {
733  // ordinary digitizing
734  mTempRubberBand->movePoint( mapPoint ); //move the last point of the temp rubberband before operating with it
735  if ( mTempRubberBand->curveIsComplete() ) //2 points for line and 3 points for circular
736  {
737  if ( QgsCurve *curve = mTempRubberBand->curve() )
738  {
739  addCurve( curve );
740  // add curve append only invalid match to mSnappingMatches,
741  // so we need to remove them and add the one from here if it is valid
742  if ( match.isValid() && mSnappingMatches.count() > 0 && !mSnappingMatches.last().isValid() )
743  {
744  mSnappingMatches.removeLast();
745  if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString )
746  {
747  // for circular string two points are added and match for intermediate point is stored
748  mSnappingMatches.removeLast();
749  mSnappingMatches.append( mCircularIntermediateMatch );
750  }
751  mSnappingMatches.append( match );
752  }
753  }
754  mCaptureLastPoint = mapPoint;
755  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
756  }
757  else if ( mTempRubberBand->pointsCount() == 0 )
758  {
759  mCaptureLastPoint = mapPoint;
760  mCaptureCurve.addVertex( layerPoint );
761  mSnappingMatches.append( match );
762  }
763  else
764  {
765  if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString )
766  {
767  mCircularIntermediateMatch = match;
768  }
769  }
770 
771  mTempRubberBand->addPoint( mapPoint );
772  }
773  else
774  {
775  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
776  mTempRubberBand->addPoint( mCaptureLastPoint );
777  }
778  }
779 
780  updateExtraSnapLayer();
781  validateGeometry();
782 
783  return 0;
784 }
785 
787 {
788  if ( !c )
789  {
790  return 1;
791  }
792 
793  if ( !mRubberBand )
794  {
796  }
797 
798  if ( mTempRubberBand )
799  {
800  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
801  const QgsPoint endPt = c->endPoint();
802  mTempRubberBand->addPoint( endPt ); //add last point of c
803  }
804 
805  //transform back to layer CRS in case map CRS and layer CRS are different
806  const QgsCoordinateTransform ct = mCanvas->mapSettings().layerTransform( layer() );
807  if ( ct.isValid() )
808  {
809  c->transform( ct, Qgis::TransformDirection::Reverse );
810  }
811  const int countBefore = mCaptureCurve.vertexCount();
812  //if there is only one point, this the first digitized point that are in the this first curve added --> remove the point
813  if ( mCaptureCurve.numPoints() == 1 )
814  mCaptureCurve.removeCurve( 0 );
815 
816  // we set the extendPrevious option to true to avoid creating compound curves with many 2 vertex linestrings -- instead we prefer
817  // to extend linestring curves so that they continue the previous linestring wherever possible...
818  mCaptureCurve.addCurve( c, !mStartNewCurve );
819  mStartNewCurve = false;
820 
821  const int countAfter = mCaptureCurve.vertexCount();
822  const int addedPoint = countAfter - countBefore;
823 
824  updateExtraSnapLayer();
825 
826  for ( int i = 0; i < addedPoint; ++i )
827  mSnappingMatches.append( QgsPointLocator::Match() );
828 
829  resetRubberBand();
830 
831  return 0;
832 }
833 
835 {
836  mCaptureCurve.clear();
837  updateExtraSnapLayer();
838 }
839 
840 QList<QgsPointLocator::Match> QgsMapToolCapture::snappingMatches() const
841 {
842  return mSnappingMatches;
843 }
844 
845 void QgsMapToolCapture::undo( bool isAutoRepeat )
846 {
847  mTracingStartPoint = QgsPointXY();
848 
849  if ( mTempRubberBand )
850  {
851  if ( size() <= 1 && mTempRubberBand->pointsCount() != 0 )
852  return;
853 
854  if ( isAutoRepeat && mIgnoreSubsequentAutoRepeatUndo )
855  return;
856  mIgnoreSubsequentAutoRepeatUndo = false;
857 
858  const QgsPoint lastPoint = mTempRubberBand->lastPoint();
859 
860  if ( mTempRubberBand->stringType() == QgsWkbTypes::CircularString && mTempRubberBand->pointsCount() > 2 )
861  {
862  mTempRubberBand->removeLastPoint();
863  mTempRubberBand->movePoint( lastPoint );
864  return;
865  }
866 
867  QgsVertexId vertexToRemove;
868  vertexToRemove.part = 0;
869  vertexToRemove.ring = 0;
870  vertexToRemove.vertex = size() - 1;
871  if ( mCaptureCurve.numPoints() == 2 && mCaptureCurve.nCurves() == 1 )
872  {
873  // store the first vertex to restore if after deleting the curve
874  // because when only two vertices, removing a point remove all the curve
875  const QgsPoint fp = mCaptureCurve.startPoint();
876  mCaptureCurve.deleteVertex( vertexToRemove );
877  mCaptureCurve.addVertex( fp );
878  }
879  else
880  {
881  const int curvesBefore = mCaptureCurve.nCurves();
882  const bool lastCurveIsLineString = qgsgeometry_cast< QgsLineString * >( mCaptureCurve.curveAt( curvesBefore - 1 ) );
883 
884  const int pointsCountBefore = mCaptureCurve.numPoints();
885  mCaptureCurve.deleteVertex( vertexToRemove );
886  int pointsCountAfter = mCaptureCurve.numPoints();
887  for ( ; pointsCountAfter < pointsCountBefore; pointsCountAfter++ )
888  if ( !mSnappingMatches.empty() )
889  mSnappingMatches.removeLast();
890 
891  // if we have removed the last point in a linestring curve, then we "stick" here and ignore subsequent
892  // autorepeat undo actions until the user releases the undo key and holds it down again. This allows
893  // users to selectively remove portions of the geometry captured with the streaming mode by holding down
894  // the undo key, without risking accidental undo of non-streamed portions.
895  if ( mCaptureCurve.nCurves() < curvesBefore && lastCurveIsLineString )
896  mIgnoreSubsequentAutoRepeatUndo = true;
897  }
898 
899  updateExtraSnapLayer();
900 
901  resetRubberBand();
902 
903  mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
904 
905  if ( mCaptureCurve.numPoints() > 0 )
906  {
907  const QgsPoint lastPt = mCaptureCurve.endPoint();
908  mCaptureLastPoint = toMapCoordinates( layer(), lastPt );
909  mTempRubberBand->addPoint( mCaptureLastPoint );
910  mTempRubberBand->movePoint( lastPoint );
911  }
912 
914  validateGeometry();
915  }
916 }
917 
919 {
920  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool )
921  {
922  mCurrentShapeMapTool->keyPressEvent( e );
923  if ( e->isAccepted() )
924  return;
925  }
926 
927  // this is backwards, but we can't change now without breaking api because
928  // forever QgsMapTools have had to explicitly mark events as ignored in order to
929  // indicate that they've consumed the event and that the default behavior should not
930  // be applied..!
931  // see QgsMapCanvas::keyPressEvent
932  e->accept();
933 
934  if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
935  {
936  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool )
937  {
938  if ( !e->isAutoRepeat() )
939  {
940  mCurrentShapeMapTool->undo();
941  }
942  }
943  else
944  {
945  undo( e->isAutoRepeat() );
946  }
947 
948  // Override default shortcut management in MapCanvas
949  e->ignore();
950  }
951  else if ( e->key() == Qt::Key_Escape )
952  {
953  if ( mCurrentShapeMapTool )
954  mCurrentShapeMapTool->clean();
955 
956  stopCapturing();
957 
958  // Override default shortcut management in MapCanvas
959  e->ignore();
960  }
961 }
962 
964 {
965  mCapturing = true;
966 }
967 
969 {
970  return mCapturing;
971 }
972 
974 {
975  mRubberBand.reset();
976 
978 
979  qDeleteAll( mGeomErrorMarkers );
980  mGeomErrorMarkers.clear();
981  mGeomErrors.clear();
982 
983  mCaptureFirstPoint = QgsPoint();
984  mCaptureLastPoint = QgsPoint();
985 
986  mTracingStartPoint = QgsPointXY();
987 
988  mCapturing = false;
989  mCaptureCurve.clear();
990  updateExtraSnapLayer();
991  mSnappingMatches.clear();
992  if ( auto *lCurrentVectorLayer = currentVectorLayer() )
993  lCurrentVectorLayer->triggerRepaint();
994 }
995 
997 {
998  mTempRubberBand.reset();
999 }
1000 
1002 {
1003  stopCapturing();
1004  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape && mCurrentShapeMapTool )
1005  mCurrentShapeMapTool->clean();
1006 
1007  clearCurve();
1008 }
1009 
1011 {
1012  mCaptureCurve.close();
1013  updateExtraSnapLayer();
1014 }
1015 
1016 void QgsMapToolCapture::validateGeometry()
1017 {
1019  || !( capabilities() & ValidateGeometries )
1020  )
1021  return;
1022 
1023  if ( mValidator )
1024  {
1025  mValidator->deleteLater();
1026  mValidator = nullptr;
1027  }
1028 
1029  mGeomErrors.clear();
1030  while ( !mGeomErrorMarkers.isEmpty() )
1031  {
1032  delete mGeomErrorMarkers.takeFirst();
1033  }
1034 
1035  QgsGeometry geom;
1036 
1037  switch ( mCaptureMode )
1038  {
1039  case CaptureNone:
1040  case CapturePoint:
1041  return;
1042  case CaptureLine:
1043  if ( size() < 2 )
1044  return;
1045  geom = QgsGeometry( mCaptureCurve.curveToLine() );
1046  break;
1047  case CapturePolygon:
1048  if ( size() < 3 )
1049  return;
1050  QgsLineString *exteriorRing = mCaptureCurve.curveToLine();
1051  exteriorRing->close();
1052  QgsPolygon *polygon = new QgsPolygon();
1053  polygon->setExteriorRing( exteriorRing );
1054  geom = QgsGeometry( polygon );
1055  break;
1056  }
1057 
1058  if ( geom.isNull() )
1059  return;
1060 
1061  Qgis::GeometryValidationEngine method = Qgis::GeometryValidationEngine::QgisInternal;
1063  method = Qgis::GeometryValidationEngine::Geos;
1064  mValidator = new QgsGeometryValidator( geom, nullptr, method );
1065  connect( mValidator, &QgsGeometryValidator::errorFound, this, &QgsMapToolCapture::addError );
1066  mValidator->start();
1067  QgsDebugMsgLevel( QStringLiteral( "Validation started" ), 4 );
1068 }
1069 
1070 void QgsMapToolCapture::addError( const QgsGeometry::Error &e )
1071 {
1072  mGeomErrors << e;
1073  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer() );
1074  if ( !vlayer )
1075  return;
1076 
1077  if ( e.hasWhere() )
1078  {
1080  vm->setCenter( mCanvas->mapSettings().layerToMapCoordinates( vlayer, e.where() ) );
1082  vm->setPenWidth( 2 );
1083  vm->setToolTip( e.what() );
1084  vm->setColor( Qt::green );
1085  vm->setZValue( vm->zValue() + 1 );
1086  mGeomErrorMarkers << vm;
1087  }
1088 }
1089 
1091 {
1092  return mCaptureCurve.numPoints();
1093 }
1094 
1095 QVector<QgsPointXY> QgsMapToolCapture::points() const
1096 {
1097  QVector<QgsPointXY> pointsXY;
1098  QgsGeometry::convertPointList( pointsZM(), pointsXY );
1099 
1100  return pointsXY;
1101 }
1102 
1104 {
1105  QgsPointSequence pts;
1106  mCaptureCurve.points( pts );
1107  return pts;
1108 }
1109 
1110 void QgsMapToolCapture::setPoints( const QVector<QgsPointXY> &pointList )
1111 {
1112  QgsLineString *line = new QgsLineString( pointList );
1113  mCaptureCurve.clear();
1114  mCaptureCurve.addCurve( line );
1115  updateExtraSnapLayer();
1116  mSnappingMatches.clear();
1117  for ( int i = 0; i < line->length(); ++i )
1118  mSnappingMatches.append( QgsPointLocator::Match() );
1119  resetRubberBand();
1120 }
1121 
1123 {
1124  QgsLineString *line = new QgsLineString( pointList );
1125  mCaptureCurve.clear();
1126  mCaptureCurve.addCurve( line );
1127  updateExtraSnapLayer();
1128  mSnappingMatches.clear();
1129  for ( int i = 0; i < line->length(); ++i )
1130  mSnappingMatches.append( QgsPointLocator::Match() );
1131  resetRubberBand();
1132 }
1133 
1135 {
1136  QgsPoint newPoint( QgsWkbTypes::Point, point.x(), point.y() );
1137 
1138  // get current layer
1139  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer() );
1140  if ( !vlayer )
1141  {
1142  return newPoint;
1143  }
1144 
1145  // convert to the corresponding type for a full ZM support
1146  const QgsWkbTypes::Type type = vlayer->wkbType();
1147  if ( QgsWkbTypes::hasZ( type ) && !QgsWkbTypes::hasM( type ) )
1148  {
1149  newPoint.convertTo( QgsWkbTypes::PointZ );
1150  }
1151  else if ( !QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
1152  {
1153  newPoint.convertTo( QgsWkbTypes::PointM );
1154  }
1155  else if ( QgsWkbTypes::hasZ( type ) && QgsWkbTypes::hasM( type ) )
1156  {
1157  newPoint.convertTo( QgsWkbTypes::PointZM );
1158  }
1159 
1160  // set z value if necessary
1161  if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) )
1162  {
1164  }
1165  // set m value if necessary
1166  if ( QgsWkbTypes::hasM( newPoint.wkbType() ) )
1167  {
1169  }
1170  return newPoint;
1171 }
1172 
1174 {
1175  QgsPoint newPoint = mapPoint( e.mapPoint() );
1176 
1177  // set z or m value from snapped point if necessary
1178  if ( QgsWkbTypes::hasZ( newPoint.wkbType() ) || QgsWkbTypes::hasM( newPoint.wkbType() ) )
1179  {
1180  // if snapped, z and m dimension are taken from the corresponding snapped
1181  // point.
1182  if ( e.isSnapped() )
1183  {
1184  const QgsPointLocator::Match match = e.mapPointMatch();
1185 
1186  if ( match.layer() )
1187  {
1188  const QgsFeature ft = match.layer()->getFeature( match.featureId() );
1189  if ( QgsWkbTypes::hasZ( match.layer()->wkbType() ) )
1190  {
1191  newPoint.setZ( ft.geometry().vertexAt( match.vertexIndex() ).z() );
1192  }
1193  if ( QgsWkbTypes::hasM( match.layer()->wkbType() ) )
1194  {
1195  newPoint.setM( ft.geometry().vertexAt( match.vertexIndex() ).m() );
1196  }
1197  }
1198  }
1199  }
1200 
1201  return newPoint;
1202 }
1203 
1204 void QgsMapToolCapture::updateExtraSnapLayer()
1205 {
1206  if ( !mExtraSnapLayer )
1207  return;
1208 
1209  if ( canvas()->snappingUtils()->config().selfSnapping() && layer() && mCaptureCurve.numPoints() >= 2 )
1210  {
1211  // the current layer may have changed
1212  mExtraSnapLayer->setCrs( layer()->crs() );
1213  QgsGeometry geom = QgsGeometry( mCaptureCurve.clone() );
1214  // we close the curve to allow snapping on last segment
1215  if ( mCaptureMode == CapturePolygon && mCaptureCurve.numPoints() >= 3 )
1216  {
1217  qgsgeometry_cast<QgsCompoundCurve *>( geom.get() )->close();
1218  }
1219  mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
1220  }
1221  else
1222  {
1223  QgsGeometry geom;
1224  mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
1225  }
1226 }
1227 
1228 
1230 {
1231  // POINT CAPTURING
1232  if ( mode() == CapturePoint )
1233  {
1234  if ( e->button() != Qt::LeftButton )
1235  return;
1236 
1237  QgsPoint savePoint; //point in layer coordinates
1238  bool isMatchPointZ = false;
1239  bool isMatchPointM = false;
1240  try
1241  {
1242  QgsPoint fetchPoint;
1243  int res = fetchLayerPoint( e->mapPointMatch(), fetchPoint );
1244  isMatchPointZ = QgsWkbTypes::hasZ( fetchPoint.wkbType() );
1245  isMatchPointM = QgsWkbTypes::hasM( fetchPoint.wkbType() );
1246 
1247  if ( res == 0 )
1248  {
1249  QgsWkbTypes::Type geomType = QgsWkbTypes::Type::Point;
1250  if ( isMatchPointM && isMatchPointZ )
1251  {
1252  geomType = QgsWkbTypes::Type::PointZM;
1253  }
1254  else if ( isMatchPointM )
1255  {
1256  geomType = QgsWkbTypes::Type::PointM;
1257  }
1258  else if ( isMatchPointZ )
1259  {
1260  geomType = QgsWkbTypes::Type::PointZ;
1261  }
1262  savePoint = QgsPoint( geomType, fetchPoint.x(), fetchPoint.y(), fetchPoint.z(), fetchPoint.m() );
1263  }
1264  else
1265  {
1266  QgsPointXY point = mCanvas->mapSettings().mapToLayerCoordinates( layer(), e->mapPoint() );
1267 
1268  savePoint = QgsPoint( point.x(), point.y(), fetchPoint.z(), fetchPoint.m() );
1269  }
1270  }
1271  catch ( QgsCsException &cse )
1272  {
1273  Q_UNUSED( cse )
1274  emit messageEmitted( tr( "Cannot transform the point to the layer's coordinate system" ), Qgis::MessageLevel::Warning );
1275  return;
1276  }
1277 
1278  QgsGeometry g( std::make_unique<QgsPoint>( savePoint ) );
1279 
1280  // The snapping result needs to be added so it's available in the @snapping_results variable of default value etc. expression contexts
1281  addVertex( e->mapPoint(), e->mapPointMatch() );
1282 
1283  geometryCaptured( g );
1284  pointCaptured( savePoint );
1285 
1286  stopCapturing();
1287 
1288  // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points
1290  }
1291 
1292  // LINE AND POLYGON CAPTURING
1293  else if ( mode() == CaptureLine || mode() == CapturePolygon )
1294  {
1295  bool digitizingFinished = false;
1296 
1297  if ( mCurrentCaptureTechnique == Qgis::CaptureTechnique::Shape )
1298  {
1299  if ( !mCurrentShapeMapTool )
1300  {
1301  emit messageEmitted( tr( "Select an option from the Shape Digitizing Toolbar in order to capture shapes" ), Qgis::MessageLevel::Warning );
1302  return;
1303  }
1304  else
1305  {
1306  if ( !mTempRubberBand )
1307  {
1308  mTempRubberBand.reset( createCurveRubberBand() );
1309  mTempRubberBand->setStringType( mLineDigitizingType );
1310  mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
1311  }
1312 
1313  digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, mCaptureMode );
1314  if ( digitizingFinished )
1315  mCurrentShapeMapTool->clean();
1316  }
1317  }
1318  else // i.e. not shape
1319  {
1320  //add point to list and to rubber band
1321  if ( e->button() == Qt::LeftButton )
1322  {
1323  const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
1324  if ( error == 2 )
1325  {
1326  //problem with coordinate transformation
1327  emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
1328  return;
1329  }
1330 
1331  startCapturing();
1332  }
1333  else if ( e->button() == Qt::RightButton )
1334  {
1335  // End of string
1337 
1338  //lines: bail out if there are not at least two vertices
1339  if ( mode() == CaptureLine && size() < 2 )
1340  {
1341  stopCapturing();
1342  return;
1343  }
1344 
1345  //polygons: bail out if there are not at least two vertices
1346  if ( mode() == CapturePolygon && size() < 3 )
1347  {
1348  stopCapturing();
1349  return;
1350  }
1351 
1352  if ( mode() == CapturePolygon || e->modifiers() == Qt::ShiftModifier )
1353  {
1354  closePolygon();
1355  }
1356 
1357  digitizingFinished = true;
1358  }
1359  }
1360 
1361  if ( digitizingFinished )
1362  {
1363  QgsGeometry g;
1364  QgsCurve *curveToAdd = captureCurve()->clone();
1365 
1366  if ( mode() == CaptureLine )
1367  {
1368  g = QgsGeometry( curveToAdd );
1369  geometryCaptured( g );
1370  lineCaptured( curveToAdd );
1371  }
1372  else
1373  {
1374  QgsCurvePolygon *poly = new QgsCurvePolygon();
1375  poly->setExteriorRing( curveToAdd );
1376  g = QgsGeometry( poly );
1377  geometryCaptured( g );
1378  polygonCaptured( poly );
1379  }
1380 
1381  stopCapturing();
1382  }
1383  }
1384 }
QgsCurve
Abstract base class for curved geometry type.
Definition: qgscurve.h:35
QgsMapToolEdit::digitizingStrokeWidth
static int digitizingStrokeWidth()
Returns stroke width for rubber bands (from global settings)
Definition: qgsmaptooledit.cpp:56
qgspolygon.h
QgsVertexId::part
int part
Part number.
Definition: qgsvertexid.h:89
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
QgsVectorLayer::LayerOptions::loadDefaultStyle
bool loadDefaultStyle
Set to true if the default layer style should be loaded.
Definition: qgsvectorlayer.h:434
QgsAdvancedDigitizingDockWidget::currentPointV2
QgsPoint currentPointV2(bool *exists=nullptr) const
The last point.
Definition: qgsadvanceddigitizingdockwidget.cpp:1818
QgsMapToolCapture::clearCurve
void clearCurve()
Clear capture curve.
Definition: qgsmaptoolcapture.cpp:834
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QgsMapCanvas::currentLayerChanged
void currentLayerChanged(QgsMapLayer *layer)
Emitted when the current layer is changed.
qgssettingsregistrycore.h
QObjectParentUniquePtr::reset
void reset(T *p=nullptr)
Will reset the managed pointer to p.
Definition: qobjectuniqueptr.h:441
QgsMapToolCapture::QgsMapToolCapture
QgsMapToolCapture(QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode)
constructor
Definition: qgsmaptoolcapture.cpp:46
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsvertexid.h:95
QgsPointXY::y
double y
Definition: qgspointxy.h:63
QgsMapTool::toLayerCoordinates
QgsPoint toLayerCoordinates(const QgsMapLayer *layer, const QgsPoint &point)
Transforms a point from map coordinates to layer coordinates.
Definition: qgsmaptool.cpp:62
QgsAdvancedDigitizingDockWidget::removePreviousPoint
void removePreviousPoint()
Remove previous point in the CAD point list.
Definition: qgsadvanceddigitizingdockwidget.cpp:1719
QObjectUniquePtr::reset
void reset(T *p=nullptr)
Will reset the managed pointer to p.
Definition: qobjectuniqueptr.h:179
QgsVectorLayer::wkbType
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Definition: qgsvectorlayer.cpp:725
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
QgsPointLocator::Match::hasMiddleSegment
bool hasMiddleSegment() const
Returns true if the Match is the middle of a segment.
Definition: qgspointlocator.h:219
QgsVectorLayer::dataProvider
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Definition: qgsvectorlayer.cpp:676
QgsMapMouseEvent::mapPoint
QgsPointXY mapPoint() const
mapPoint returns the point in coordinates
Definition: qgsmapmouseevent.h:88
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:33
QgsLineString::length
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
Definition: qgslinestring.cpp:833
qgslinestring.h
QgsVertexMarker::setIconType
void setIconType(int iconType)
Definition: qgsvertexmarker.cpp:27
QgsMapToolAdvancedDigitizing::mCadDockWidget
QgsAdvancedDigitizingDockWidget * mCadDockWidget
Definition: qgsmaptooladvanceddigitizing.h:120
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:736
qgsmapcanvas.h
QgsAdvancedDigitizingDockWidget::getLineZ
double getLineZ() const
Convenient method to get the Z value from the line edit wiget.
Definition: qgsadvanceddigitizingdockwidget.cpp:1866
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsPoint::setM
void setM(double m) SIP_HOLDGIL
Sets the point's m-value.
Definition: qgspoint.h:336
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:551
QgsCompoundCurve::isEmpty
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgscompoundcurve.cpp:433
QgsMapToolCapture::CaptureMode
CaptureMode
Different capture modes.
Definition: qgsmaptoolcapture.h:56
QgsTracer::init
bool init()
Build the internal data structures.
Definition: qgstracer.cpp:675
QgsRubberBand
A class for drawing transient features (e.g. digitizing lines) on the map.
Definition: qgsrubberband.h:51
QgsCurvePolygon::setExteriorRing
virtual void setExteriorRing(QgsCurve *ring)
Sets the exterior ring of the polygon.
Definition: qgscurvepolygon.cpp:698
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:664
qgsgui.h
QgsCompoundCurve::nCurves
int nCurves() const SIP_HOLDGIL
Returns the number of curves in the geometry.
Definition: qgscompoundcurve.h:82
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:762
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
QgsCurvePolygon
Curve polygon geometry type.
Definition: qgscurvepolygon.h:34
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
QgsMapTool::setCursor
virtual void setCursor(const QCursor &cursor)
Sets a user defined cursor.
Definition: qgsmaptool.cpp:160
QgsMapToolCapture::supportsTechnique
virtual bool supportsTechnique(Qgis::CaptureTechnique technique) const
Returns true if the tool supports the specified capture technique.
Definition: qgsmaptoolcapture.cpp:102
QgsMapToolEdit::defaultMValue
static double defaultMValue()
Returns default M value.
Definition: qgsmaptooledit.cpp:42
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsMapToolAdvancedDigitizing::activate
void activate() override
Registers this maptool with the cad dock widget.
Definition: qgsmaptooladvanceddigitizing.cpp:121
QgsMapToolShapeAbstract::deactivate
virtual void deactivate()
Deactivates the map tool.
Definition: qgsmaptoolshapeabstract.h:94
QgsGeometry::Error
A geometry error.
Definition: qgsgeometry.h:2404
QgsAdvancedDigitizingDockWidget::getLineM
double getLineM() const
Convenient method to get the M value from the line edit wiget.
Definition: qgsadvanceddigitizingdockwidget.cpp:1871
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsPoint::z
double z
Definition: qgspoint.h:71
QgsRubberBand::getPoint
const QgsPointXY * getPoint(int i, int j=0, int ringIndex=0) const
Returns a vertex.
Definition: qgsrubberband.cpp:735
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsMapToolShapeAbstract::cadCanvasReleaseEvent
virtual bool cadCanvasReleaseEvent(QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode)=0
Called for a mouse release event Must return true if the digitization has ended and the geometry is c...
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:477
QgsCompoundCurve::close
void close()
Appends first point if not already closed.
Definition: qgscompoundcurve.cpp:1157
QgsMapToolAdvancedDigitizing::layer
virtual QgsMapLayer * layer() const
Returns the layer associated with the map tool.
Definition: qgsmaptooladvanceddigitizing.cpp:145
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:112
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
QgsSettingsRegistryCore::settingsDigitizingConvertToCurveAngleTolerance
static const QgsSettingsEntryDouble settingsDigitizingConvertToCurveAngleTolerance
Settings entry digitizing convert to curve angle tolerance.
Definition: qgssettingsregistrycore.h:157
QgsVectorLayer::startEditing
Q_INVOKABLE bool startEditing()
Makes the layer editable.
Definition: qgsvectorlayer.cpp:1491
QgsCompoundCurve::numPoints
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
Definition: qgscompoundcurve.cpp:416
QgsMapToolCapture::size
int size()
Number of points digitized.
Definition: qgsmaptoolcapture.cpp:1090
QgsSettingsRegistryCore::settingsDigitizingStreamTolerance
static const QgsSettingsEntryInteger settingsDigitizingStreamTolerance
Settings entry digitizing stream tolerance.
Definition: qgssettingsregistrycore.h:55
QgsMapTool::canvas
QgsMapCanvas * canvas() const
returns pointer to the tool's map canvas
Definition: qgsmaptool.cpp:215
QgsPointLocator::Match::point
QgsPointXY point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords,...
Definition: qgspointlocator.h:238
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
qgsmaptoolshapeabstract.h
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsMapTool::mCanvas
QPointer< QgsMapCanvas > mCanvas
The pointer to the map canvas.
Definition: qgsmaptool.h:336
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:900
QgsRubberBand::movePoint
void movePoint(const QgsPointXY &p, int geometryIndex=0, int ringIndex=0)
Moves the rubber band point specified by index.
Definition: qgsrubberband.cpp:232
QgsMapLayer::setCrs
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Definition: qgsmaplayer.cpp:937
Qgis::GeometryValidationEngine
GeometryValidationEngine
Available engines for validating geometries.
Definition: qgis.h:942
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:91
QgsPointLocator::Match::hasVertex
bool hasVertex() const
Returns true if the Match is a vertex.
Definition: qgspointlocator.h:211
qgssnapindicator.h
QgsSnapIndicator
Class that shows snapping marker on map canvas for the current snapping match.
Definition: qgssnapindicator.h:32
QgsCompoundCurve::curveAt
const QgsCurve * curveAt(int i) const SIP_HOLDGIL
Returns the curve at the specified index.
Definition: qgscompoundcurve.cpp:574
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
QgsRubberBand::reset
void reset(QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry)
Clears all the geometries in this rubberband.
Definition: qgsrubberband.cpp:110
QgsFeatureRequest::setFilterFid
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the feature ID that should be fetched.
Definition: qgsfeaturerequest.cpp:141
QgsMapToolCapture::setStreamDigitizingEnabled
Q_DECL_DEPRECATED void setStreamDigitizingEnabled(bool enable)
Toggles the stream digitizing mode.
Definition: qgsmaptoolcapture.cpp:387
QgsCompoundCurve::startPoint
QgsPoint startPoint() const override SIP_HOLDGIL
Returns the starting point of the curve.
Definition: qgscompoundcurve.cpp:380
qgsrubberband.h
QgsPoint::dropMValue
bool dropMValue() override
Drops any measure values which exist in the geometry.
Definition: qgspoint.cpp:603
QgsAbstractGeometry::vertexAt
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
QgsMapToolShapeMetadata
QgsMapToolShapeMetadata is a base class for shape map tools metadata to be used in QgsMapToolShapeReg...
Definition: qgsmaptoolshaperegistry.h:81
qgsapplication.h
QgsAbstractGeometry::isMeasure
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
Definition: qgsabstractgeometry.h:228
QgsAdvancedDigitizingDockWidget::clearPoints
void clearPoints()
Removes all points from the CAD point list.
Definition: qgsadvanceddigitizingdockwidget.cpp:1730
QgsSettingsRegistryCore::settingsDigitizingConvertToCurveDistanceTolerance
static const QgsSettingsEntryDouble settingsDigitizingConvertToCurveDistanceTolerance
Settings entry digitizing convert to curve distance tolerance.
Definition: qgssettingsregistrycore.h:160
QgsWkbTypes::PointM
@ PointM
Definition: qgswkbtypes.h:99
QObjectUniquePtr::release
T * release()
Clears the pointer and returns it.
Definition: qobjectuniqueptr.h:167
qgsmaptoolcapturerubberband.h
qgsmapcanvastracer.h
QgsVertexMarker
A class for marking vertices of features using e.g. circles or 'x'.
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:3048
QObjectParentUniquePtr::setParentOwner
void setParentOwner(QObject *parent)
Sets the parent object.
Definition: qobjectuniqueptr.h:320
QgsPointLocator::Match::vertexIndex
int vertexIndex() const
for vertex / edge match (first vertex of the edge)
Definition: qgspointlocator.h:241
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsPoint::y
double y
Definition: qgspoint.h:70
QgsPointLocator::Match::hasEdge
bool hasEdge() const
Returns true if the Match is an edge.
Definition: qgspointlocator.h:213
QgsMapTool::toCanvasCoordinates
QPoint toCanvasCoordinates(const QgsPointXY &point) const
Transforms a point from map coordinates to screen coordinates.
Definition: qgsmaptool.cpp:77
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
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:786
QgsVectorDataProvider::capabilities
virtual Q_INVOKABLE QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Definition: qgsvectordataprovider.cpp:208
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:65
QgsMapToolCapture::captureCurve
const QgsCompoundCurve * captureCurve() const
Gets the capture curve.
Definition: qgsmaptoolcapture.h:129
QgsMapToolCapture::~QgsMapToolCapture
~QgsMapToolCapture() override
Definition: qgsmaptoolcapture.cpp:75
QgsRubberBand::addGeometry
void addGeometry(const QgsGeometry &geometry, QgsMapLayer *layer, bool doUpdate=true)
Adds the geometry of an existing feature to a rubberband This is useful for multi feature highlightin...
Definition: qgsrubberband.cpp:288
QgsPoint::addMValue
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
Definition: qgspoint.cpp:562
QgsProject::topologicalEditing
bool topologicalEditing
Definition: qgsproject.h:120
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:206
QgsCurve::endPoint
virtual QgsPoint endPoint() const =0
Returns the end point of the curve.
QgsMapToolCapture::activate
void activate() override
Registers this maptool with the cad dock widget.
Definition: qgsmaptoolcapture.cpp:116
QgsSettingsRegistryCore::settingsDigitizingValidateGeometries
static const QgsSettingsEntryInteger settingsDigitizingValidateGeometries
Settings entry digitizing validate geometries.
Definition: qgssettingsregistrycore.h:142
QgsCompoundCurve::endPoint
QgsPoint endPoint() const override SIP_HOLDGIL
Returns the end point of the curve.
Definition: qgscompoundcurve.cpp:389
Qgis::CaptureTechnique::CircularString
@ CircularString
Capture in circular strings.
QgsCompoundCurve::addVertex
void addVertex(const QgsPoint &pt)
Adds a vertex to the end of the geometry.
Definition: qgscompoundcurve.cpp:639
QgsPointLocator::Match::hasLineEndpoint
bool hasLineEndpoint() const
Returns true if the Match is a line endpoint (start or end vertex).
Definition: qgspointlocator.h:226
QgsMapCanvasTracer
Extension of QgsTracer that provides extra functionality:
Definition: qgsmapcanvastracer.h:41
qgsvertexmarker.h
QgsTracer::ErrTooManyFeatures
@ ErrTooManyFeatures
Max feature count threshold was reached while reading features.
Definition: qgstracer.h:140
QgsMapToolCapture::capabilities
virtual QgsMapToolCapture::Capabilities capabilities() const
Returns flags containing the supported capabilities.
Definition: qgsmaptoolcapture.cpp:97
QgsPoint::dropZValue
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
Definition: qgspoint.cpp:592
QgsVertexMarker::setPenWidth
void setPenWidth(int width)
Definition: qgsvertexmarker.cpp:58
QgsMapToolCapture::deleteTempRubberBand
void deleteTempRubberBand()
Clean a temporary rubberband.
Definition: qgsmaptoolcapture.cpp:996
QgsMapToolCapture::snappingMatches
QList< QgsPointLocator::Match > snappingMatches() const
Returns a list of matches for each point on the captureCurve.
Definition: qgsmaptoolcapture.cpp:840
QgsCompoundCurve::points
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
Definition: qgscompoundcurve.cpp:398
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1130
QgsMapToolCapture::setPoints
Q_DECL_DEPRECATED void setPoints(const QVector< QgsPointXY > &pointList)
Set the points on which to work.
Definition: qgsmaptoolcapture.cpp:1110
QgsVertexMarker::setCenter
void setCenter(const QgsPointXY &point)
Sets the center point of the marker, in map coordinates.
Definition: qgsvertexmarker.cpp:39
QgsPointLocator::Match::isValid
bool isValid() const
Definition: qgspointlocator.h:209
QgsWkbTypes::PointZ
@ PointZ
Definition: qgswkbtypes.h:86
QgsMapCanvasTracer::actionEnableSnapping
QAction * actionEnableSnapping() const
Access to action that user may use to toggle snapping on/off.
Definition: qgsmapcanvastracer.h:63
QgsPoint::m
double m
Definition: qgspoint.h:72
QgsVertexMarker::setColor
void setColor(const QColor &color)
Sets the stroke color for the marker.
Definition: qgsvertexmarker.cpp:46
QgsMapTool::messageEmitted
void messageEmitted(const QString &message, Qgis::MessageLevel=Qgis::MessageLevel::Info)
emit a message
QgsMapToolCapture::startCapturing
void startCapturing()
Start capturing.
Definition: qgsmaptoolcapture.cpp:963
BUILTIN_UNREACHABLE
#define BUILTIN_UNREACHABLE
Definition: qgis.h:2907
QgsRubberBand::numberOfVertices
int numberOfVertices() const
Returns count of vertices in all lists of mPoint.
Definition: qgsrubberband.cpp:722
QgsMapToolCapture::CapturePolygon
@ CapturePolygon
Capture polygons.
Definition: qgsmaptoolcapture.h:61
QgsMapToolEdit::defaultZValue
static double defaultZValue()
Returns default Z value.
Definition: qgsmaptooledit.cpp:37
QgsMapToolCapture::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Intercept key events like Esc or Del to delete the last point.
Definition: qgsmaptoolcapture.cpp:918
QgsPointLocator::Match::layer
QgsVectorLayer * layer() const
The vector layer where the snap occurred.
Definition: qgspointlocator.h:247
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:70
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsMapToolCapture::CaptureLine
@ CaptureLine
Capture lines.
Definition: qgsmaptoolcapture.h:60
QgsAdvancedDigitizingDockWidget
The QgsAdvancedDigitizingDockWidget class is a dockable widget used to handle the CAD tools on top of...
Definition: qgsadvanceddigitizingdockwidget.h:50
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsMapToolCapture::setCurrentShapeMapTool
void setCurrentShapeMapTool(const QgsMapToolShapeMetadata *shapeMapToolMetadata)
Sets the current shape tool.
Definition: qgsmaptoolcapture.cpp:438
Qgis::CaptureTechnique::Shape
@ Shape
Digitize shapes.
QgsMapCanvasTracer::tracerForCanvas
static QgsMapCanvasTracer * tracerForCanvas(QgsMapCanvas *canvas)
Retrieve instance of this class associated with given canvas (if any).
Definition: qgsmapcanvastracer.cpp:61
QgsCompoundCurve::clear
void clear() override
Clears the geometry, ie reset it to a null geometry.
Definition: qgscompoundcurve.cpp:141
QgsMapToolShapeAbstract::activate
virtual void activate(QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint)
Activates the map tool with the last captured map point.
Definition: qgsmaptoolshapeabstract.h:91
QgsAbstractGeometry::is3D
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
Definition: qgsabstractgeometry.h:219
QgsMapToolCapture::isCapturing
bool isCapturing() const
Are we currently capturing?
Definition: qgsmaptoolcapture.cpp:968
QgsGeometry::vertexAt
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Definition: qgsgeometry.cpp:683
QgsMapToolEdit::digitizingFillColor
static QColor digitizingFillColor()
Returns fill color for rubber bands (from global settings)
Definition: qgsmaptooledit.cpp:61
QgsPointLocator::Match
Definition: qgspointlocator.h:187
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsMapToolShapeAbstract::undo
virtual void undo()
Called to undo last action (last point added)
Definition: qgsmaptoolshapeabstract.cpp:50
QgsSettingsRegistryCore::settingsDigitizingLineColorAlphaScale
static const QgsSettingsEntryDouble settingsDigitizingLineColorAlphaScale
Settings entry digitizing line color alpha scale.
Definition: qgssettingsregistrycore.h:73
QgsMapToolShapeAbstract::clean
virtual void clean()
Called to clean the map tool (after canceling the operation or when the digitization has finished)
Definition: qgsmaptoolshapeabstract.cpp:39
QgsMapToolCapture::clean
void clean() override
convenient method to clean members
Definition: qgsmaptoolcapture.cpp:1001
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:2277
QgsCompoundCurve::moveVertex
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
Definition: qgscompoundcurve.cpp:777
QgsVectorLayer::LayerOptions
Setting options for loading vector layers.
Definition: qgsvectorlayer.h:408
QgsMapToolShapeAbstract::cadCanvasMoveEvent
virtual void cadCanvasMoveEvent(QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode)=0
Called for a mouse move event.
QgsGeometry::get
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:141
qgsmaptoolshaperegistry.h
QgsMapMouseEvent
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas....
Definition: qgsmapmouseevent.h:35
QgsPointLocator::Match::featureId
QgsFeatureId featureId() const
The id of the feature to which the snapped geometry belongs.
Definition: qgspointlocator.h:252
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsAdvancedDigitizingDockWidget::currentPointLayerCoordinates
QgsPoint currentPointLayerCoordinates(QgsMapLayer *layer) const
Returns the last CAD point, in a map layer's coordinates.
Definition: qgsadvanceddigitizingdockwidget.cpp:1828
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:136
QgsMapToolCapture::cadCanvasReleaseEvent
void cadCanvasReleaseEvent(QgsMapMouseEvent *e) override
Override this method when subclassing this class.
Definition: qgsmaptoolcapture.cpp:1229
QgsGeometry::convertPointList
static void convertPointList(const QVector< QgsPointXY > &input, QgsPointSequence &output)
Upgrades a point list from QgsPointXY to QgsPoint.
Definition: qgsgeometry.cpp:3333
QgsTracer::ErrNone
@ ErrNone
No error.
Definition: qgstracer.h:139
QgsMapToolCapture::takeRubberBand
QgsRubberBand * takeRubberBand()
Returns the rubberBand currently owned by this map tool and transfers ownership to the caller.
Definition: qgsmaptoolcapture.cpp:374
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
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:180
QgsMapToolCapture::setCircularDigitizingEnabled
Q_DECL_DEPRECATED void setCircularDigitizingEnabled(bool enable)
Enable the digitizing with curve.
Definition: qgsmaptoolcapture.cpp:379
QgsPointSequence
QVector< QgsPoint > QgsPointSequence
Definition: qgsabstractgeometry.h:52
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
QgsMapToolCapture::setCurrentCaptureTechnique
void setCurrentCaptureTechnique(Qgis::CaptureTechnique technique)
Sets the current capture if it is supported by the map tool.
Definition: qgsmaptoolcapture.cpp:395
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:1983
Qgis::CaptureTechnique::StraightSegments
@ StraightSegments
Default capture mode - capture occurs with straight line segments.
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsCompoundCurve::addCurve
void addCurve(QgsCurve *c, bool extendPrevious=false)
Adds a curve to the geometry (takes ownership).
Definition: qgscompoundcurve.cpp:583
QgsMapToolShapeAbstract::id
QString id() const
Returns the id of the shape tool (equivalent to the one from the metadata)
Definition: qgsmaptoolshapeabstract.h:67
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent
virtual void cadCanvasMoveEvent(QgsMapMouseEvent *e)
Override this method when subclassing this class.
Definition: qgsmaptooladvanceddigitizing.h:154
QgsMapToolCapture::points
Q_DECL_DEPRECATED QVector< QgsPointXY > points() const
List of digitized points.
Definition: qgsmaptoolcapture.cpp:1095
QgsMapToolCapture::CaptureNone
@ CaptureNone
Do not capture / determine mode from layer geometry type.
Definition: qgsmaptoolcapture.h:58
QgsMapToolCapture::CapturePoint
@ CapturePoint
Capture points.
Definition: qgsmaptoolcapture.h:59
qgsmaptoolcapture.h
QgsVertexId::ring
int ring
Ring number.
Definition: qgsvertexid.h:92
QgsMapToolCapture::stopCapturing
void stopCapturing()
Stop capturing.
Definition: qgsmaptoolcapture.cpp:973
QgsMapToolCapture::ValidateGeometries
@ ValidateGeometries
Tool supports geometry validation (since QGIS 3.22)
Definition: qgsmaptoolcapture.h:69
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:1173
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:592
QgsMapCanvasTracer::reportError
void reportError(PathError err, bool addingVertex)
Report a path finding error to the user.
Definition: qgsmapcanvastracer.cpp:66
QgsPoint::convertTo
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
Definition: qgspoint.cpp:620
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1080
QgsSettingsRegistryCore::settingsDigitizingConvertToCurve
static const QgsSettingsEntryBool settingsDigitizingConvertToCurve
Settings entry digitizing convert to curve.
Definition: qgssettingsregistrycore.h:154
QgsMapToolAdvancedDigitizing::cadDockWidget
QgsAdvancedDigitizingDockWidget * cadDockWidget() const
Definition: qgsmaptooladvanceddigitizing.h:65
QgsGeometry::vertexIdFromVertexNr
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
Definition: qgsgeometry.cpp:3263
qgsexception.h
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsPoint::isEmpty
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
Definition: qgspoint.cpp:767
QgsMapToolCapture::closePolygon
void closePolygon()
Close an open polygon.
Definition: qgsmaptoolcapture.cpp:1010
QgsMapToolCapture::undo
void undo(bool isAutoRepeat=false)
Removes the last vertex from mRubberBand and mCaptureList.
Definition: qgsmaptoolcapture.cpp:845
QgsMapCanvas::currentLayer
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
Definition: qgsmapcanvas.cpp:614
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:128
QgsVectorLayer::getFeature
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
Definition: qgsvectorlayer.h:1187
QgsMapToolCapture::nextPoint
int nextPoint(const QgsPoint &mapPoint, QgsPoint &layerPoint)
Converts a map point to layer coordinates.
Definition: qgsmaptoolcapture.cpp:559
qgslogger.h
QgsMapToolShapeAbstract::keyPressEvent
virtual void keyPressEvent(QKeyEvent *e)
Filters a key press event Ignores the event in default implementation.
Definition: qgsmaptoolshapeabstract.cpp:29
QgsCurve::segmentize
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
Definition: qgscurve.cpp:175
QgsCompoundCurve::deleteVertex
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Definition: qgscompoundcurve.cpp:794
Qgis::CaptureTechnique
CaptureTechnique
Capture technique.
Definition: qgis.h:152
QgsTracer::PathError
PathError
Possible errors that may happen when calling findShortestPath()
Definition: qgstracer.h:137
QgsMapTool::isActive
bool isActive() const
Returns if the current map tool active on the map canvas.
Definition: qgsmaptool.cpp:145
QgsPoint::setZ
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
Definition: qgspoint.h:321
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:803
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
qgsmapmouseevent.h
QgsGeometryValidator
Definition: qgsgeometryvalidator.h:31
QgsProject::snappingConfigChanged
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:720
QgsVectorLayer::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
Definition: qgsvectorlayer.cpp:1070
QgsMapToolAdvancedDigitizing
The QgsMapToolAdvancedDigitizing class is a QgsMapTool which gives event directly in map coordinates ...
Definition: qgsmaptooladvanceddigitizing.h:36
Qgis::CaptureTechnique::Streaming
@ Streaming
Streaming points digitizing mode (points are automatically added as the mouse cursor moves).
QgsAdvancedDigitizingDockWidget::switchZM
void switchZM()
Determines if Z or M will be enabled.
Definition: qgsadvanceddigitizingdockwidget.cpp:361
QgsAdvancedDigitizingDockWidget::cadEnabled
bool cadEnabled() const
determines if CAD tools are enabled or if map tools behaves "nomally"
Definition: qgsadvanceddigitizingdockwidget.h:261
QgsMapToolCapture::cadCanvasMoveEvent
void cadCanvasMoveEvent(QgsMapMouseEvent *e) override
Override this method when subclassing this class.
Definition: qgsmaptoolcapture.cpp:459
QgsVectorLayer::LayerOptions::skipCrsValidation
bool skipCrsValidation
Controls whether the layer is allowed to have an invalid/unknown CRS.
Definition: qgsvectorlayer.h:487
QgsPoint::x
double x
Definition: qgspoint.h:69
qgsproject.h
QgsGeometryValidator::errorFound
void errorFound(const QgsGeometry::Error &error)
Sent when an error has been found during the validation process.
QgsGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Definition: qgsgeometry.cpp:357
QgsMapTool::toMapCoordinates
QgsPointXY toMapCoordinates(QPoint point)
Transforms a point from screen coordinates to map coordinates.
Definition: qgsmaptool.cpp:41
qgsgeometryvalidator.h
QgsMapToolEdit::digitizingStrokeColor
static QColor digitizingStrokeColor()
Returns stroke color for rubber bands (from global settings)
Definition: qgsmaptooledit.cpp:48
QgsMapMouseEvent::isSnapped
bool isSnapped() const
Returns true if there is a snapped point cached.
Definition: qgsmapmouseevent.h:82
QgsCompoundCurve::removeCurve
void removeCurve(int i)
Removes a curve from the geometry.
Definition: qgscompoundcurve.cpp:628
QgsSettingsEntryByValue::value
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
Definition: qgssettingsentry.h:520
QgsMapToolShapeMetadata::factory
virtual QgsMapToolShapeAbstract * factory(QgsMapToolCapture *parentlTool) const SIP_FACTORY=0
Creates the shape map tool for the given parentTool Caller takes ownership of the returned object.
QgsWkbTypes::CompoundCurve
@ CompoundCurve
Definition: qgswkbtypes.h:81
QgsMapToolShapeMetadata::id
virtual QString id() const =0
Unique ID for the shape map tool.
QgsMapToolCapture::pointsZM
QgsPointSequence pointsZM() const
List of digitized points.
Definition: qgsmaptoolcapture.cpp:1103