51#include "moc_qgsmaptoolcapture.cpp"
53using namespace Qt::StringLiterals;
57 , mCaptureMode(
mode )
60 mTempRubberBand.setParentOwner(
canvas );
62 mSnapIndicator = std::make_unique<QgsSnapIndicator>(
canvas );
71 mExtraSnapLayer =
new QgsVectorLayer( u
"LineString?crs="_s, u
"extra snap"_s, u
"memory"_s, layerOptions );
72 mExtraSnapLayer->startEditing();
74 mExtraSnapLayer->addFeature( f );
75 mExtraSnapFeatureId = f.
id();
79 currentLayerChanged(
canvas->currentLayer() );
90 mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
92 mExtraSnapLayer->deleteLater();
93 mExtraSnapLayer =
nullptr;
99 mValidator->deleteLater();
100 mValidator =
nullptr;
126 if ( mTempRubberBand )
127 mTempRubberBand->show();
129 mCanvas->snappingUtils()->addExtraSnapLayer( mExtraSnapLayer );
134 setCurrentShapeMapToolIsActivated(
true );
140 if ( mTempRubberBand )
141 mTempRubberBand->hide();
145 mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
149 setCurrentShapeMapToolIsActivated(
false );
155void QgsMapToolCapture::currentLayerChanged(
QgsMapLayer *layer )
157 if ( !mCaptureModeFromLayer )
193 if ( mTempRubberBand )
201bool QgsMapToolCapture::tracingEnabled()
209QgsPointXY QgsMapToolCapture::tracingStartPoint()
213 if ( mTracingStartPoint != QgsPointXY() )
214 return mTracingStartPoint;
216 return mCaptureLastPoint;
225 QgsPointXY pt0 = tracingStartPoint();
226 if ( pt0 == QgsPointXY() )
242 mTempRubberBand->addPoint( mCaptureLastPoint );
248 const QgsPoint lastPoint = mCaptureLastPoint;
249 QgsPointXY lastPointXY( lastPoint );
250 if ( lastPointXY == pt0 &&
points[0] != lastPointXY )
252 if ( mRubberBand->numberOfVertices() != 0 )
256 if ( mRubberBand->numberOfVertices() > 2 || ( mRubberBand->numberOfVertices() == 2 && *mRubberBand->getPoint( 0, 0 ) != *mRubberBand->getPoint( 0, 1 ) ) )
257 mRubberBand->movePoint(
points[0] );
260 mTempRubberBand->movePoint( 0, QgsPoint(
points[0] ) );
263 mTempRubberBand->movePoint( QgsPoint(
points[0] ) );
266 for (
int i = 1; i <
points.count(); ++i )
267 mTempRubberBand->addPoint( QgsPoint(
points.at( i ) ), i ==
points.count() - 1 );
270 mTempRubberBand->addPoint( QgsPoint(
points[
points.size() - 1] ) );
274 QgsCoordinateReferenceSystem targetCrs =
mCanvas->mapSettings().destinationCrs();
275 if ( QgsMapLayer *l =
layer() )
278 targetCrs = l->crs();
281 std::unique_ptr< QgsCompoundCurve > tempCurve( mCaptureCurve.clone() );
284 std::unique_ptr< QgsCurve > tracedCurve( mTempRubberBand->curve() );
286 tempCurve->addCurve( tracedCurve.release() );
290 auto curvePolygon = std::make_unique< QgsCurvePolygon >();
291 curvePolygon->setExteriorRing( tempCurve.release() );
299 catch ( QgsCsException &e )
308bool QgsMapToolCapture::tracingAddVertex(
const QgsPointXY &point )
314 if ( mTempRubberBand->pointsCount() == 0 )
316 if ( !tracer->
init() )
326 mTracingStartPoint = point;
331 QgsPointXY pt0 = tracingStartPoint();
332 if ( pt0 == QgsPointXY() )
336 const QVector<QgsPointXY> tracedPointsInMapCrs = tracer->
findShortestPath( pt0, point, &err );
337 if ( tracedPointsInMapCrs.isEmpty() )
342 layerPoints.reserve( tracedPointsInMapCrs.size() );
344 mapPoints.reserve( tracedPointsInMapCrs.size() );
345 for (
const QgsPointXY &tracedPointMapCrs : tracedPointsInMapCrs )
347 QgsPoint
mapPoint( tracedPointMapCrs );
365 const QgsVertexId lastVertexId( 0, 0, mCaptureCurve.numPoints() - 1 );
366 mCaptureCurve.moveVertex( lastVertexId, layerPoints.first() );
367 mSnappingMatches.removeLast();
368 mSnappingMatches.append( QgsPointLocator::Match() );
370 addCurve(
new QgsLineString( mapPoints ) );
378 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>(
layer() );
381 const QgsGeometry linear = QgsGeometry( mCaptureCurve.segmentize() );
388 mCaptureCurve.clear();
397 mSnappingMatches.resize( mCaptureCurve.numPoints() );
403 const QgsPoint lastPt = mCaptureCurve.endPoint();
409QgsMapToolCaptureRubberBand *QgsMapToolCapture::createCurveRubberBand()
const
411 QgsMapToolCaptureRubberBand *rb =
new QgsMapToolCaptureRubberBand(
mCanvas );
416 color.setAlphaF( color.alphaF() * alphaScale );
417 rb->setLineStyle( Qt::DotLine );
418 rb->setStrokeColor( color );
421 rb->setFillColor( fillColor );
426void QgsMapToolCapture::resetRubberBand()
430 QgsLineString *lineString = mCaptureCurve.curveToLine();
433 mRubberBand->addGeometry( QgsGeometry( lineString ),
layer() );
436void QgsMapToolCapture::setCurrentShapeMapToolIsActivated(
bool activated )
441 mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
446 mCurrentShapeMapTool->deactivate();
452 return mRubberBand.release();
473 if ( mCurrentCaptureTechnique == technique )
476 mStartNewCurve =
true;
480 setCurrentShapeMapToolIsActivated(
false );
504 if ( mTempRubberBand )
505 mTempRubberBand->setStringType( mLineDigitizingType );
507 mCurrentCaptureTechnique = technique;
512 setCurrentShapeMapToolIsActivated(
true );
518 if ( mCurrentShapeMapTool )
520 if ( shapeMapToolMetadata && mCurrentShapeMapTool->
id() == shapeMapToolMetadata->
id() )
524 setCurrentShapeMapToolIsActivated(
false );
526 mCurrentShapeMapTool->deleteLater();
529 mCurrentShapeMapTool.reset( shapeMapToolMetadata ? shapeMapToolMetadata->
factory(
this ) :
nullptr );
534 if ( mCurrentShapeMapTool )
536 setCurrentShapeMapToolIsActivated(
true );
544 if ( mCaptureModeFromLayer && ( !
canvas()->currentLayer() || !
canvas()->currentLayer()->isSpatial() ) )
555 if ( !mCurrentShapeMapTool )
561 if ( !mTempRubberBand )
563 mTempRubberBand.reset( createCurveRubberBand() );
564 mTempRubberBand->setStringType( mLineDigitizingType );
568 mCurrentShapeMapTool->cadCanvasMoveEvent( e, mCaptureMode );
580 targetCrs = l->crs();
583 if ( mCaptureMode !=
CapturePoint && mTempRubberBand && mCapturing )
585 bool hasTrace =
false;
589 if ( !mCaptureCurve.isEmpty() )
591 const QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint();
596 mAllowAddingStreamingPoints =
true;
598 mAllowAddingStreamingPoints =
false;
600 std::unique_ptr< QgsCompoundCurve > tempCurve( mCaptureCurve.clone() );
603 auto curvePolygon = std::make_unique< QgsCurvePolygon >();
605 curvePolygon->setExteriorRing( tempCurve.release() );
613 else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
619 mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 );
621 mCircularItermediatePoint =
QgsPoint();
623 hasTrace = tracingMouseMove( e );
629 mTempRubberBand->addPoint( mCaptureLastPoint );
630 if ( !mCircularItermediatePoint.isEmpty() )
632 mTempRubberBand->movePoint( mCircularItermediatePoint );
633 mTempRubberBand->addPoint( mCircularItermediatePoint );
640 if ( mCaptureCurve.numPoints() > 0 )
642 const QgsPoint mapPt = mCaptureLastPoint;
644 if ( mTempRubberBand )
646 mTempRubberBand->movePoint(
mapPoint );
647 mTempRubberBand->movePoint( 0, mapPt );
651 if ( mRubberBand->numberOfVertices() )
652 mRubberBand->movePoint( mapPt );
654 std::unique_ptr< QgsCompoundCurve > tempCurve( mCaptureCurve.clone() );
661 tempCurve->addCurve(
new QgsLineString( tempCurve->endPoint(), hoverPointTargetCrs ) );
670 auto curvePolygon = std::make_unique< QgsCurvePolygon >();
672 curvePolygon->setExteriorRing( tempCurve.release() );
680 else if ( mTempRubberBand )
681 mTempRubberBand->movePoint(
mapPoint );
695 const bool is3D = layerPoint.
is3D();
696 const bool isMeasure = layerPoint.
isMeasure();
698 layerPoint =
QgsPoint( layerPoint.
wkbType(), mapP.
x(), mapP.
y(), layerPoint.
z(), layerPoint.
m() );
706 QgsDebugError( u
"transformation to layer coordinate failed"_s );
738 if ( match.
isValid() && sourceLayer )
742 if ( sourceLayer->
crs() != vlayer->
crs() )
825 mCaptureCurve.addVertex( layerPoint );
826 mSnappingMatches.append( match );
830 if ( mCaptureFirstPoint.isEmpty() )
838 if ( !mTempRubberBand )
840 mTempRubberBand.reset( createCurveRubberBand() );
841 mTempRubberBand->setStringType( mLineDigitizingType );
845 bool traceCreated =
false;
846 if ( tracingEnabled() )
848 traceCreated = tracingAddVertex(
mapPoint );
853 mTracingStartPoint = traceCreated ? point :
QgsPointXY();
858 mTempRubberBand->movePoint(
mapPoint );
859 if ( mTempRubberBand->curveIsComplete() )
861 if (
QgsCurve *curve = mTempRubberBand->curve() )
866 if ( match.
isValid() && mSnappingMatches.count() > 0 && !mSnappingMatches.last().isValid() )
868 mSnappingMatches.removeLast();
872 mSnappingMatches.removeLast();
873 mSnappingMatches.append( mCircularIntermediateMatch );
875 mSnappingMatches.append( match );
881 else if ( mTempRubberBand->pointsCount() == 0 )
884 mCaptureCurve.addVertex( layerPoint );
885 mSnappingMatches.append( match );
891 mCircularIntermediateMatch = match;
895 mTempRubberBand->addPoint(
mapPoint );
900 mTempRubberBand->addPoint( mCaptureLastPoint );
904 updateExtraSnapLayer();
922 if ( mTempRubberBand )
926 mTempRubberBand->addPoint( endPt );
929 const int countBefore = mCaptureCurve.vertexCount();
931 if ( mCaptureCurve.numPoints() == 1 )
932 mCaptureCurve.removeCurve( 0 );
942 mCaptureCurve.addCurve( segmented,
false );
949 mCaptureCurve.addCurve(
c, !mStartNewCurve );
952 mStartNewCurve =
false;
954 const int countAfter = mCaptureCurve.vertexCount();
955 const int addedPoint = countAfter - countBefore;
957 updateExtraSnapLayer();
959 for (
int i = 0; i < addedPoint; ++i )
969 mCaptureCurve.clear();
970 updateExtraSnapLayer();
975 return mSnappingMatches;
982 if ( mTempRubberBand )
984 if (
size() <= 1 && mTempRubberBand->pointsCount() != 0 )
987 if ( isAutoRepeat && mIgnoreSubsequentAutoRepeatUndo )
989 mIgnoreSubsequentAutoRepeatUndo =
false;
991 const QgsPoint lastPoint = mTempRubberBand->lastPoint();
995 mTempRubberBand->removeLastPoint();
996 mTempRubberBand->movePoint( lastPoint );
1003 mTempRubberBand->removeLastPoint();
1004 mTempRubberBand->movePoint( lastPoint );
1010 vertexToRemove.
part = 0;
1011 vertexToRemove.
ring = 0;
1018 mCaptureCurve.removeCurve( mCaptureCurve.nCurves() - 1 );
1020 if ( mCaptureCurve.numPoints() == 2 && mCaptureCurve.nCurves() == 1 )
1024 const QgsPoint fp = mCaptureCurve.startPoint();
1026 mCaptureCurve.addVertex( fp );
1030 const int curvesBefore = mCaptureCurve.nCurves();
1033 const int pointsCountBefore = mCaptureCurve.numPoints();
1034 mCaptureCurve.deleteVertex( vertexToRemove );
1035 int pointsCountAfter = mCaptureCurve.numPoints();
1036 for ( ; pointsCountAfter < pointsCountBefore; pointsCountAfter++ )
1037 if ( !mSnappingMatches.empty() )
1038 mSnappingMatches.removeLast();
1044 if ( mCaptureCurve.nCurves() < curvesBefore && lastCurveIsLineString )
1045 mIgnoreSubsequentAutoRepeatUndo =
true;
1048 updateExtraSnapLayer();
1054 if ( mCaptureCurve.numPoints() > 0 )
1056 const QgsPoint lastPt = mCaptureCurve.endPoint();
1058 mTempRubberBand->addPoint( mCaptureLastPoint );
1059 mTempRubberBand->movePoint( lastPoint );
1071 mCurrentShapeMapTool->keyPressEvent( e );
1072 if ( e->isAccepted() )
1083 if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
1087 if ( !e->isAutoRepeat() )
1089 mCurrentShapeMapTool->undo();
1094 undo( e->isAutoRepeat() );
1100 else if ( e->key() == Qt::Key_Escape )
1102 if ( mCurrentShapeMapTool )
1103 mCurrentShapeMapTool->clean();
1110 else if ( e->key() == Qt::Key_W && !e->isAutoRepeat() )
1115 mWeightEditMode =
true;
1117 mWeightEditControlPointIndex = mTempRubberBand->pointsCount() - 2;
1122 cadDockWidget()->
setWeight( QString::number( mTempRubberBand->weight( mWeightEditControlPointIndex ),
'f', 2 ),
true );
1131 if ( e->key() == Qt::Key_W && !e->isAutoRepeat() )
1133 if ( mWeightEditMode )
1135 mWeightEditMode =
false;
1136 mWeightEditControlPointIndex = -1;
1154 if ( mWeightEditMode )
1160 double adjustment = e->angleDelta().y() > 0 ? 0.1 : -0.1;
1161 if ( e->modifiers() & Qt::ControlModifier )
1163 else if ( e->modifiers() & Qt::ShiftModifier )
1166 const double currentWeight = mTempRubberBand->weight( mWeightEditControlPointIndex );
1167 const double newWeight = std::max( 0.01, currentWeight + adjustment );
1169 if ( mTempRubberBand->setWeight( mWeightEditControlPointIndex, newWeight ) )
1196 mRubberBand.reset();
1201 if ( mWeightEditMode )
1203 mWeightEditMode =
false;
1204 mWeightEditControlPointIndex = -1;
1211 qDeleteAll( mGeomErrorMarkers );
1212 mGeomErrorMarkers.clear();
1213 mGeomErrors.clear();
1221 mCaptureCurve.clear();
1222 updateExtraSnapLayer();
1223 mSnappingMatches.clear();
1225 lCurrentVectorLayer->triggerRepaint();
1232 mTempRubberBand.reset();
1239 mCurrentShapeMapTool->clean();
1246 mCaptureCurve.close();
1247 updateExtraSnapLayer();
1250void QgsMapToolCapture::validateGeometry()
1258 mValidator->deleteLater();
1259 mValidator =
nullptr;
1262 mGeomErrors.clear();
1263 while ( !mGeomErrorMarkers.isEmpty() )
1265 delete mGeomErrorMarkers.takeFirst();
1270 switch ( mCaptureMode )
1278 geom = QgsGeometry( mCaptureCurve.curveToLine() );
1283 QgsLineString *exteriorRing = mCaptureCurve.curveToLine();
1284 exteriorRing->
close();
1285 QgsPolygon *polygon =
new QgsPolygon();
1287 geom = QgsGeometry( polygon );
1297 mValidator =
new QgsGeometryValidator( geom,
nullptr, method );
1299 mValidator->start();
1306 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>(
layer() );
1312 QgsVertexMarker *vm =
new QgsVertexMarker(
mCanvas );
1316 vm->setToolTip( e.
what() );
1318 vm->setZValue( vm->zValue() + 1 );
1319 mGeomErrorMarkers << vm;
1325 return mCaptureCurve.numPoints();
1330 QVector<QgsPointXY> pointsXY;
1339 mCaptureCurve.points( pts );
1346 mCaptureCurve.clear();
1347 mCaptureCurve.addCurve( line );
1348 updateExtraSnapLayer();
1349 mSnappingMatches.clear();
1350 for (
int i = 0; i < line->
length(); ++i )
1358 mCaptureCurve.clear();
1359 mCaptureCurve.addCurve( line );
1360 updateExtraSnapLayer();
1361 mSnappingMatches.clear();
1362 for (
int i = 0; i < line->
length(); ++i )
1419 if ( match.
layer() )
1437void QgsMapToolCapture::updateExtraSnapLayer()
1439 if ( !mExtraSnapLayer )
1442 if (
canvas()->snappingUtils()->config().selfSnapping() &&
layer() && mCaptureCurve.
numPoints() >= 2 )
1452 mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
1457 mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
1467 if ( e->button() != Qt::LeftButton )
1471 bool isMatchPointZ =
false;
1472 bool isMatchPointM =
false;
1483 if ( isMatchPointM && isMatchPointZ )
1487 else if ( isMatchPointM )
1491 else if ( isMatchPointZ )
1495 savePoint =
QgsPoint( geomType, fetchPoint.
x(), fetchPoint.
y(), fetchPoint.
z(), fetchPoint.
m() );
1501 savePoint =
QgsPoint( point.
x(), point.
y(), fetchPoint.
z(), fetchPoint.
m() );
1511 QgsGeometry g( std::make_unique<QgsPoint>( savePoint ) );
1528 bool digitizingFinished =
false;
1530 QVector<double> nurbsWeights;
1534 if ( !mCurrentShapeMapTool )
1541 if ( !mTempRubberBand )
1543 mTempRubberBand.reset( createCurveRubberBand() );
1544 mTempRubberBand->setStringType( mLineDigitizingType );
1548 digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, mCaptureMode );
1549 if ( digitizingFinished )
1550 mCurrentShapeMapTool->clean();
1556 if ( e->button() == Qt::LeftButton )
1568 else if ( e->button() == Qt::RightButton )
1575 const int rbPointCount = mTempRubberBand->pointsCount();
1576 if ( rbPointCount > 1 )
1579 for (
int i = 0; i < rbPointCount - 1; ++i )
1581 nurbsControlPoints.append( mTempRubberBand->pointFromEnd( rbPointCount - 1 - i ) );
1584 const QVector<double> &rbWeights = mTempRubberBand->weights();
1585 for (
int i = 0; i < rbPointCount - 1; ++i )
1587 if ( i < rbWeights.size() )
1588 nurbsWeights.append( rbWeights[i] );
1590 nurbsWeights.append( 1.0 );
1633 nurbsControlPoints.append( nurbsControlPoints.first() );
1634 if ( !nurbsWeights.isEmpty() )
1635 nurbsWeights.append( nurbsWeights.first() );
1643 digitizingFinished =
true;
1647 if ( digitizingFinished )
1650 std::unique_ptr<QgsCurve> curveToAdd;
1657 const int n = nurbsControlPoints.size();
1660 if ( n < degree + 1 )
1662 degree = std::max( 1, n - 1 );
1665 curveToAdd = std::make_unique<QgsLineString>( nurbsControlPoints );
1672 const int knotCount = n + degree + 1;
1673 QVector<double> knots( knotCount );
1676 for (
int i = 0; i <= degree; ++i )
1680 for (
int i = knotCount - degree - 1; i < knotCount; ++i )
1684 const int numMiddleKnots = n - degree - 1;
1685 for (
int i = 0; i < numMiddleKnots; ++i )
1687 knots[degree + 1 + i] =
static_cast<double>( i + 1 ) / ( numMiddleKnots + 1 );
1691 QVector<double> weights = nurbsWeights;
1692 while ( weights.size() < n )
1693 weights.append( 1.0 );
1694 weights.resize( n );
1696 curveToAdd = std::make_unique<QgsNurbsCurve>( nurbsControlPoints, degree, knots, weights );
1723 if ( hasCurvedSegments && providerSupportsCurvedSegments )
1738 poly->setExteriorRing( curveToAdd.release() );
@ CircularGeometries
Supports circular geometry types (circularstring, compoundcurve, curvepolygon).
CaptureTechnique
Capture technique.
@ NurbsCurve
Digitizes NURBS curves with control points.
@ StraightSegments
Default capture mode - capture occurs with straight line segments.
@ CircularString
Capture in circular strings.
@ Streaming
Streaming points digitizing mode (points are automatically added as the mouse cursor moves).
GeometryValidationEngine
Available engines for validating geometries.
@ QgisInternal
Use internal QgsGeometryValidator method.
@ Geos
Use GEOS validation methods.
@ Warning
Warning message.
WkbType
The WKB type describes the number of dimensions a geometry has.
@ CompoundCurve
CompoundCurve.
@ CircularString
CircularString.
@ Reverse
Reverse/inverse transform (from destination to source).
bool isMeasure() const
Returns true if the geometry contains m values.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
@ CapturePoint
Select and capture a point or a feature.
QgsCompoundCurve * clone() const override
Clones the geometry by performing a deep copy.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
int numPoints() const override
Returns the number of points in the curve.
Represents a coordinate reference system (CRS).
Custom exception class for Coordinate Reference System related exceptions.
Curve polygon geometry type.
Abstract base class for curved geometry type.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the feature ID that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void errorFound(const QgsGeometry::Error &error)
Sent when an error has been found during the validation process.
bool hasWhere() const
true if the location available from
QgsPointXY where() const
The coordinates at which the error is located and should be visualized.
QString what() const
A human readable error message containing details about the error.
A geometry is the spatial representation of a feature.
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
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.
static void convertPointList(const QVector< QgsPointXY > &input, QgsPointSequence &output)
Upgrades a point list from QgsPointXY to QgsPoint.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
Line string geometry type, with support for z-dimension and m-values.
double length() const override
Returns the planar, 2-dimensional length of the geometry.
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
QAction * actionEnableSnapping() const
Access to action that user may use to toggle snapping on/off.
void reportError(PathError err, bool addingVertex)
Report a path finding error to the user.
QAction * actionEnableTracing() const
Access to action that user may use to toggle tracing on/off. May be nullptr if no action was associat...
static QgsMapCanvasTracer * tracerForCanvas(QgsMapCanvas *canvas)
Retrieve instance of this class associated with given canvas (if any).
void currentLayerChanged(QgsMapLayer *layer)
Emitted when the current layer is changed.
Base class for all map layer types.
QgsCoordinateReferenceSystem crs
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
A mouse event which is the result of a user interaction with a QgsMapCanvas.
bool isSnapped() const
Returns true if there is a snapped point cached.
QgsPointXY mapPoint() const
mapPoint returns the point in coordinates
QgsPointLocator::Match mapPointMatch() const
Returns the matching data from the most recently snapped point.
Point geometry type, with support for z-dimension and m-values.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool dropMValue() override
Drops any measure values which exist in the geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
void setM(double m)
Sets the point's m-value.
bool convertTo(Qgis::WkbType type) override
Converts the geometry to a specified type.
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
void setZ(double z)
Sets the point's z-coordinate.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsCoordinateTransformContext transformContext
A QgsGeometry with associated coordinate reference system.
Responsible for drawing transient features (e.g.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryInteger * settingsDigitizingStreamTolerance
Settings entry digitizing stream tolerance.
static const QgsSettingsEntryDouble * settingsDigitizingLineColorAlphaScale
Settings entry digitizing line color alpha scale.
static const QgsSettingsEntryInteger * settingsDigitizingNurbsDegree
Settings entry digitizing NURBS curve degree.
static const QgsSettingsEntryDouble * settingsDigitizingConvertToCurveAngleTolerance
Settings entry digitizing convert to curve angle tolerance.
static const QgsSettingsEntryDouble * settingsDigitizingConvertToCurveDistanceTolerance
Settings entry digitizing convert to curve distance tolerance.
static const QgsSettingsEntryInteger * settingsDigitizingValidateGeometries
Settings entry digitizing validate geometries.
static const QgsSettingsEntryBool * settingsDigitizingConvertToCurve
Settings entry digitizing convert to curve.
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...
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.
PathError
Possible errors that may happen when calling findShortestPath().
@ ErrTooManyFeatures
Max feature count threshold was reached while reading features.
bool init()
Build the internal data structures.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
Represents a vector layer which manages a vector based dataset.
bool isSpatial() const final
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
Q_INVOKABLE QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
void setPenWidth(int width)
void setCenter(const QgsPointXY &point)
Sets the center point of the marker, in map coordinates.
void setIconType(int iconType)
void setColor(const QColor &color)
Sets the stroke color for the marker.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Q_INVOKABLE bool isNurbsType(Qgis::WkbType type)
Returns true if the WKB type is a NURBS curve type.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
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
#define BUILTIN_UNREACHABLE
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QgsFeatureId featureId() const
The id of the feature to which the snapped geometry belongs.
QgsVectorLayer * layer() const
The vector layer where the snap occurred.
QgsPoint interpolatedPoint(const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem()) const
Convenient method to return a point on an edge with linear interpolation of the Z value.
bool hasEdge() const
Returns true if the Match is an edge.
bool hasLineEndpoint() const
Returns true if the Match is a line endpoint (start or end vertex).
bool hasMiddleSegment() const
Returns true if the Match is the middle of a segment.
int vertexIndex() const
for vertex / edge match (first vertex of the edge)
bool hasVertex() const
Returns true if the Match is a vertex.
Setting options for loading vector layers.
bool skipCrsValidation
Controls whether the layer is allowed to have an invalid/unknown CRS.
bool loadDefaultStyle
Set to true if the default layer style should be loaded.
Utility class for identifying a unique vertex within a geometry.