QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 
18 #include "qgsgeometryrubberband.h"
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 
36 void 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 
84 void 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 
154 void QgsGeometryRubberBand::setLineStyle( Qt::PenStyle penStyle )
155 {
156  mPen.setStyle( penStyle );
157 }
158 
159 void QgsGeometryRubberBand::setBrushStyle( Qt::BrushStyle brushStyle )
160 {
161  mBrush.setStyle( brushStyle );
162 }
163 
165 {
166  mDrawVertices = isVerticesDrawn;
167 }
168 
169 QgsRectangle QgsGeometryRubberBand::rubberBandRectangle() const
170 {
171  if ( !mGeometry || mGeometry->isEmpty() )
172  {
173  return QgsRectangle();
174  }
175  const QgsMapToPixel &m2p = *( mMapCanvas->getCoordinateTransform() );
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 );
192  r.combineExtentWith( rect );
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 }
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsGeometryRubberBand::paint
void paint(QPainter *painter) override
function to be implemented by derived classes
Definition: qgsgeometryrubberband.cpp:36
QgsPointXY::y
double y
Definition: qgspointxy.h:63
QgsMapToPixel::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Definition: qgsmaptopixel.h:229
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
qgsmapcanvas.h
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:48
QgsMapCanvasItem::mMapCanvas
QgsMapCanvas * mMapCanvas
pointer to map canvas
Definition: qgsmapcanvasitem.h:82
QgsGeometryRubberBand::ICON_CROSS
@ ICON_CROSS
A cross is used to highlight points (+)
Definition: qgsgeometryrubberband.h:72
qgsgeometryrubberband.h
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsGeometryRubberBand::ICON_CIRCLE
@ ICON_CIRCLE
A circle is used to highlight points (○)
Definition: qgsgeometryrubberband.h:87
qgspoint.h
QgsMapToPixel::toMapCoordinates
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
Definition: qgsmaptopixel.h:173
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsGeometryRubberBand::ICON_BOX
@ ICON_BOX
A box is used to highlight points (□)
Definition: qgsgeometryrubberband.h:82
QgsMapCanvasItem::setRect
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
Definition: qgsmapcanvasitem.cpp:74
QgsGeometryRubberBand::geometryType
QgsWkbTypes::GeometryType geometryType() const
Returns which geometry is handled by the rubber band, polygon or line.
Definition: qgsgeometryrubberband.cpp:74
QgsGeometryRubberBand::setFillColor
void setFillColor(const QColor &c)
Sets fill color for vertex markers.
Definition: qgsgeometryrubberband.cpp:139
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
QgsPoint::y
double y
Definition: qgspoint.h:70
QgsMapCanvasItem
An abstract class for items that can be placed on the map canvas.
Definition: qgsmapcanvasitem.h:33
QgsMapCanvasItem::toCanvasCoordinates
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
Definition: qgsmapcanvasitem.cpp:61
QgsGeometryRubberBand::setLineStyle
void setLineStyle(Qt::PenStyle penStyle)
Sets pen style.
Definition: qgsgeometryrubberband.cpp:154
QgsGeometryRubberBand::QgsGeometryRubberBand
QgsGeometryRubberBand(QgsMapCanvas *mapCanvas, QgsWkbTypes::GeometryType geomType=QgsWkbTypes::LineGeometry)
Definition: qgsgeometryrubberband.cpp:25
qgsrendercontext.h
QgsGeometryRubberBand::updatePosition
void updatePosition() override
called on changed extent or resize event to update position of the item
Definition: qgsgeometryrubberband.cpp:204
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsScopedQPainterState
Scoped object for saving and restoring a QPainter object's state.
Definition: qgsrendercontext.h:1336
QgsMapCanvas::getCoordinateTransform
const QgsMapToPixel * getCoordinateTransform()
Gets the current coordinate transform.
Definition: qgsmapcanvas.cpp:379
QgsGeometryRubberBand::setGeometry
virtual void setGeometry(QgsAbstractGeometry *geom)
Sets geometry (takes ownership). Geometry is expected to be in map coordinates.
Definition: qgsgeometryrubberband.cpp:120
QgsGeometryRubberBand::ICON_FULL_BOX
@ ICON_FULL_BOX
A full box is used to highlight points (■)
Definition: qgsgeometryrubberband.h:92
QgsMapToPixel::transform
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
Definition: qgsmaptopixel.h:90
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:79
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsGeometryRubberBand::setBrushStyle
void setBrushStyle(Qt::BrushStyle brushStyle)
Sets brush style.
Definition: qgsgeometryrubberband.cpp:159
QgsGeometryRubberBand::setGeometryType
void setGeometryType(const QgsWkbTypes::GeometryType &geometryType)
Sets which geometry is handled by the rubber band, polygon or line.
Definition: qgsgeometryrubberband.cpp:79
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:140
QgsMapCanvasItem::rect
QgsRectangle rect() const
returns canvas item rectangle in map units
Definition: qgsmapcanvasitem.cpp:68
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
QgsMapToPixel
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:38
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
QgsGeometryRubberBand::moveVertex
void moveVertex(QgsVertexId id, const QgsPoint &newPos)
Moves vertex to new position (in map coordinates)
Definition: qgsgeometryrubberband.cpp:130
QgsGeometryRubberBand::ICON_NONE
@ ICON_NONE
No icon is used.
Definition: qgsgeometryrubberband.h:67
QgsGeometryRubberBand::setVertexDrawingEnabled
void setVertexDrawingEnabled(bool isVerticesDrawn)
Sets whether the vertices are drawn.
Definition: qgsgeometryrubberband.cpp:164
QgsGeometryRubberBand::setStrokeWidth
void setStrokeWidth(int width)
Sets stroke width.
Definition: qgsgeometryrubberband.cpp:149
QgsGeometryRubberBand::setStrokeColor
void setStrokeColor(const QColor &c)
Sets stroke color for vertex markers.
Definition: qgsgeometryrubberband.cpp:144
qgsabstractgeometry.h
QgsPoint::x
double x
Definition: qgspoint.h:69
QgsGeometryRubberBand::ICON_X
@ ICON_X
A cross is used to highlight points (x)
Definition: qgsgeometryrubberband.h:77
QgsGeometryRubberBand::~QgsGeometryRubberBand
~QgsGeometryRubberBand() override
Definition: qgsgeometryrubberband.cpp:32