QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 "qgsgeometry.h"
18 #include "qgslogger.h"
19 #include "qgsmapcanvas.h"
20 #include "qgsvectorlayer.h"
21 #include "qgsproject.h"
22 #include "qgsrectangle.h"
23 #include "qgssymbol.h"
24 #include "qgsrendercontext.h"
25 #include "qgslinesymbol.h"
26 #include "qgsfillsymbol.h"
27 #include "qgsguiutils.h"
28 
29 #include <QPainter>
30 
32  : QObject( nullptr )
33  , QgsMapCanvasItem( mapCanvas )
34  , mGeometryType( geometryType )
35 {
36  reset( geometryType );
37  QColor color( Qt::lightGray );
38  color.setAlpha( 63 );
39  setColor( color );
40  setWidth( 1 );
41  setLineStyle( Qt::SolidLine );
42  setBrushStyle( Qt::SolidPattern );
43  setSecondaryStrokeColor( QColor() );
44 }
45 
46 QgsRubberBand::QgsRubberBand()
47  : QObject( nullptr )
48  , QgsMapCanvasItem( nullptr )
49 {
50 }
51 
53 
54 void QgsRubberBand::setColor( const QColor &color )
55 {
56  setStrokeColor( color );
57  setFillColor( color );
58 }
59 
60 void QgsRubberBand::setFillColor( const QColor &color )
61 {
62  if ( mBrush.color() == color )
63  return;
64 
65  mBrush.setColor( color );
66 }
67 
68 void QgsRubberBand::setStrokeColor( const QColor &color )
69 {
70  mPen.setColor( color );
71 }
72 
73 void QgsRubberBand::setSecondaryStrokeColor( const QColor &color )
74 {
75  mSecondaryPen.setColor( color );
76 }
77 
78 void QgsRubberBand::setWidth( int width )
79 {
80  mPen.setWidth( width );
81 }
82 
84 {
85  mIconType = icon;
86 }
87 
88 void QgsRubberBand::setSvgIcon( const QString &path, QPoint drawOffset )
89 {
90  setIcon( ICON_SVG );
91  mSvgRenderer = std::make_unique<QSvgRenderer>( path );
92  mSvgOffset = drawOffset;
93 }
94 
96 {
97  mIconSize = iconSize;
98 }
99 
100 void QgsRubberBand::setLineStyle( Qt::PenStyle penStyle )
101 {
102  mPen.setStyle( penStyle );
103 }
104 
105 void QgsRubberBand::setBrushStyle( Qt::BrushStyle brushStyle )
106 {
107  mBrush.setStyle( brushStyle );
108 }
109 
111 {
112  mPoints.clear();
113  mGeometryType = geometryType;
114  updateRect();
115  update();
116 }
117 
118 void QgsRubberBand::addPoint( const QgsPointXY &p, bool doUpdate /* = true */, int geometryIndex, int ringIndex )
119 {
120  if ( geometryIndex < 0 )
121  {
122  geometryIndex = mPoints.size() - 1;
123  }
124 
125  if ( geometryIndex < 0 || geometryIndex > mPoints.size() )
126  {
127  return;
128  }
129 
130  if ( geometryIndex == mPoints.size() )
131  {
132  // since we're adding a geometry, ringIndex must be 0 or negative for last ring
133  if ( ringIndex > 0 )
134  return;
135  mPoints.append( QgsPolygonXY() );
136  }
137 
138  // negative ringIndex means last ring
139  if ( ringIndex < 0 )
140  {
141  if ( mPoints.at( geometryIndex ).isEmpty() )
142  ringIndex = 0;
143  else
144  ringIndex = mPoints.at( geometryIndex ).size() - 1;
145  }
146 
147  if ( ringIndex > mPoints.at( geometryIndex ).size() )
148  return;
149 
150  if ( ringIndex == mPoints.at( geometryIndex ).size() )
151  {
152  mPoints[geometryIndex].append( QgsPolylineXY() );
153  if ( mGeometryType != QgsWkbTypes::PointGeometry )
154  mPoints[geometryIndex][ringIndex].append( p );
155  }
156 
157  if ( mPoints.at( geometryIndex ).at( ringIndex ).size() == 2 &&
158  mPoints.at( geometryIndex ).at( ringIndex ).at( 0 ) == mPoints.at( geometryIndex ).at( ringIndex ).at( 1 ) )
159  {
160  mPoints[geometryIndex][ringIndex].last() = p;
161  }
162  else
163  {
164  mPoints[geometryIndex][ringIndex].append( p );
165  }
166 
167 
168  if ( doUpdate )
169  {
170  setVisible( true );
171  updateRect();
172  update();
173  }
174 }
175 
176 void QgsRubberBand::closePoints( bool doUpdate, int geometryIndex, int ringIndex )
177 {
178  if ( geometryIndex < 0 || ringIndex < 0 ||
179  mPoints.size() <= geometryIndex ||
180  mPoints.at( geometryIndex ).size() <= ringIndex ||
181  mPoints.at( geometryIndex ).at( ringIndex ).isEmpty() )
182  {
183  return;
184  }
185 
186  if ( mPoints.at( geometryIndex ).at( ringIndex ).constFirst() != mPoints.at( geometryIndex ).at( ringIndex ).constLast() )
187  {
188  mPoints[geometryIndex][ringIndex].append( mPoints.at( geometryIndex ).at( ringIndex ).constFirst() );
189  }
190 
191  if ( doUpdate )
192  {
193  setVisible( true );
194  updateRect();
195  update();
196  }
197 }
198 
199 
200 void QgsRubberBand::removePoint( int index, bool doUpdate/* = true*/, int geometryIndex/* = 0*/, int ringIndex/* = 0*/ )
201 {
202 
203  if ( geometryIndex < 0 || ringIndex < 0 ||
204  mPoints.size() <= geometryIndex ||
205  mPoints.at( geometryIndex ).size() <= ringIndex ||
206  mPoints.at( geometryIndex ).at( ringIndex ).size() <= index ||
207  mPoints.at( geometryIndex ).at( ringIndex ).size() < -index ||
208  mPoints.at( geometryIndex ).at( ringIndex ).isEmpty() )
209  {
210  return;
211  }
212 
213  // negative index removes from end, e.g., -1 removes last one
214  if ( index < 0 )
215  {
216  index = mPoints.at( geometryIndex ).at( ringIndex ).size() + index;
217  }
218  mPoints[geometryIndex][ringIndex].removeAt( index );
219 
220  if ( doUpdate )
221  {
222  updateRect();
223  update();
224  }
225 }
226 
227 void QgsRubberBand::removeLastPoint( int geometryIndex, bool doUpdate/* = true*/, int ringIndex/* = 0*/ )
228 {
229  removePoint( -1, doUpdate, geometryIndex, ringIndex );
230 }
231 
232 void QgsRubberBand::movePoint( const QgsPointXY &p, int geometryIndex, int ringIndex )
233 {
234  if ( geometryIndex < 0 || ringIndex < 0 ||
235  mPoints.size() <= geometryIndex ||
236  mPoints.at( geometryIndex ).size() <= ringIndex ||
237  mPoints.at( geometryIndex ).at( ringIndex ).isEmpty() )
238  {
239  return;
240  }
241 
242  mPoints[geometryIndex][ringIndex].last() = p;
243 
244  updateRect();
245  update();
246 }
247 
248 void QgsRubberBand::movePoint( int index, const QgsPointXY &p, int geometryIndex, int ringIndex )
249 {
250  if ( geometryIndex < 0 || ringIndex < 0 || index < 0 ||
251  mPoints.size() <= geometryIndex ||
252  mPoints.at( geometryIndex ).size() <= ringIndex ||
253  mPoints.at( geometryIndex ).at( ringIndex ).size() <= index )
254  {
255  return;
256  }
257 
258  mPoints[geometryIndex][ringIndex][index] = p;
259 
260  updateRect();
261  update();
262 }
263 
265 {
266  if ( geom.isNull() )
267  {
268  reset( mGeometryType );
269  return;
270  }
271 
272  reset( geom.type() );
273  addGeometry( geom, layer );
274 }
275 
277 {
278  if ( geom.isNull() )
279  {
280  reset( mGeometryType );
281  return;
282  }
283 
284  reset( geom.type() );
285  addGeometry( geom, crs );
286 }
287 
288 void QgsRubberBand::addGeometry( const QgsGeometry &geometry, QgsMapLayer *layer, bool doUpdate )
289 {
290  QgsGeometry geom = geometry;
291  if ( layer )
292  {
294  try
295  {
296  geom.transform( ct );
297  }
298  catch ( QgsCsException & )
299  {
300  return;
301  }
302  }
303 
304  addGeometry( geom, QgsCoordinateReferenceSystem(), doUpdate );
305 }
306 
307 void QgsRubberBand::addGeometry( const QgsGeometry &geometry, const QgsCoordinateReferenceSystem &crs, bool doUpdate )
308 {
309  if ( geometry.isEmpty() )
310  {
311  return;
312  }
313 
314  //maprender object of canvas
315  const QgsMapSettings &ms = mMapCanvas->mapSettings();
316 
317  int idx = mPoints.size();
318 
319  QgsGeometry geom = geometry;
320  if ( crs.isValid() )
321  {
323  try
324  {
325  geom.transform( ct );
326  }
327  catch ( QgsCsException & )
328  {
329  QgsDebugMsg( QStringLiteral( "Could not transform rubber band geometry to map CRS" ) );
330  return;
331  }
332  }
333 
334  QgsWkbTypes::Type geomType = geom.wkbType();
336  {
337  QgsPointXY pt = geom.asPoint();
338  addPoint( pt, false, idx );
339  }
340  else if ( QgsWkbTypes::geometryType( geomType ) == QgsWkbTypes::PointGeometry && QgsWkbTypes::isMultiType( geomType ) )
341  {
342  const QgsMultiPointXY mpt = geom.asMultiPoint();
343  for ( const QgsPointXY &pt : mpt )
344  {
345  addPoint( pt, false, idx );
346  idx++;
347  }
348  }
349  else if ( QgsWkbTypes::geometryType( geomType ) == QgsWkbTypes::LineGeometry && !QgsWkbTypes::isMultiType( geomType ) )
350  {
351  const QgsPolylineXY line = geom.asPolyline();
352  for ( const QgsPointXY &pt : line )
353  {
354  addPoint( pt, false, idx );
355  }
356  }
357  else if ( QgsWkbTypes::geometryType( geomType ) == QgsWkbTypes::LineGeometry && QgsWkbTypes::isMultiType( geomType ) )
358  {
359  const QgsMultiPolylineXY mline = geom.asMultiPolyline();
360  for ( const QgsPolylineXY &line : mline )
361  {
362  if ( line.isEmpty() )
363  {
364  continue;
365  }
366  for ( const QgsPointXY &pt : line )
367  {
368  addPoint( pt, false, idx );
369  }
370  idx++;
371  }
372  }
373  else if ( QgsWkbTypes::geometryType( geomType ) == QgsWkbTypes::PolygonGeometry && !QgsWkbTypes::isMultiType( geomType ) )
374  {
375  const QgsPolygonXY poly = geom.asPolygon();
376  int ringIdx = 0;
377  for ( const QgsPolylineXY &ring : poly )
378  {
379  for ( const QgsPointXY &pt : ring )
380  {
381  addPoint( pt, false, idx, ringIdx );
382  }
383  ringIdx++;
384  }
385  }
387  {
388  const QgsMultiPolygonXY multipoly = geom.asMultiPolygon();
389  for ( const QgsPolygonXY &poly : multipoly )
390  {
391  if ( poly.isEmpty() )
392  continue;
393 
394  int ringIdx = 0;
395  for ( const QgsPolylineXY &ring : poly )
396  {
397  for ( const QgsPointXY &pt : ring )
398  {
399  addPoint( pt, false, idx, ringIdx );
400  }
401  ringIdx++;
402  }
403  idx++;
404  }
405  }
406  else
407  {
408  return;
409  }
410 
411  setVisible( true );
412  if ( doUpdate )
413  {
414  updateRect();
415  update();
416  }
417 }
418 
420 {
421  if ( !mMapCanvas )
422  {
423  return;
424  }
425 
426  const QgsMapToPixel *transform = mMapCanvas->getCoordinateTransform();
427  QgsPointXY ll = transform->toMapCoordinates( rect.left(), rect.bottom() );
428  QgsPointXY lr = transform->toMapCoordinates( rect.right(), rect.bottom() );
429  QgsPointXY ul = transform->toMapCoordinates( rect.left(), rect.top() );
430  QgsPointXY ur = transform->toMapCoordinates( rect.right(), rect.top() );
431 
433  addPoint( ll, false );
434  addPoint( lr, false );
435  addPoint( ur, false );
436  addPoint( ul, true );
437 }
438 
440 {
441  reset( other->mGeometryType );
442  mPoints = other->mPoints;
443  updateRect();
444  update();
445 }
446 
447 void QgsRubberBand::paint( QPainter *p )
448 {
449  if ( mPoints.isEmpty() )
450  return;
451 
452  QVector< QVector<QPolygonF> > shapes;
453  shapes.reserve( mPoints.size() );
454  for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
455  {
456  QVector<QPolygonF> rings;
457  rings.reserve( poly.size() );
458  for ( const QgsPolylineXY &line : poly )
459  {
460  QVector<QPointF> pts;
461  pts.reserve( line.size() );
462  for ( const QgsPointXY &pt : line )
463  {
464  const QPointF cur = toCanvasCoordinates( QgsPointXY( pt.x() + mTranslationOffsetX, pt.y() + mTranslationOffsetY ) ) - pos();
465  if ( pts.isEmpty() || std::abs( pts.last().x() - cur.x() ) > 1 || std::abs( pts.last().y() - cur.y() ) > 1 )
466  pts.append( cur );
467  }
468  rings.append( pts );
469  }
470  shapes.append( rings );
471  }
472 
473  if ( QgsLineSymbol *lineSymbol = dynamic_cast< QgsLineSymbol * >( mSymbol.get() ) )
474  {
477 
478  lineSymbol->startRender( context );
479  for ( const QVector<QPolygonF> &shape : std::as_const( shapes ) )
480  {
481  for ( const QPolygonF &ring : shape )
482  {
483  lineSymbol->renderPolyline( ring, nullptr, context );
484  }
485  }
486  lineSymbol->stopRender( context );
487  }
488  else if ( QgsFillSymbol *fillSymbol = dynamic_cast< QgsFillSymbol * >( mSymbol.get() ) )
489  {
492 
493  fillSymbol->startRender( context );
494  for ( const QVector<QPolygonF> &shape : std::as_const( shapes ) )
495  {
496  for ( const QPolygonF &ring : shape )
497  {
498  fillSymbol->renderPolygon( ring, nullptr, nullptr, context );
499  }
500  }
501  fillSymbol->stopRender( context );
502  }
503  else
504  {
505  int iterations = mSecondaryPen.color().isValid() ? 2 : 1;
506  for ( int i = 0; i < iterations; ++i )
507  {
508  if ( i == 0 && iterations > 1 )
509  {
510  // first iteration with multi-pen painting, so use secondary pen
511  mSecondaryPen.setWidth( mPen.width() + QgsGuiUtils::scaleIconSize( 2 ) );
512  p->setBrush( Qt::NoBrush );
513  p->setPen( mSecondaryPen );
514  }
515  else
516  {
517  // "top" layer, use primary pen/brush
518  p->setBrush( mBrush );
519  p->setPen( mPen );
520  }
521 
522  for ( const QVector<QPolygonF> &shape : std::as_const( shapes ) )
523  {
524  drawShape( p, shape );
525  }
526  }
527  }
528 }
529 
530 void QgsRubberBand::drawShape( QPainter *p, const QVector<QPolygonF> &rings )
531 {
532  if ( rings.size() == 1 )
533  {
534  drawShape( p, rings.at( 0 ) );
535  }
536  else
537  {
538  QPainterPath path;
539  for ( const QPolygonF &poly : rings )
540  {
541  path.addPolygon( poly );
542  }
543  p->drawPath( path );
544  }
545 }
546 
547 void QgsRubberBand::drawShape( QPainter *p, const QVector<QPointF> &pts )
548 {
549  switch ( mGeometryType )
550  {
552  {
553  p->drawPolygon( pts );
554  }
555  break;
556 
558  {
559  const auto constPts = pts;
560  for ( QPointF pt : constPts )
561  {
562  double x = pt.x();
563  double y = pt.y();
564 
565  qreal s = ( mIconSize - 1 ) / 2.0;
566 
567  switch ( mIconType )
568  {
569  case ICON_NONE:
570  break;
571 
572  case ICON_CROSS:
573  p->drawLine( QLineF( x - s, y, x + s, y ) );
574  p->drawLine( QLineF( x, y - s, x, y + s ) );
575  break;
576 
577  case ICON_X:
578  p->drawLine( QLineF( x - s, y - s, x + s, y + s ) );
579  p->drawLine( QLineF( x - s, y + s, x + s, y - s ) );
580  break;
581 
582  case ICON_BOX:
583  p->drawLine( QLineF( x - s, y - s, x + s, y - s ) );
584  p->drawLine( QLineF( x + s, y - s, x + s, y + s ) );
585  p->drawLine( QLineF( x + s, y + s, x - s, y + s ) );
586  p->drawLine( QLineF( x - s, y + s, x - s, y - s ) );
587  break;
588 
589  case ICON_FULL_BOX:
590  p->drawRect( static_cast< int>( x - s ), static_cast< int >( y - s ), mIconSize, mIconSize );
591  break;
592 
593  case ICON_CIRCLE:
594  p->drawEllipse( static_cast< int >( x - s ), static_cast< int >( y - s ), mIconSize, mIconSize );
595  break;
596 
597  case ICON_DIAMOND:
598  case ICON_FULL_DIAMOND:
599  {
600  QPointF pts[] =
601  {
602  QPointF( x, y - s ),
603  QPointF( x + s, y ),
604  QPointF( x, y + s ),
605  QPointF( x - s, y )
606  };
607  if ( mIconType == ICON_FULL_DIAMOND )
608  p->drawPolygon( pts, 4 );
609  else
610  p->drawPolyline( pts, 4 );
611  break;
612  }
613 
614  case ICON_SVG:
615  {
616  QRectF viewBox = mSvgRenderer->viewBoxF();
617  QRectF r( mSvgOffset.x(), mSvgOffset.y(), viewBox.width(), viewBox.height() );
618  QgsScopedQPainterState painterState( p );
619  p->translate( pt );
620  mSvgRenderer->render( p, r );
621  break;
622  }
623  }
624  }
625  }
626  break;
627 
629  default:
630  {
631  p->drawPolyline( pts );
632  }
633  break;
634  }
635 }
636 
638 {
639  if ( mPoints.isEmpty() )
640  {
641  setRect( QgsRectangle() );
642  setVisible( false );
643  return;
644  }
645 
646  const QgsMapToPixel &m2p = *( mMapCanvas->getCoordinateTransform() );
647 
648 #if 0 // unused?
649  double iconSize = ( mIconSize + 1 ) / 2.;
650  if ( mSvgRenderer )
651  {
652  QRectF viewBox = mSvgRenderer->viewBoxF();
653  iconSize = std::max( std::fabs( mSvgOffset.x() ) + .5 * viewBox.width(), std::fabs( mSvgOffset.y() ) + .5 * viewBox.height() );
654  }
655 #endif
656 
657  qreal w = ( ( mIconSize - 1 ) / 2 + mPen.width() ); // in canvas units
658 
659  QgsRectangle r; // in canvas units
660  for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
661  {
662  for ( const QgsPointXY &point : poly.at( 0 ) )
663  {
664  QgsPointXY p( point.x() + mTranslationOffsetX, point.y() + mTranslationOffsetY );
665  p = m2p.transform( p );
666  // no need to normalize the rectangle -- we know it is already normal
667  QgsRectangle rect( p.x() - w, p.y() - w, p.x() + w, p.y() + w, false );
668  r.combineExtentWith( rect );
669  }
670  }
671 
672  // This is an hack to pass QgsMapCanvasItem::setRect what it
673  // expects (encoding of position and size of the item)
674  qreal res = m2p.mapUnitsPerPixel();
675  QgsPointXY topLeft = m2p.toMapCoordinates( r.xMinimum(), r.yMinimum() );
676  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + r.width()*res, topLeft.y() - r.height()*res );
677 
678  setRect( rect );
679 }
680 
682 {
683  return mSymbol.get();
684 }
685 
687 {
688  mSymbol.reset( symbol );
689 }
690 
692 {
693  // re-compute rectangle
694  // See https://github.com/qgis/QGIS/issues/20566
695  // NOTE: could be optimized by saving map-extent
696  // of rubberband and simply re-projecting
697  // that to device-rectangle on "updatePosition"
698  updateRect();
699 }
700 
701 void QgsRubberBand::setTranslationOffset( double dx, double dy )
702 {
703  mTranslationOffsetX = dx;
704  mTranslationOffsetY = dy;
705  updateRect();
706 }
707 
709 {
710  return mPoints.size();
711 }
712 
713 int QgsRubberBand::partSize( int geometryIndex ) const
714 {
715  if ( geometryIndex < 0 ||
716  geometryIndex >= mPoints.size() ||
717  mPoints.at( geometryIndex ).isEmpty() )
718  return 0;
719  return mPoints.at( geometryIndex ).at( 0 ).size();
720 }
721 
723 {
724  int count = 0;
725  for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
726  {
727  for ( const QgsPolylineXY &ring : poly )
728  {
729  count += ring.size();
730  }
731  }
732  return count;
733 }
734 
735 const QgsPointXY *QgsRubberBand::getPoint( int i, int j, int ringIndex ) const
736 {
737  if ( i < 0 || ringIndex < 0 || j < 0 ||
738  mPoints.size() <= i ||
739  mPoints.at( i ).size() <= ringIndex ||
740  mPoints.at( i ).at( ringIndex ).size() <= j )
741  return nullptr;
742  else
743  return &mPoints[i][ringIndex][j];
744 }
745 
747 {
748  QgsGeometry geom;
749 
750  switch ( mGeometryType )
751  {
753  {
754  geom = QgsGeometry::fromMultiPolygonXY( mPoints );
755  break;
756  }
757 
759  {
760  QgsMultiPointXY multiPoint;
761 
762  for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
763  {
764  if ( poly.isEmpty() )
765  continue;
766  multiPoint.append( poly.at( 0 ) );
767  }
768  geom = QgsGeometry::fromMultiPointXY( multiPoint );
769  break;
770  }
771 
773  default:
774  {
775  if ( !mPoints.isEmpty() )
776  {
777  if ( mPoints.size() > 1 )
778  {
779  QgsMultiPolylineXY multiPolyline;
780  for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
781  {
782  if ( poly.isEmpty() )
783  continue;
784  multiPolyline.append( poly.at( 0 ) );
785  }
786  geom = QgsGeometry::fromMultiPolylineXY( multiPolyline );
787  }
788  else
789  {
790  if ( !mPoints.at( 0 ).isEmpty() )
791  geom = QgsGeometry::fromPolylineXY( mPoints.at( 0 ).at( 0 ) );
792  else
794  }
795  }
796  break;
797  }
798  }
799  return geom;
800 }
QgsRubberBand::symbol
QgsSymbol * symbol() const
Returns the symbol used for rendering the rubberband, if set.
Definition: qgsrubberband.cpp:681
QgsRubberBand::size
int size() const
Returns number of geometries.
Definition: qgsrubberband.cpp:708
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsPointXY::y
double y
Definition: qgspointxy.h:63
QgsRubberBand::removePoint
void removePoint(int index=0, bool doUpdate=true, int geometryIndex=0, int ringIndex=0)
Removes a vertex from the rubberband and (optionally) updates canvas.
Definition: qgsrubberband.cpp:200
QgsRubberBand::setSvgIcon
void setSvgIcon(const QString &path, QPoint drawOffset)
Set the path to the svg file to use to draw points.
Definition: qgsrubberband.cpp:88
QgsMapToPixel::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Definition: qgsmaptopixel.h:229
QgsRubberBand::ICON_CIRCLE
@ ICON_CIRCLE
A circle is used to highlight points (○)
Definition: qgsrubberband.h:108
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
QgsMapSettings::layerTransform
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
Definition: qgsmapsettings.cpp:481
qgsrectangle.h
QgsPolygonXY
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition: qgsgeometry.h:76
qgsmapcanvas.h
QgsGeometry::fromPolylineXY
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
Definition: qgsgeometry.cpp:186
QgsMapCanvasItem::mMapCanvas
QgsMapCanvas * mMapCanvas
pointer to map canvas
Definition: qgsmapcanvasitem.h:82
QgsRubberBand::updatePosition
void updatePosition() override
called on changed extent or resize event to update position of the item
Definition: qgsrubberband.cpp:691
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
QgsGeometry::fromMultiPolylineXY
static QgsGeometry fromMultiPolylineXY(const QgsMultiPolylineXY &multiline)
Creates a new geometry from a QgsMultiPolylineXY object.
Definition: qgsgeometry.cpp:221
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:437
QgsRubberBand::removeLastPoint
void removeLastPoint(int geometryIndex=0, bool doUpdate=true, int ringIndex=0)
Removes the last point.
Definition: qgsrubberband.cpp:227
QgsRubberBand
A class for drawing transient features (e.g. digitizing lines) on the map.
Definition: qgsrubberband.h:51
QgsRubberBand::setIconSize
void setIconSize(int iconSize)
Sets the size of the point icons.
Definition: qgsrubberband.cpp:95
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsPolylineXY
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:52
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
QgsRubberBand::getPoint
const QgsPointXY * getPoint(int i, int j=0, int ringIndex=0) const
Returns a vertex.
Definition: qgsrubberband.cpp:735
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsRubberBand::setStrokeColor
void setStrokeColor(const QColor &color)
Sets the stroke color for the rubberband.
Definition: qgsrubberband.cpp:68
QgsMultiPolygonXY
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:93
QgsRubberBand::setFillColor
void setFillColor(const QColor &color)
Sets the fill color for the rubberband.
Definition: qgsrubberband.cpp:60
QgsRubberBand::ICON_BOX
@ ICON_BOX
A box is used to highlight points (□)
Definition: qgsrubberband.h:103
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:92
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsRubberBand::width
int width
Definition: qgsrubberband.h:79
QgsMapToPixel::toMapCoordinates
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
Definition: qgsmaptopixel.h:173
QgsRubberBand::IconType
IconType
Icons.
Definition: qgsrubberband.h:82
QgsRubberBand::movePoint
void movePoint(const QgsPointXY &p, int geometryIndex=0, int ringIndex=0)
Moves the rubber band point specified by index.
Definition: qgsrubberband.cpp:232
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsGeometry::asMultiPolyline
QgsMultiPolylineXY asMultiPolyline() const
Returns the contents of the geometry as a multi-linestring.
Definition: qgsgeometry.cpp:1783
QgsRubberBand::ICON_NONE
@ ICON_NONE
No icon is used.
Definition: qgsrubberband.h:88
QgsMultiPointXY
QVector< QgsPointXY > QgsMultiPointXY
A collection of QgsPoints that share a common collection of attributes.
Definition: qgsgeometry.h:82
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsRubberBand::reset
void reset(QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry)
Clears all the geometries in this rubberband.
Definition: qgsrubberband.cpp:110
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:264
qgsrubberband.h
QgsMapCanvasItem::setRect
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
Definition: qgsmapcanvasitem.cpp:74
QgsRubberBand::ICON_FULL_DIAMOND
@ ICON_FULL_DIAMOND
A diamond is used to highlight points (◆)
Definition: qgsrubberband.h:125
QgsGeometry::asPolygon
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.
Definition: qgsgeometry.cpp:1724
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsMapCanvasItem
An abstract class for items that can be placed on the map canvas.
Definition: qgsmapcanvasitem.h:33
QgsRubberBand::addGeometry
void addGeometry(const QgsGeometry &geometry, QgsMapLayer *layer, bool doUpdate=true)
Adds the geometry of an existing feature to a rubberband This is useful for multi feature highlightin...
Definition: qgsrubberband.cpp:288
QgsMapCanvasItem::toCanvasCoordinates
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
Definition: qgsmapcanvasitem.cpp:61
QgsGeometry::fromMultiPointXY
static QgsGeometry fromMultiPointXY(const QgsMultiPointXY &multipoint)
Creates a new geometry from a QgsMultiPointXY object.
Definition: qgsgeometry.cpp:211
QgsRubberBand::~QgsRubberBand
~QgsRubberBand() override
QgsRubberBand::setTranslationOffset
void setTranslationOffset(double dx, double dy)
Adds translation to original coordinates (all in map coordinates)
Definition: qgsrubberband.cpp:701
QgsRubberBand::updateRect
void updateRect()
Recalculates needed rectangle.
Definition: qgsrubberband.cpp:637
QgsRenderContext::setFlag
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Definition: qgsrendercontext.cpp:216
qgsrendercontext.h
QgsRubberBand::setColor
void setColor(const QColor &color)
Sets the color for the rubberband.
Definition: qgsrubberband.cpp:54
QgsLineSymbol
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgslinesymbol.h:29
QgsRubberBand::setSymbol
void setSymbol(QgsSymbol *symbol)
Sets the symbol used for rendering the rubberband.
Definition: qgsrubberband.cpp:686
QgsCoordinateReferenceSystem::isValid
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Definition: qgscoordinatereferencesystem.cpp:977
QgsMultiPolylineXY
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
Definition: qgsgeometry.h:86
QgsRubberBand::numberOfVertices
int numberOfVertices() const
Returns count of vertices in all lists of mPoint.
Definition: qgsrubberband.cpp:722
QgsGeometry::isEmpty
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Definition: qgsgeometry.cpp:379
QgsRubberBand::ICON_X
@ ICON_X
A cross is used to highlight points (x)
Definition: qgsrubberband.h:98
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsRubberBand::addPoint
void addPoint(const QgsPointXY &p, bool doUpdate=true, int geometryIndex=0, int ringIndex=0)
Adds a vertex to the rubberband and update canvas.
Definition: qgsrubberband.cpp:118
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
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsMapToPixel::transform
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
Definition: qgsmaptopixel.h:90
QgsRubberBand::drawShape
void drawShape(QPainter *p, const QVector< QPointF > &pts)
Draws shape of the rubber band.
Definition: qgsrubberband.cpp:547
QgsRubberBand::ICON_FULL_BOX
@ ICON_FULL_BOX
A full box is used to highlight points (■)
Definition: qgsrubberband.h:113
QgsRubberBand::paint
void paint(QPainter *p) override
Paints the rubber band in response to an update event.
Definition: qgsrubberband.cpp:447
QgsRubberBand::setLineStyle
void setLineStyle(Qt::PenStyle penStyle)
Sets the style of the line.
Definition: qgsrubberband.cpp:100
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Definition: qgsmapsettings.cpp:358
QgsRubberBand::QgsRubberBand
QgsRubberBand(QgsMapCanvas *mapCanvas, QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::LineGeometry)
Creates a new RubberBand.
Definition: qgsrubberband.cpp:31
QgsGeometry::asPoint
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
Definition: qgsgeometry.cpp:1662
Qgis::RenderContextFlag::Antialiasing
@ Antialiasing
Use antialiasing while drawing.
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsRubberBand::setWidth
void setWidth(int width)
Sets the width of the line.
Definition: qgsrubberband.cpp:78
qgsgeometry.h
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
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsMapToPixel
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:38
QgsRubberBand::ICON_CROSS
@ ICON_CROSS
A cross is used to highlight points (+)
Definition: qgsrubberband.h:93
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsRenderContext::fromQPainter
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
Definition: qgsrendercontext.cpp:143
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsRubberBand::setToCanvasRectangle
void setToCanvasRectangle(QRect rect)
Sets this rubber band to a map canvas rectangle.
Definition: qgsrubberband.cpp:419
QgsFillSymbol
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:29
QgsRubberBand::icon
IconType icon() const
Returns the current icon type to highlight point geometries.
Definition: qgsrubberband.h:219
QgsRubberBand::setIcon
void setIcon(IconType icon)
Sets the icon type to highlight point geometries.
Definition: qgsrubberband.cpp:83
QgsGeometry::asPolyline
QgsPolylineXY asPolyline() const
Returns the contents of the geometry as a polyline.
Definition: qgsgeometry.cpp:1678
QgsWkbTypes::geometryType
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:968
QgsGeometry::asMultiPoint
QgsMultiPointXY asMultiPoint() const
Returns the contents of the geometry as a multi-point.
Definition: qgsgeometry.cpp:1759
QgsRubberBand::setToGeometry
void setToGeometry(const QgsGeometry &geom, QgsVectorLayer *layer)
Sets this rubber band to geom.
Definition: qgsrubberband.cpp:264
qgslogger.h
QgsRubberBand::ICON_SVG
@ ICON_SVG
An svg image is used to highlight points.
Definition: qgsrubberband.h:131
qgsguiutils.h
QgsRubberBand::partSize
int partSize(int geometryIndex) const
Returns number of vertices in feature part.
Definition: qgsrubberband.cpp:713
QgsGuiUtils::scaleIconSize
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Definition: qgsguiutils.cpp:259
QgsRubberBand::ICON_DIAMOND
@ ICON_DIAMOND
A diamond is used to highlight points (◇)
Definition: qgsrubberband.h:119
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
QgsWkbTypes::isMultiType
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
Definition: qgswkbtypes.h:862
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsGeometry::type
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsRubberBand::setSecondaryStrokeColor
void setSecondaryStrokeColor(const QColor &color)
Sets a secondary stroke color for the rubberband which will be drawn under the main stroke color.
Definition: qgsrubberband.cpp:73
QgsRubberBand::copyPointsFrom
void copyPointsFrom(const QgsRubberBand *other)
Copies the points from another rubber band.
Definition: qgsrubberband.cpp:439
qgsfillsymbol.h
QgsRubberBand::setBrushStyle
void setBrushStyle(Qt::BrushStyle brushStyle)
Sets the style of the brush.
Definition: qgsrubberband.cpp:105
qgssymbol.h
QgsRubberBand::asGeometry
QgsGeometry asGeometry() const
Returns the rubberband as a Geometry.
Definition: qgsrubberband.cpp:746
qgsproject.h
QgsRubberBand::closePoints
void closePoints(bool doUpdate=true, int geometryIndex=0, int ringIndex=0)
Ensures that a polygon geometry is closed and that the last vertex equals the first vertex.
Definition: qgsrubberband.cpp:176
QgsRubberBand::iconSize
int iconSize
Definition: qgsrubberband.h:77
QgsGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Definition: qgsgeometry.cpp:357
QgsGeometry::fromMultiPolygonXY
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
Definition: qgsgeometry.cpp:231
QgsGeometry::asMultiPolygon
QgsMultiPolygonXY asMultiPolygon() const
Returns the contents of the geometry as a multi-polygon.
Definition: qgsgeometry.cpp:1836
qgslinesymbol.h