QGIS API Documentation  2.99.0-Master (9fdd060)
qgsrubberband.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrubberband.cpp - Rubberband widget for drawing multilines and polygons
3  --------------------------------------
4  Date : 07-Jan-2006
5  Copyright : (C) 2006 by Tom Elwertowski
6  Email : telwertowski at users dot sourceforge dot net
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsrubberband.h"
17 #include "qgsfeature.h"
18 #include "qgsgeometry.h"
19 #include "qgslogger.h"
20 #include "qgsmapcanvas.h"
21 #include "qgsvectorlayer.h"
22 #include <QPainter>
23 
25  : QgsMapCanvasItem( mapCanvas )
26  , mGeometryType( geometryType )
27 {
28  reset( geometryType );
29  QColor color( Qt::lightGray );
30  color.setAlpha( 63 );
31  setColor( color );
32  setWidth( 1 );
33  setLineStyle( Qt::SolidLine );
34  setBrushStyle( Qt::SolidPattern );
35  setSecondaryStrokeColor( QColor() );
36 }
37 
39  : QgsMapCanvasItem( nullptr )
40 {
41 }
42 
43 void QgsRubberBand::setColor( const QColor &color )
44 {
45  setStrokeColor( color );
46  setFillColor( color );
47 }
48 
49 void QgsRubberBand::setFillColor( const QColor &color )
50 {
51  mBrush.setColor( color );
52 }
53 
54 void QgsRubberBand::setStrokeColor( const QColor &color )
55 {
56  mPen.setColor( color );
57 }
58 
59 void QgsRubberBand::setSecondaryStrokeColor( const QColor &color )
60 {
61  mSecondaryPen.setColor( color );
62 }
63 
65 {
66  mPen.setWidth( width );
67 }
68 
70 {
71  mIconType = icon;
72 }
73 
75 {
76  mIconSize = iconSize;
77 }
78 
79 void QgsRubberBand::setLineStyle( Qt::PenStyle penStyle )
80 {
81  mPen.setStyle( penStyle );
82 }
83 
84 void QgsRubberBand::setBrushStyle( Qt::BrushStyle brushStyle )
85 {
86  mBrush.setStyle( brushStyle );
87 }
88 
90 {
91  mPoints.clear();
92  mGeometryType = geometryType;
93  updateRect();
94  update();
95 }
96 
97 void QgsRubberBand::addPoint( const QgsPointXY &p, bool doUpdate /* = true */, int geometryIndex )
98 {
99  if ( geometryIndex < 0 )
100  {
101  geometryIndex = mPoints.size() - 1;
102  }
103 
104  if ( geometryIndex < 0 || geometryIndex > mPoints.size() )
105  {
106  return;
107  }
108 
109  if ( geometryIndex == mPoints.size() )
110  {
111  mPoints.push_back( QList<QgsPointXY>() << p );
112  }
113 
114  if ( mPoints.at( geometryIndex ).size() == 2 &&
115  mPoints.at( geometryIndex ).at( 0 ) == mPoints.at( geometryIndex ).at( 1 ) )
116  {
117  mPoints[geometryIndex].last() = p;
118  }
119  else
120  {
121  mPoints[geometryIndex] << p;
122  }
123 
124 
125  if ( doUpdate )
126  {
127  setVisible( true );
128  updateRect();
129  update();
130  }
131 }
132 
133 void QgsRubberBand::closePoints( bool doUpdate, int geometryIndex )
134 {
135  if ( geometryIndex < 0 || geometryIndex >= mPoints.size() )
136  {
137  return;
138  }
139 
140  if ( mPoints.at( geometryIndex ).at( 0 ) != mPoints.at( geometryIndex ).at( mPoints.at( geometryIndex ).size() - 1 ) )
141  {
142  mPoints[geometryIndex] << mPoints.at( geometryIndex ).at( 0 );
143  }
144 
145  if ( doUpdate )
146  {
147  setVisible( true );
148  updateRect();
149  update();
150  }
151 }
152 
153 
154 void QgsRubberBand::removePoint( int index, bool doUpdate/* = true*/, int geometryIndex/* = 0*/ )
155 {
156 
157  if ( mPoints.size() < geometryIndex + 1 )
158  {
159  return;
160  }
161 
162 
163  if ( !mPoints[geometryIndex].isEmpty() )
164  {
165  // negative index removes from end, e.g., -1 removes last one
166  if ( index < 0 )
167  {
168  index = mPoints.at( geometryIndex ).size() + index;
169  }
170  mPoints[geometryIndex].removeAt( index );
171  }
172 
173  if ( doUpdate )
174  {
175  updateRect();
176  update();
177  }
178 }
179 
180 void QgsRubberBand::removeLastPoint( int geometryIndex, bool doUpdate/* = true*/ )
181 {
182  removePoint( -1, doUpdate, geometryIndex );
183 }
184 
185 void QgsRubberBand::movePoint( const QgsPointXY &p, int geometryIndex )
186 {
187  if ( mPoints.size() < geometryIndex + 1 )
188  {
189  return;
190  }
191 
192  if ( mPoints.at( geometryIndex ).empty() )
193  {
194  return;
195  }
196 
197  mPoints[geometryIndex].last() = p;
198 
199  updateRect();
200  update();
201 }
202 
203 void QgsRubberBand::movePoint( int index, const QgsPointXY &p, int geometryIndex )
204 {
205  if ( mPoints.size() < geometryIndex + 1 )
206  {
207  return;
208  }
209 
210  if ( mPoints.at( geometryIndex ).size() < index )
211  {
212  return;
213  }
214 
215  mPoints[geometryIndex][index] = p;
216 
217  updateRect();
218  update();
219 }
220 
222 {
223  if ( geom.isNull() )
224  {
225  reset( mGeometryType );
226  return;
227  }
228 
229  reset( geom.type() );
230  addGeometry( geom, layer );
231 }
232 
234 {
235  QgsGeometry geom = geometry;
236  if ( layer )
237  {
239  geom.transform( ct );
240  }
241 
242  addGeometry( geom );
243 }
244 
246 {
247  if ( geometry.isEmpty() )
248  {
249  return;
250  }
251 
252  //maprender object of canvas
253  const QgsMapSettings &ms = mMapCanvas->mapSettings();
254 
255  int idx = mPoints.size();
256 
257  QgsGeometry geom = geometry;
258  if ( crs.isValid() )
259  {
260  QgsCoordinateTransform ct( crs, ms.destinationCrs() );
261  geom.transform( ct );
262  }
263 
264  switch ( QgsWkbTypes::flatType( geom.wkbType() ) )
265  {
266 
267  case QgsWkbTypes::Point:
269  {
270  QgsPointXY pt = geom.asPoint();
271  addPoint( pt, false, idx );
272  removeLastPoint( idx, false );
273  }
274  break;
275 
278  {
279  const QgsMultiPoint mpt = geom.asMultiPoint();
280  for ( QgsPointXY pt : mpt )
281  {
282  addPoint( pt, false, idx );
283  removeLastPoint( idx, false );
284  idx++;
285  }
286  }
287  break;
288 
291  {
292  const QgsPolyline line = geom.asPolyline();
293  for ( QgsPointXY pt : line )
294  {
295  addPoint( pt, false, idx );
296  }
297  }
298  break;
299 
302  {
303 
304  const QgsMultiPolyline mline = geom.asMultiPolyline();
305  for ( const QgsPolyline &line : mline )
306  {
307  if ( line.isEmpty() )
308  {
309  continue;
310  }
311 
312  for ( QgsPointXY pt : line )
313  {
314  addPoint( pt, false, idx );
315  }
316  idx++;
317  }
318  }
319  break;
320 
323  {
324  const QgsPolygon poly = geom.asPolygon();
325  const QgsPolyline line = poly.at( 0 );
326  for ( QgsPointXY pt : line )
327  {
328  addPoint( pt, false, idx );
329  }
330  }
331  break;
332 
335  {
336 
337  const QgsMultiPolygon multipoly = geom.asMultiPolygon();
338  for ( const QgsPolygon &poly : multipoly )
339  {
340  if ( poly.empty() )
341  continue;
342 
343  const QgsPolyline line = poly.at( 0 );
344  for ( QgsPointXY pt : line )
345  {
346  addPoint( pt, false, idx );
347  }
348  idx++;
349  }
350  }
351  break;
352 
354  default:
355  return;
356  }
357 
358  setVisible( true );
359  updateRect();
360  update();
361 }
362 
364 {
365  if ( !mMapCanvas )
366  {
367  return;
368  }
369 
370  const QgsMapToPixel *transform = mMapCanvas->getCoordinateTransform();
371  QgsPointXY ll = transform->toMapCoordinates( rect.left(), rect.bottom() );
372  QgsPointXY lr = transform->toMapCoordinates( rect.right(), rect.bottom() );
373  QgsPointXY ul = transform->toMapCoordinates( rect.left(), rect.top() );
374  QgsPointXY ur = transform->toMapCoordinates( rect.right(), rect.top() );
375 
377  addPoint( ll, false );
378  addPoint( lr, false );
379  addPoint( ur, false );
380  addPoint( ul, true );
381 }
382 
383 void QgsRubberBand::paint( QPainter *p )
384 {
385  if ( mPoints.isEmpty() )
386  return;
387 
388  QVector< QVector<QPointF> > shapes;
389  for ( const QList<QgsPointXY> &line : qgis::as_const( mPoints ) )
390  {
391  QVector<QPointF> pts;
392  for ( const QgsPointXY &pt : line )
393  {
394  const QPointF cur = toCanvasCoordinates( QgsPointXY( pt.x() + mTranslationOffsetX, pt.y() + mTranslationOffsetY ) ) - pos();
395  if ( pts.empty() || std::abs( pts.back().x() - cur.x() ) > 1 || std::abs( pts.back().y() - cur.y() ) > 1 )
396  pts.append( cur );
397  }
398  shapes << pts;
399  }
400 
401  int iterations = mSecondaryPen.color().isValid() ? 2 : 1;
402  for ( int i = 0; i < iterations; ++i )
403  {
404  if ( i == 0 && iterations > 1 )
405  {
406  // first iteration with multi-pen painting, so use secondary pen
407  mSecondaryPen.setWidth( mPen.width() + 2 );
408  p->setBrush( Qt::NoBrush );
409  p->setPen( mSecondaryPen );
410  }
411  else
412  {
413  // "top" layer, use primary pen/brush
414  p->setBrush( mBrush );
415  p->setPen( mPen );
416  }
417 
418  for ( const QVector<QPointF> &shape : qgis::as_const( shapes ) )
419  {
420  drawShape( p, shape );
421  }
422  }
423 }
424 
425 void QgsRubberBand::drawShape( QPainter *p, const QVector<QPointF> &pts )
426 {
427  switch ( mGeometryType )
428  {
430  {
431  p->drawPolygon( pts );
432  }
433  break;
434 
436  {
437  Q_FOREACH ( QPointF pt, pts )
438  {
439  double x = pt.x();
440  double y = pt.y();
441 
442  qreal s = ( mIconSize - 1 ) / 2.0;
443 
444  switch ( mIconType )
445  {
446  case ICON_NONE:
447  break;
448 
449  case ICON_CROSS:
450  p->drawLine( QLineF( x - s, y, x + s, y ) );
451  p->drawLine( QLineF( x, y - s, x, y + s ) );
452  break;
453 
454  case ICON_X:
455  p->drawLine( QLineF( x - s, y - s, x + s, y + s ) );
456  p->drawLine( QLineF( x - s, y + s, x + s, y - s ) );
457  break;
458 
459  case ICON_BOX:
460  p->drawLine( QLineF( x - s, y - s, x + s, y - s ) );
461  p->drawLine( QLineF( x + s, y - s, x + s, y + s ) );
462  p->drawLine( QLineF( x + s, y + s, x - s, y + s ) );
463  p->drawLine( QLineF( x - s, y + s, x - s, y - s ) );
464  break;
465 
466  case ICON_FULL_BOX:
467  p->drawRect( x - s, y - s, mIconSize, mIconSize );
468  break;
469 
470  case ICON_CIRCLE:
471  p->drawEllipse( x - s, y - s, mIconSize, mIconSize );
472  break;
473 
474  case ICON_DIAMOND:
475  case ICON_FULL_DIAMOND:
476  {
477  QPointF pts[] =
478  {
479  QPointF( x, y - s ),
480  QPointF( x + s, y ),
481  QPointF( x, y + s ),
482  QPointF( x - s, y )
483  };
484  if ( mIconType == ICON_FULL_DIAMOND )
485  p->drawPolygon( pts, 4 );
486  else
487  p->drawPolyline( pts, 4 );
488  }
489  }
490  }
491  }
492  break;
493 
495  default:
496  {
497  p->drawPolyline( pts );
498  }
499  break;
500  }
501 }
502 
504 {
505  if ( mPoints.empty() )
506  {
507  setRect( QgsRectangle() );
508  setVisible( false );
509  return;
510  }
511 
512  const QgsMapToPixel &m2p = *( mMapCanvas->getCoordinateTransform() );
513 
514  qreal w = ( ( mIconSize - 1 ) / 2 + mPen.width() ); // in canvas units
515 
516  QgsRectangle r; // in canvas units
517  for ( int i = 0; i < mPoints.size(); ++i )
518  {
519  QList<QgsPointXY>::const_iterator it = mPoints.at( i ).constBegin(),
520  itE = mPoints.at( i ).constEnd();
521  for ( ; it != itE; ++it )
522  {
523  QgsPointXY p( it->x() + mTranslationOffsetX, it->y() + mTranslationOffsetY );
524  p = m2p.transform( p );
525  QgsRectangle rect( p.x() - w, p.y() - w, p.x() + w, p.y() + w );
526 
527  if ( r.isEmpty() )
528  {
529  // Get rectangle of the first point
530  r = rect;
531  }
532  else
533  {
534  r.combineExtentWith( rect );
535  }
536  }
537  }
538 
539  // This is an hack to pass QgsMapCanvasItem::setRect what it
540  // expects (encoding of position and size of the item)
541  qreal res = m2p.mapUnitsPerPixel();
542  QgsPointXY topLeft = m2p.toMapPoint( r.xMinimum(), r.yMinimum() );
543  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + r.width()*res, topLeft.y() - r.height()*res );
544 
545  setRect( rect );
546 }
547 
549 {
550  // re-compute rectangle
551  // See https://issues.qgis.org/issues/12392
552  // NOTE: could be optimized by saving map-extent
553  // of rubberband and simply re-projecting
554  // that to device-rectangle on "updatePosition"
555  updateRect();
556 }
557 
558 void QgsRubberBand::setTranslationOffset( double dx, double dy )
559 {
560  mTranslationOffsetX = dx;
561  mTranslationOffsetY = dy;
562  updateRect();
563 }
564 
566 {
567  return mPoints.size();
568 }
569 
570 int QgsRubberBand::partSize( int geometryIndex ) const
571 {
572  if ( geometryIndex < 0 || geometryIndex >= mPoints.size() ) return 0;
573  return mPoints[geometryIndex].size();
574 }
575 
577 {
578  int count = 0;
579  QList<QList<QgsPointXY> >::const_iterator it = mPoints.constBegin();
580  for ( ; it != mPoints.constEnd(); ++it )
581  {
582  QList<QgsPointXY>::const_iterator iter = it->constBegin();
583  for ( ; iter != it->constEnd(); ++iter )
584  {
585  ++count;
586  }
587  }
588  return count;
589 }
590 
591 const QgsPointXY *QgsRubberBand::getPoint( int i, int j ) const
592 {
593  if ( i < mPoints.size() && j < mPoints[i].size() )
594  return &mPoints[i][j];
595  else
596  return nullptr;
597 }
598 
600 {
601  QgsGeometry geom;
602 
603  switch ( mGeometryType )
604  {
606  {
607  QgsPolygon polygon;
608  QList< QList<QgsPointXY> >::const_iterator it = mPoints.constBegin();
609  for ( ; it != mPoints.constEnd(); ++it )
610  {
611  polygon.append( getPolyline( *it ) );
612  }
613  geom = QgsGeometry::fromPolygon( polygon );
614  break;
615  }
616 
618  {
619  QgsMultiPoint multiPoint;
620 
621  QList< QList<QgsPointXY> >::const_iterator it = mPoints.constBegin();
622  for ( ; it != mPoints.constEnd(); ++it )
623  {
624  multiPoint += getPolyline( *it );
625  }
626  geom = QgsGeometry::fromMultiPoint( multiPoint );
627  break;
628  }
629 
631  default:
632  {
633  if ( !mPoints.isEmpty() )
634  {
635  if ( mPoints.size() > 1 )
636  {
637  QgsMultiPolyline multiPolyline;
638  QList< QList<QgsPointXY> >::const_iterator it = mPoints.constBegin();
639  for ( ; it != mPoints.constEnd(); ++it )
640  {
641  multiPolyline.append( getPolyline( *it ) );
642  }
643  geom = QgsGeometry::fromMultiPolyline( multiPolyline );
644  }
645  else
646  {
647  geom = QgsGeometry::fromPolyline( getPolyline( mPoints.at( 0 ) ) );
648  }
649  }
650  break;
651  }
652  }
653  return geom;
654 }
655 
656 QgsPolyline QgsRubberBand::getPolyline( const QList<QgsPointXY> &points )
657 {
658  QgsPolyline polyline;
659  QList<QgsPointXY>::const_iterator iter = points.constBegin();
660  for ( ; iter != points.constEnd(); ++iter )
661  {
662  polyline.append( *iter );
663  }
664  return polyline;
665 }
QgsPolygon asPolygon() const
Returns contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list...
A cross is used to highlight points (x)
Definition: qgsrubberband.h:58
void setIconSize(int iconSize)
Sets the size of the point icons.
void setWidth(int width)
Sets the width of the line.
QgsMultiPolyline asMultiPolyline() const
Returns contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
A rectangle specified with double values.
Definition: qgsrectangle.h:39
int numberOfVertices() const
Returns count of vertices in all lists of mPoint.
QgsRectangle rect() const
returns canvas item rectangle in map units
void setToCanvasRectangle(QRect rect)
Sets this rubber band to a map canvas rectangle.
static QgsGeometry fromPolyline(const QgsPolyline &polyline)
Creates a new geometry from a QgsPolyline object.
void setStrokeColor(const QColor &color)
Sets the stroke color for the rubberband.
IconType icon() const
Returns the current icon type to highlight point geometries.
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
void setTranslationOffset(double dx, double dy)
Adds translation to original coordinates (all in map coordinates)
void setLineStyle(Qt::PenStyle penStyle)
Sets the style of the line.
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
An abstract class for items that can be placed on the map canvas.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:94
void setSecondaryStrokeColor(const QColor &color)
Sets a secondary stroke color for the rubberband which will be drawn under the main stroke color...
A diamond is used to highlight points (◇)
Definition: qgsrubberband.h:79
virtual void updatePosition() override
called on changed extent or resize event to update position of the item
void addGeometry(const QgsGeometry &geometry, QgsVectorLayer *layer)
Adds the geometry of an existing feature to a rubberband This is useful for multi feature highlightin...
A cross is used to highlight points (+)
Definition: qgsrubberband.h:53
const QgsPointXY * getPoint(int i, int j=0) const
Returns a vertex.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:74
QgsPolyline asPolyline() const
Returns contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list...
QVector< QgsPointXY > QgsPolyline
Polyline is represented as a vector of points.
Definition: qgsgeometry.h:49
virtual void paint(QPainter *p) override
Paints the rubber band in response to an update event.
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
int width() const
Returns the current width of the line or stroke width for polygon.
The QgsMapSettings class contains configuration for rendering of the map.
void setToGeometry(const QgsGeometry &geom, QgsVectorLayer *layer)
Sets this rubber band to the geometry of an existing feature.
QgsRubberBand(QgsMapCanvas *mapCanvas, QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry)
Creates a new RubberBand.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Return coordinate transform from layer&#39;s CRS to destination CRS.
QgsMultiPoint asMultiPoint() const
Returns contents of the geometry as a multi point if wkbType is WKBMultiPoint, otherwise an empty lis...
void closePoints(bool doUpdate=true, int geometryIndex=0)
Ensures that a polygon geometry is closed and that the last vertex equals the first vertex...
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:36
QgsPointXY transform(const QgsPointXY &p) const
Transform the point from map (world) coordinates to device coordinates.
QgsGeometry asGeometry() const
Returns the rubberband as a Geometry.
bool isEmpty() const
Returns true if the rectangle is empty.
A circle is used to highlight points (○)
Definition: qgsrubberband.h:68
void removePoint(int index=0, bool doUpdate=true, int geometryIndex=0)
Removes a vertex from the rubberband and (optionally) updates canvas.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:131
void addPoint(const QgsPointXY &p, bool doUpdate=true, int geometryIndex=0)
Adds a vertex to the rubberband and update canvas.
void movePoint(const QgsPointXY &p, int geometryIndex=0)
Moves the rubber band point specified by index.
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
QVector< QgsPolygon > QgsMultiPolygon
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:73
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
void setFillColor(const QColor &color)
Sets the fill color for the rubberband.
QVector< QgsPolyline > QgsPolygon
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
Definition: qgsgeometry.h:56
double mapUnitsPerPixel() const
Return current map units per pixel.
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
double x
Definition: qgspointxy.h:47
static QgsGeometry fromPolygon(const QgsPolygon &polygon)
Creates a new geometry from a QgsPolygon.
QgsMapCanvasItem(QgsMapCanvas *mapCanvas)
protected constructor: cannot be constructed directly
void setBrushStyle(Qt::BrushStyle brushStyle)
Sets the style of the brush.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:119
QVector< QgsPolyline > QgsMultiPolyline
A collection of QgsPolylines that share a common collection of attributes.
Definition: qgsgeometry.h:66
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
void combineExtentWith(const QgsRectangle &rect)
Expand the rectangle so that covers both the original rectangle and the given rectangle.
void setIcon(IconType icon)
Sets the icon type to highlight point geometries.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:137
A box is used to highlight points (□)
Definition: qgsrubberband.h:63
QgsPointXY toMapPoint(double x, double y) const
OperationResult transform(const QgsCoordinateTransform &ct)
Transforms this geometry as described by CoordinateTransform ct.
QgsPointXY asPoint() const
Returns contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
static QgsGeometry fromMultiPoint(const QgsMultiPoint &multipoint)
Creates a new geometry from a QgsMultiPoint object.
int iconSize() const
Returns the current icon size of the point icons.
QgsMultiPolygon asMultiPolygon() const
Returns contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty list.
void drawShape(QPainter *p, const QVector< QPointF > &pts)
Draws shape of the rubber band.
int partSize(int geometryIndex) const
Returns number of vertices in feature part.
QgsMapCanvas * mMapCanvas
pointer to map canvas
QVector< QgsPointXY > QgsMultiPoint
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:62
This class represents a coordinate reference system (CRS).
A diamond is used to highlight points (◆)
Definition: qgsrubberband.h:85
Class for doing transforms between two map coordinate systems.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:109
const QgsMapToPixel * getCoordinateTransform()
Get the current coordinate transform.
void reset(QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry)
Clears all the geometries in this rubberband.
void setColor(const QColor &color)
Sets the color for the rubberband.
No icon is used.
Definition: qgsrubberband.h:48
int size() const
Returns number of geometries.
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
Represents a vector layer which manages a vector based data sets.
void removeLastPoint(int geometryIndex=0, bool doUpdate=true)
Removes the last point.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:427
QgsPointXY toMapCoordinates(int x, int y) const
void updateRect()
Recalculates needed rectangle.
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:138
A full box is used to highlight points (■)
Definition: qgsrubberband.h:73
static QgsGeometry fromMultiPolyline(const QgsMultiPolyline &multiline)
Creates a new geometry from a QgsMultiPolyline object.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.