QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsgeometryrubberband.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometryrubberband.cpp
3 -------------------------
4 begin : December 2014
5 copyright : (C) 2014 by Marco Hugentobler
6 email : marco at sourcepole dot ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "qgsabstractgeometry.h"
20#include "qgsmapcanvas.h"
21#include "qgsrendercontext.h"
22#include "qgspoint.h"
23#include <QPainter>
24
26 mIconSize( 5 ), mIconType( ICON_BOX ), mGeometryType( geomType )
27{
28 mPen = QPen( QColor( 255, 0, 0 ) );
29 mBrush = QBrush( QColor( 255, 0, 0 ) );
30}
31
33{
34}
35
36void QgsGeometryRubberBand::paint( QPainter *painter )
37{
38 if ( !mGeometry || !painter )
39 {
40 return;
41 }
42
43 const QgsScopedQPainterState painterState( painter );
44 painter->translate( -pos() );
45
46 if ( mGeometryType == QgsWkbTypes::PolygonGeometry )
47 {
48 painter->setBrush( mBrush );
49 }
50 else
51 {
52 painter->setBrush( Qt::NoBrush );
53 }
54 painter->setPen( mPen );
55
56
57 std::unique_ptr< QgsAbstractGeometry > paintGeom( mGeometry->clone() );
58
59 paintGeom->transform( mMapCanvas->getCoordinateTransform()->transform() );
60 paintGeom->draw( *painter );
61
62 if ( !mDrawVertices )
63 return;
64
65 //draw vertices
66 QgsVertexId vertexId;
67 QgsPoint vertex;
68 while ( paintGeom->nextVertex( vertexId, vertex ) )
69 {
70 drawVertex( painter, vertex.x(), vertex.y() );
71 }
72}
73
75{
76 return mGeometryType;
77}
78
80{
81 mGeometryType = geometryType;
82}
83
84void QgsGeometryRubberBand::drawVertex( QPainter *p, double x, double y )
85{
86 const qreal s = ( mIconSize - 1 ) / 2.0;
87
88 switch ( mIconType )
89 {
90 case ICON_NONE:
91 break;
92
93 case ICON_CROSS:
94 p->drawLine( QLineF( x - s, y, x + s, y ) );
95 p->drawLine( QLineF( x, y - s, x, y + s ) );
96 break;
97
98 case ICON_X:
99 p->drawLine( QLineF( x - s, y - s, x + s, y + s ) );
100 p->drawLine( QLineF( x - s, y + s, x + s, y - s ) );
101 break;
102
103 case ICON_BOX:
104 p->drawLine( QLineF( x - s, y - s, x + s, y - s ) );
105 p->drawLine( QLineF( x + s, y - s, x + s, y + s ) );
106 p->drawLine( QLineF( x + s, y + s, x - s, y + s ) );
107 p->drawLine( QLineF( x - s, y + s, x - s, y - s ) );
108 break;
109
110 case ICON_FULL_BOX:
111 p->drawRect( x - s, y - s, mIconSize, mIconSize );
112 break;
113
114 case ICON_CIRCLE:
115 p->drawEllipse( x - s, y - s, mIconSize, mIconSize );
116 break;
117 }
118}
119
121{
122 mGeometry.reset( geom );
123
124 if ( mGeometry )
125 {
126 setRect( rubberBandRectangle() );
127 }
128}
129
131{
132 if ( mGeometry )
133 {
134 mGeometry->moveVertex( id, newPos );
135 setRect( rubberBandRectangle() );
136 }
137}
138
140{
141 mBrush.setColor( c );
142}
143
145{
146 mPen.setColor( c );
147}
148
150{
151 mPen.setWidth( width );
152}
153
154void QgsGeometryRubberBand::setLineStyle( Qt::PenStyle penStyle )
155{
156 mPen.setStyle( penStyle );
157}
158
159void QgsGeometryRubberBand::setBrushStyle( Qt::BrushStyle brushStyle )
160{
161 mBrush.setStyle( brushStyle );
162}
163
165{
166 mDrawVertices = isVerticesDrawn;
167}
168
169QgsRectangle QgsGeometryRubberBand::rubberBandRectangle() const
170{
171 if ( !mGeometry || mGeometry->isEmpty() )
172 {
173 return QgsRectangle();
174 }
176
177 qreal w = ( ( mIconSize - 1 ) / 2 + mPen.width() ); // in canvas units
178
179 QgsRectangle r; // in canvas units
180 QgsRectangle rectMap = mGeometry->boundingBox(); // in map units
181 QList<QgsPointXY> pl;
182 pl << QgsPointXY( rectMap.xMinimum(), rectMap.yMinimum() )
183 << QgsPointXY( rectMap.xMinimum(), rectMap.yMaximum() )
184 << QgsPointXY( rectMap.xMaximum(), rectMap.yMaximum() )
185 << QgsPointXY( rectMap.xMaximum(), rectMap.yMinimum() );
186
187 for ( QgsPointXY &p : pl )
188 {
189 p = toCanvasCoordinates( p );
190 // no need to normalize the rectangle -- we know it is already normal
191 QgsRectangle rect( p.x() - w, p.y() - w, p.x() + w, p.y() + w, false );
193 }
194
195 // This is an hack to pass QgsMapCanvasItem::setRect what it
196 // expects (encoding of position and size of the item)
197 qreal res = m2p.mapUnitsPerPixel();
198 QgsPointXY topLeft = m2p.toMapCoordinates( r.xMinimum(), r.yMinimum() );
199 QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + r.width()*res, topLeft.y() - r.height()*res );
200
201 return rect;
202}
203
205{
206 // re-compute rectangle
207 // See https://github.com/qgis/QGIS/issues/20566
208 // NOTE: could be optimized by saving map-extent
209 // of rubberband and simply re-projecting
210 // that to device-rectangle on "updatePosition"
211 setRect( rubberBandRectangle() );
212}
Abstract base class for all geometries.
void setStrokeColor(const QColor &c)
Sets stroke color for vertex markers.
@ ICON_X
A cross is used to highlight points (x)
@ ICON_NONE
No icon is used.
@ ICON_FULL_BOX
A full box is used to highlight points (■)
@ ICON_CIRCLE
A circle is used to highlight points (○)
@ ICON_BOX
A box is used to highlight points (□)
@ ICON_CROSS
A cross is used to highlight points (+)
QgsWkbTypes::GeometryType geometryType() const
Returns which geometry is handled by the rubber band, polygon or line.
void setBrushStyle(Qt::BrushStyle brushStyle)
Sets brush style.
void setGeometryType(const QgsWkbTypes::GeometryType &geometryType)
Sets which geometry is handled by the rubber band, polygon or line.
void updatePosition() override
called on changed extent or resize event to update position of the item
void setLineStyle(Qt::PenStyle penStyle)
Sets pen style.
virtual void setGeometry(QgsAbstractGeometry *geom)
Sets geometry (takes ownership). Geometry is expected to be in map coordinates.
void paint(QPainter *painter) override
function to be implemented by derived classes
void moveVertex(QgsVertexId id, const QgsPoint &newPos)
Moves vertex to new position (in map coordinates)
void setStrokeWidth(int width)
Sets stroke width.
void setVertexDrawingEnabled(bool isVerticesDrawn)
Sets whether the vertices are drawn.
QgsGeometryRubberBand(QgsMapCanvas *mapCanvas, QgsWkbTypes::GeometryType geomType=QgsWkbTypes::LineGeometry)
void setFillColor(const QColor &c)
Sets fill color for vertex markers.
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.
Definition: qgsmapcanvas.h:90
const QgsMapToPixel * getCoordinateTransform()
Gets the current coordinate transform.
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
Definition: qgsmaptopixel.h:90
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Q_GADGET double x
Definition: qgspoint.h:52
double y
Definition: qgspoint.h:53
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
Scoped object for saving and restoring a QPainter object's state.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
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
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:31