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