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 )
443 mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
448 mCurrentShapeMapTool->deactivate();
455 return mRubberBand.release();
476 if ( mCurrentCaptureTechnique == technique )
479 mStartNewCurve =
true;
483 setCurrentShapeMapToolIsActivated(
false );
507 if ( mTempRubberBand )
508 mTempRubberBand->setStringType( mLineDigitizingType );
510 mCurrentCaptureTechnique = technique;
515 setCurrentShapeMapToolIsActivated(
true );
521 if ( mCurrentShapeMapTool )
523 if ( shapeMapToolMetadata && mCurrentShapeMapTool->
id() == shapeMapToolMetadata->
id() )
527 setCurrentShapeMapToolIsActivated(
false );
529 mCurrentShapeMapTool->deleteLater();
532 mCurrentShapeMapTool.reset( shapeMapToolMetadata ? shapeMapToolMetadata->
factory(
this ) :
nullptr );
537 if ( mCurrentShapeMapTool )
539 setCurrentShapeMapToolIsActivated(
true );
547 if ( mCaptureModeFromLayer && ( !
canvas()->currentLayer() || !
canvas()->currentLayer()->isSpatial() ) )
558 if ( !mCurrentShapeMapTool )
564 if ( !mTempRubberBand )
566 mTempRubberBand.reset( createCurveRubberBand() );
567 mTempRubberBand->setStringType( mLineDigitizingType );
571 mCurrentShapeMapTool->cadCanvasMoveEvent( e, mCaptureMode );
583 targetCrs = l->crs();
586 if ( mCaptureMode !=
CapturePoint && mTempRubberBand && mCapturing )
588 bool hasTrace =
false;
592 if ( !mCaptureCurve.isEmpty() )
594 const QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint();
599 mAllowAddingStreamingPoints =
true;
601 mAllowAddingStreamingPoints =
false;
603 std::unique_ptr< QgsCompoundCurve > tempCurve( mCaptureCurve.clone() );
606 auto curvePolygon = std::make_unique< QgsCurvePolygon >();
608 curvePolygon->setExteriorRing( tempCurve.release() );
616 else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
622 mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 );
624 mCircularItermediatePoint =
QgsPoint();
626 hasTrace = tracingMouseMove( e );
632 mTempRubberBand->addPoint( mCaptureLastPoint );
633 if ( !mCircularItermediatePoint.isEmpty() )
635 mTempRubberBand->movePoint( mCircularItermediatePoint );
636 mTempRubberBand->addPoint( mCircularItermediatePoint );
643 if ( mCaptureCurve.numPoints() > 0 )
645 const QgsPoint mapPt = mCaptureLastPoint;
647 if ( mTempRubberBand )
649 mTempRubberBand->movePoint(
mapPoint );
650 mTempRubberBand->movePoint( 0, mapPt );
654 if ( mRubberBand->numberOfVertices() )
655 mRubberBand->movePoint( mapPt );
657 std::unique_ptr< QgsCompoundCurve > tempCurve( mCaptureCurve.clone() );
664 tempCurve->addCurve(
new QgsLineString( tempCurve->endPoint(), hoverPointTargetCrs ) );
673 auto curvePolygon = std::make_unique< QgsCurvePolygon >();
675 curvePolygon->setExteriorRing( tempCurve.release() );
683 else if ( mTempRubberBand )
684 mTempRubberBand->movePoint(
mapPoint );
698 const bool is3D = layerPoint.
is3D();
699 const bool isMeasure = layerPoint.
isMeasure();
701 layerPoint =
QgsPoint( layerPoint.
wkbType(), mapP.
x(), mapP.
y(), layerPoint.
z(), layerPoint.
m() );
709 QgsDebugError( u
"transformation to layer coordinate failed"_s );
741 if ( match.
isValid() && sourceLayer )
745 if ( sourceLayer->
crs() != vlayer->
crs() )
828 mCaptureCurve.addVertex( layerPoint );
829 mSnappingMatches.append( match );
833 if ( mCaptureFirstPoint.isEmpty() )
841 if ( !mTempRubberBand )
843 mTempRubberBand.reset( createCurveRubberBand() );
844 mTempRubberBand->setStringType( mLineDigitizingType );
848 bool traceCreated =
false;
849 if ( tracingEnabled() )
851 traceCreated = tracingAddVertex(
mapPoint );
856 mTracingStartPoint = traceCreated ? point :
QgsPointXY();
861 mTempRubberBand->movePoint(
mapPoint );
862 if ( mTempRubberBand->curveIsComplete() )
864 if (
QgsCurve *curve = mTempRubberBand->curve() )
869 if ( match.
isValid() && mSnappingMatches.count() > 0 && !mSnappingMatches.last().isValid() )
871 mSnappingMatches.removeLast();
875 mSnappingMatches.removeLast();
876 mSnappingMatches.append( mCircularIntermediateMatch );
878 mSnappingMatches.append( match );
884 else if ( mTempRubberBand->pointsCount() == 0 )
887 mCaptureCurve.addVertex( layerPoint );
888 mSnappingMatches.append( match );
894 mCircularIntermediateMatch = match;
898 mTempRubberBand->addPoint(
mapPoint );
903 mTempRubberBand->addPoint( mCaptureLastPoint );
907 updateExtraSnapLayer();
925 if ( mTempRubberBand )
929 mTempRubberBand->addPoint( endPt );
932 const int countBefore = mCaptureCurve.vertexCount();
934 if ( mCaptureCurve.numPoints() == 1 )
935 mCaptureCurve.removeCurve( 0 );
945 mCaptureCurve.addCurve( segmented,
false );
952 mCaptureCurve.addCurve(
c, !mStartNewCurve );
955 mStartNewCurve =
false;
957 const int countAfter = mCaptureCurve.vertexCount();
958 const int addedPoint = countAfter - countBefore;
960 updateExtraSnapLayer();
962 for (
int i = 0; i < addedPoint; ++i )
972 mCaptureCurve.clear();
973 updateExtraSnapLayer();
978 return mSnappingMatches;
985 if ( mTempRubberBand )
987 if (
size() <= 1 && mTempRubberBand->pointsCount() != 0 )
990 if ( isAutoRepeat && mIgnoreSubsequentAutoRepeatUndo )
992 mIgnoreSubsequentAutoRepeatUndo =
false;
994 const QgsPoint lastPoint = mTempRubberBand->lastPoint();
998 mTempRubberBand->removeLastPoint();
999 mTempRubberBand->movePoint( lastPoint );
1006 mTempRubberBand->removeLastPoint();
1007 mTempRubberBand->movePoint( lastPoint );
1013 vertexToRemove.
part = 0;
1014 vertexToRemove.
ring = 0;
1021 mCaptureCurve.removeCurve( mCaptureCurve.nCurves() - 1 );
1023 if ( mCaptureCurve.numPoints() == 2 && mCaptureCurve.nCurves() == 1 )
1027 const QgsPoint fp = mCaptureCurve.startPoint();
1029 mCaptureCurve.addVertex( fp );
1033 const int curvesBefore = mCaptureCurve.nCurves();
1036 const int pointsCountBefore = mCaptureCurve.numPoints();
1037 mCaptureCurve.deleteVertex( vertexToRemove );
1038 int pointsCountAfter = mCaptureCurve.numPoints();
1039 for ( ; pointsCountAfter < pointsCountBefore; pointsCountAfter++ )
1040 if ( !mSnappingMatches.empty() )
1041 mSnappingMatches.removeLast();
1047 if ( mCaptureCurve.nCurves() < curvesBefore && lastCurveIsLineString )
1048 mIgnoreSubsequentAutoRepeatUndo =
true;
1051 updateExtraSnapLayer();
1057 if ( mCaptureCurve.numPoints() > 0 )
1059 const QgsPoint lastPt = mCaptureCurve.endPoint();
1061 mTempRubberBand->addPoint( mCaptureLastPoint );
1062 mTempRubberBand->movePoint( lastPoint );
1074 mCurrentShapeMapTool->keyPressEvent( e );
1075 if ( e->isAccepted() )
1086 if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
1090 if ( !e->isAutoRepeat() )
1092 mCurrentShapeMapTool->undo();
1097 undo( e->isAutoRepeat() );
1103 else if ( e->key() == Qt::Key_Escape )
1105 if ( mCurrentShapeMapTool )
1106 mCurrentShapeMapTool->clean();
1113 else if ( e->key() == Qt::Key_W && !e->isAutoRepeat() )
1118 mWeightEditMode =
true;
1120 mWeightEditControlPointIndex = mTempRubberBand->pointsCount() - 2;
1125 cadDockWidget()->
setWeight( QString::number( mTempRubberBand->weight( mWeightEditControlPointIndex ),
'f', 2 ),
true );
1134 if ( e->key() == Qt::Key_W && !e->isAutoRepeat() )
1136 if ( mWeightEditMode )
1138 mWeightEditMode =
false;
1139 mWeightEditControlPointIndex = -1;
1157 if ( mWeightEditMode )
1163 double adjustment = e->angleDelta().y() > 0 ? 0.1 : -0.1;
1164 if ( e->modifiers() & Qt::ControlModifier )
1166 else if ( e->modifiers() & Qt::ShiftModifier )
1169 const double currentWeight = mTempRubberBand->weight( mWeightEditControlPointIndex );
1170 const double newWeight = std::max( 0.01, currentWeight + adjustment );
1172 if ( mTempRubberBand->setWeight( mWeightEditControlPointIndex, newWeight ) )
1199 mRubberBand.reset();
1204 if ( mWeightEditMode )
1206 mWeightEditMode =
false;
1207 mWeightEditControlPointIndex = -1;
1214 qDeleteAll( mGeomErrorMarkers );
1215 mGeomErrorMarkers.clear();
1216 mGeomErrors.clear();
1224 mCaptureCurve.clear();
1225 updateExtraSnapLayer();
1226 mSnappingMatches.clear();
1228 lCurrentVectorLayer->triggerRepaint();
1233 mTempRubberBand.reset();
1240 mCurrentShapeMapTool->clean();
1247 mCaptureCurve.close();
1248 updateExtraSnapLayer();
1251void QgsMapToolCapture::validateGeometry()
1259 mValidator->deleteLater();
1260 mValidator =
nullptr;
1263 mGeomErrors.clear();
1264 while ( !mGeomErrorMarkers.isEmpty() )
1266 delete mGeomErrorMarkers.takeFirst();
1271 switch ( mCaptureMode )
1279 geom = QgsGeometry( mCaptureCurve.curveToLine() );
1284 QgsLineString *exteriorRing = mCaptureCurve.curveToLine();
1285 exteriorRing->
close();
1286 QgsPolygon *polygon =
new QgsPolygon();
1288 geom = QgsGeometry( polygon );
1298 mValidator =
new QgsGeometryValidator( geom,
nullptr, method );
1300 mValidator->start();
1307 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>(
layer() );
1313 QgsVertexMarker *vm =
new QgsVertexMarker(
mCanvas );
1317 vm->setToolTip( e.
what() );
1319 vm->setZValue( vm->zValue() + 1 );
1320 mGeomErrorMarkers << vm;
1326 return mCaptureCurve.numPoints();
1331 QVector<QgsPointXY> pointsXY;
1340 mCaptureCurve.points( pts );
1347 mCaptureCurve.clear();
1348 mCaptureCurve.addCurve( line );
1349 updateExtraSnapLayer();
1350 mSnappingMatches.clear();
1351 for (
int i = 0; i < line->
length(); ++i )
1359 mCaptureCurve.clear();
1360 mCaptureCurve.addCurve( line );
1361 updateExtraSnapLayer();
1362 mSnappingMatches.clear();
1363 for (
int i = 0; i < line->
length(); ++i )
1420 if ( match.
layer() )
1438void QgsMapToolCapture::updateExtraSnapLayer()
1440 if ( !mExtraSnapLayer )
1443 if (
canvas()->snappingUtils()->config().selfSnapping() &&
layer() && mCaptureCurve.
numPoints() >= 2 )
1453 mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
1458 mExtraSnapLayer->changeGeometry( mExtraSnapFeatureId, geom );
1468 if ( e->button() != Qt::LeftButton )
1472 bool isMatchPointZ =
false;
1473 bool isMatchPointM =
false;
1484 if ( isMatchPointM && isMatchPointZ )
1488 else if ( isMatchPointM )
1492 else if ( isMatchPointZ )
1496 savePoint =
QgsPoint( geomType, fetchPoint.
x(), fetchPoint.
y(), fetchPoint.
z(), fetchPoint.
m() );
1502 savePoint =
QgsPoint( point.
x(), point.
y(), fetchPoint.
z(), fetchPoint.
m() );
1512 QgsGeometry g( std::make_unique<QgsPoint>( savePoint ) );
1529 bool digitizingFinished =
false;
1531 QVector<double> nurbsWeights;
1535 if ( !mCurrentShapeMapTool )
1542 if ( !mTempRubberBand )
1544 mTempRubberBand.reset( createCurveRubberBand() );
1545 mTempRubberBand->setStringType( mLineDigitizingType );
1549 digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, mCaptureMode );
1550 if ( digitizingFinished )
1551 mCurrentShapeMapTool->clean();
1557 if ( e->button() == Qt::LeftButton )
1569 else if ( e->button() == Qt::RightButton )
1576 const int rbPointCount = mTempRubberBand->pointsCount();
1577 if ( rbPointCount > 1 )
1580 for (
int i = 0; i < rbPointCount - 1; ++i )
1582 nurbsControlPoints.append( mTempRubberBand->pointFromEnd( rbPointCount - 1 - i ) );
1585 const QVector<double> &rbWeights = mTempRubberBand->weights();
1586 for (
int i = 0; i < rbPointCount - 1; ++i )
1588 if ( i < rbWeights.size() )
1589 nurbsWeights.append( rbWeights[i] );
1591 nurbsWeights.append( 1.0 );
1634 nurbsControlPoints.append( nurbsControlPoints.first() );
1635 if ( !nurbsWeights.isEmpty() )
1636 nurbsWeights.append( nurbsWeights.first() );
1644 digitizingFinished =
true;
1648 if ( digitizingFinished )
1651 std::unique_ptr<QgsCurve> curveToAdd;
1658 const int n = nurbsControlPoints.size();
1661 if ( n < degree + 1 )
1663 degree = std::max( 1, n - 1 );
1666 curveToAdd = std::make_unique<QgsLineString>( nurbsControlPoints );
1673 const int knotCount = n + degree + 1;
1674 QVector<double> knots( knotCount );
1677 for (
int i = 0; i <= degree; ++i )
1681 for (
int i = knotCount - degree - 1; i < knotCount; ++i )
1685 const int numMiddleKnots = n - degree - 1;
1686 for (
int i = 0; i < numMiddleKnots; ++i )
1688 knots[degree + 1 + i] =
static_cast<double>( i + 1 ) / ( numMiddleKnots + 1 );
1692 QVector<double> weights = nurbsWeights;
1693 while ( weights.size() < n )
1694 weights.append( 1.0 );
1695 weights.resize( n );
1697 curveToAdd = std::make_unique<QgsNurbsCurve>( nurbsControlPoints, degree, knots, weights );
1724 if ( hasCurvedSegments && providerSupportsCurvedSegments )
1739 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.