25 , mLockedPen( QPen( QColor( 0, 127, 0, 255 ), 1, Qt::DashLine ) )
26 , mConstruction1Pen( QPen( QColor( 127, 127, 127, 150 ), 1, Qt::DashLine ) )
27 , mConstruction2Pen( QPen( QColor( 127, 127, 127, 255 ), 1, Qt::DashLine ) )
28 , mSnapPen( QPen( QColor( 127, 0, 0, 150 ), 1 ) )
29 , mSnapLinePen( QPen( QColor( 127, 0, 0, 150 ), 1, Qt::DashLine ) )
30 , mCursorPen( QPen( QColor( 127, 127, 127, 255 ), 1 ) )
31 , mAdvancedDigitizingDockWidget( cadDockWidget )
37 if ( !mAdvancedDigitizingDockWidget->
cadEnabled() )
42 const double canvasWidth = QLineF( mapPoly[0], mapPoly[1] ).length();
43 const double canvasHeight = QLineF( mapPoly[0], mapPoly[3] ).length();
45 const int nPoints = mAdvancedDigitizingDockWidget->
pointsCount();
49 bool previousPointExist, penulPointExist;
53 const bool snappedToVertex = mAdvancedDigitizingDockWidget->
snappedToVertex();
54 const QList<QgsPointXY> snappedSegment = mAdvancedDigitizingDockWidget->
snappedSegment();
55 const bool hasSnappedSegment = snappedSegment.count() == 2;
57 const bool curPointExist = mapPoly.containsPoint( curPoint.
toQPointF(), Qt::OddEvenFill );
64 const double canvasDiagonalDimension = ( canvasWidth + canvasHeight ) / mupp ;
66 QPointF curPointPix, prevPointPix, penulPointPix, snapSegmentPix1, snapSegmentPix2;
72 if ( previousPointExist )
76 if ( penulPointExist )
80 if ( hasSnappedSegment )
86 painter->setRenderHint( QPainter::Antialiasing );
87 painter->setCompositionMode( QPainter::CompositionMode_Difference );
90 if ( curPointExist && snappedToVertex )
92 painter->setPen( mSnapPen );
93 painter->drawEllipse( curPointPix, 10, 10 );
97 if ( hasSnappedSegment && !snappedToVertex )
99 painter->setPen( mSnapPen );
100 painter->drawLine( snapSegmentPix1, snapSegmentPix2 );
104 painter->setPen( mSnapLinePen );
105 painter->drawLine( snapSegmentPix1, curPointPix );
112 painter->setPen( mConstruction2Pen );
113 painter->drawLine( snapSegmentPix1, snapSegmentPix2 );
122 a0 = std::atan2( -( prevPoint.
y() - penulPoint.
y() ), prevPoint.
x() - penulPoint.
x() );
134 a = std::atan2( -( curPoint.
y() - prevPoint.
y() ), curPoint.
x() - prevPoint.
x() );
137 a0 += canvasRotationRad;
138 a += canvasRotationRad;
140 painter->setPen( mConstruction2Pen );
141 painter->drawArc( QRectF( prevPointPix.x() - 20,
142 prevPointPix.y() - 20,
144 static_cast<int>( 16 * -a0 * 180 / M_PI ),
145 static_cast<int>( 16 * ( a0 - a ) * 180 / M_PI ) );
146 painter->drawLine( prevPointPix,
147 prevPointPix + 60 * QPointF( std::cos( a0 ), std::sin( a0 ) ) );
152 painter->setPen( mLockedPen );
153 const double canvasPadding = QLineF( prevPointPix, curPointPix ).length();
154 painter->drawLine( prevPointPix + ( canvasPadding - canvasDiagonalDimension ) * QPointF( std::cos( a ), std::sin( a ) ),
155 prevPointPix + ( canvasPadding + canvasDiagonalDimension ) * QPointF( std::cos( a ), std::sin( a ) ) );
162 painter->setPen( mLockedPen );
164 QPainterPath ellipsePath;
165 ellipsePath.addEllipse( prevPointPix, r, r );
166 const double a = std::atan2( -( curPoint.
y() - prevPoint.
y() ), curPoint.
x() - prevPoint.
x() ) + canvasRotationRad;
167 const QTransform t = QTransform().translate( prevPointPix.x(), prevPointPix.y() ).rotateRadians( a ).translate( -prevPointPix.x(), -prevPointPix.y() );
168 const QPolygonF ellipsePoly = ellipsePath.toFillPolygon( t );
169 painter->drawPolygon( ellipsePoly );
177 painter->setPen( mLockedPen );
195 painter->drawLine(
toCanvasCoordinates(
QgsPointXY( x, mapPoly[0].y() ) ) - canvasDiagonalDimension * QPointF( std::sin( -canvasRotationRad ), std::cos( -canvasRotationRad ) ),
196 toCanvasCoordinates(
QgsPointXY( x, mapPoly[0].y() ) ) + canvasDiagonalDimension * QPointF( std::sin( -canvasRotationRad ), std::cos( -canvasRotationRad ) ) );
205 painter->setPen( mLockedPen );
223 painter->drawLine(
toCanvasCoordinates(
QgsPointXY( mapPoly[0].x(), y ) ) - canvasDiagonalDimension * QPointF( std::cos( -canvasRotationRad ), -std::sin( -canvasRotationRad ) ),
224 toCanvasCoordinates(
QgsPointXY( mapPoly[0].x(), y ) ) + canvasDiagonalDimension * QPointF( std::cos( -canvasRotationRad ), -std::sin( -canvasRotationRad ) ) );
232 if ( curPointExist && previousPointExist )
234 painter->setPen( mConstruction2Pen );
235 painter->drawLine( prevPointPix, curPointPix );
238 if ( previousPointExist && penulPointExist )
240 painter->setPen( mConstruction1Pen );
241 painter->drawLine( penulPointPix, prevPointPix );
247 painter->setPen( mCursorPen );
248 painter->drawLine( curPointPix + QPointF( -5, -5 ),
249 curPointPix + QPointF( +5, +5 ) );
250 painter->drawLine( curPointPix + QPointF( -5, +5 ),
251 curPointPix + QPointF( +5, -5 ) );
259 painter->setPen( mLockedPen );
280 const double angle = std::atan2( snappedPoint.y() - point.y(), snappedPoint.x() - point.x() );
282 const double canvasPadding = QLineF( snappedPoint, curPointPix ).length();
283 painter->drawLine( snappedPoint + ( canvasPadding - canvasDiagonalDimension ) * QPointF( std::cos(
angle ), std::sin(
angle ) ),
284 snappedPoint + ( canvasPadding + canvasDiagonalDimension ) * QPointF( std::cos(
angle ), std::sin(
angle ) ) );
291 painter->setPen( mLockedPen );
293 double coordinateExtension = mAdvancedDigitizingDockWidget->
softLockX();
294 if ( coordinateExtension != std::numeric_limits<double>::quiet_NaN() )
296 const QgsPointXY point( coordinateExtension, mapPoly[0].y() );
297 const QPointF rotation( std::sin( -canvasRotationRad ), std::cos( -canvasRotationRad ) );
302 coordinateExtension = mAdvancedDigitizingDockWidget->
softLockY();
303 if ( coordinateExtension != std::numeric_limits<double>::quiet_NaN() )
305 const QgsPointXY point( mapPoly[0].x(), coordinateExtension );
306 const QPointF rotation( std::cos( -canvasRotationRad ), -std::sin( -canvasRotationRad ) );
312 painter->setPen( mCursorPen );
314 const QList< QgsPointLocator::Match > lockedSnapVertices = mAdvancedDigitizingDockWidget->
lockedSnapVertices();
320 painter->drawLine( canvasPoint + QPointF( 5, 5 ),
321 canvasPoint - QPointF( 5, 5 ) );
322 painter->drawLine( canvasPoint + QPointF( -5, 5 ),
323 canvasPoint - QPointF( -5, 5 ) );
326 if ( !lockedSnapVertices.isEmpty() )
328 const QgsPointXY point = lockedSnapVertices.last().point();
331 painter->drawLine( canvasPoint + QPointF( 0, 5 ),
332 canvasPoint - QPointF( 0, 5 ) );
333 painter->drawLine( canvasPoint + QPointF( 5, 0 ),
334 canvasPoint - QPointF( 5, 0 ) );
342 const double canvasWidth = QLineF( mapPoly[0], mapPoly[1] ).length();
343 const double canvasHeight = QLineF( mapPoly[0], mapPoly[3] ).length();
346 mapPoly[0].x() + canvasWidth,
347 mapPoly[0].y() - canvasHeight
350 if (
rect() != mapRect )
@ NoConstraint
No additional constraint.
@ NoVertex
Don't lock to vertex.
@ BeforeVertex
Lock to previous vertex.
void paint(QPainter *painter) override
function to be implemented by derived classes
void updatePosition() override
called on changed extent or resize event to update position of the item
QgsAdvancedDigitizingCanvasItem(QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget)
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
A geometry is the spatial representation of a feature.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
An abstract class for items that can be placed on the map canvas.
QgsRectangle rect() const
returns canvas item rectangle in map units
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
QgsMapCanvas * mMapCanvas
pointer to map canvas
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
Map canvas is a class for displaying all GIS data types on a canvas.
double rotation() const
Gets the current map canvas rotation in clockwise degrees.
const QgsMapToPixel * getCoordinateTransform()
Gets the current coordinate transform.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QPolygonF visiblePolygon() const
Returns the visible area as a polygon (may be rotated)
double mapUnitsPerPixel() const
Returns the current map units per pixel.
A class to represent a 2D point.
QPointF toQPointF() const
Converts a point to a QPointF.
Point geometry type, with support for z-dimension and m-values.
bool isEmpty() const override
Returns true if the geometry is empty.
A rectangle specified with double values.
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
QgsFeatureId featureId() const
The id of the feature to which the snapped geometry belongs.
QgsVectorLayer * layer() const
The vector layer where the snap occurred.
QgsPointXY point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords,...
int vertexIndex() const
for vertex / edge match (first vertex of the edge)