QGIS API Documentation 4.3.0-Master (6402a64e93b)
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 "qgsproject.h"
25#include "qgsrectangle.h"
26#include "qgsrendercontext.h"
27#include "qgssymbol.h"
28#include "qgsvectorlayer.h"
29
30#include <QPainter>
31#include <QString>
32
33#include "moc_qgsrubberband.cpp"
34
35using namespace Qt::StringLiterals;
36
38 : QObject( nullptr )
39 , QgsMapCanvasItem( mapCanvas )
40 , mGeometryType( geometryType )
41{
42 reset( geometryType );
43 QColor color( Qt::lightGray );
44 color.setAlpha( 63 );
45 setColor( color );
46 setWidth( 1 );
47 setLineStyle( Qt::SolidLine );
48 setBrushStyle( Qt::SolidPattern );
49 setSecondaryStrokeColor( QColor() );
50}
51
53 : QObject( nullptr )
54 , QgsMapCanvasItem( nullptr )
55{}
56
58
59void QgsRubberBand::setColor( const QColor &color )
60{
61 setStrokeColor( color );
62 setFillColor( color );
63}
64
65void QgsRubberBand::setFillColor( const QColor &color )
66{
67 if ( mBrush.color() == color )
68 return;
69
70 mBrush.setColor( color );
71}
72
73void QgsRubberBand::setStrokeColor( const QColor &color )
74{
75 mPen.setColor( color );
76}
77
78void QgsRubberBand::setSecondaryStrokeColor( const QColor &color )
79{
80 mSecondaryPen.setColor( color );
81}
82
84{
85 mPen.setWidthF( width );
86}
87
92
93void QgsRubberBand::setSvgIcon( const QString &path, QPoint drawOffset )
94{
96 mSvgRenderer = std::make_unique<QSvgRenderer>( path );
97 mSvgOffset = drawOffset;
98}
99
101{
102 mIconSize = iconSize;
103}
104
105void QgsRubberBand::setLineStyle( Qt::PenStyle penStyle )
106{
107 mPen.setStyle( penStyle );
108}
109
110void QgsRubberBand::setBrushStyle( Qt::BrushStyle brushStyle )
111{
112 mBrush.setStyle( brushStyle );
113}
114
116{
117 mPoints.clear();
118 mGeometryType = geometryType;
119 updateRect();
120 update();
121}
122
124{
125 if ( item )
126 {
127 mPreviewItems.push_back( std::unique_ptr< QgsRubberBandPreviewItem>( item ) );
128 update();
129 }
130}
131
133{
134 mPreviewItems.clear();
135 update();
136}
137
138void QgsRubberBand::addPoint( const QgsPointXY &p, bool doUpdate /* = true */, int geometryIndex, int ringIndex )
139{
140 if ( geometryIndex < 0 )
141 {
142 geometryIndex = mPoints.size() - 1;
143 }
144
145 if ( geometryIndex < 0 || geometryIndex > mPoints.size() )
146 {
147 return;
148 }
149
150 if ( geometryIndex == mPoints.size() )
151 {
152 // since we're adding a geometry, ringIndex must be 0 or negative for last ring
153 if ( ringIndex > 0 )
154 return;
155 mPoints.append( QgsPolygonXY() );
156 }
157
158 // negative ringIndex means last ring
159 if ( ringIndex < 0 )
160 {
161 if ( mPoints.at( geometryIndex ).isEmpty() )
162 ringIndex = 0;
163 else
164 ringIndex = mPoints.at( geometryIndex ).size() - 1;
165 }
166
167 if ( ringIndex > mPoints.at( geometryIndex ).size() )
168 return;
169
170 if ( ringIndex == mPoints.at( geometryIndex ).size() )
171 {
172 mPoints[geometryIndex].append( QgsPolylineXY() );
173 if ( mGeometryType != Qgis::GeometryType::Point )
174 mPoints[geometryIndex][ringIndex].append( p );
175 }
176
177 if ( mPoints.at( geometryIndex ).at( ringIndex ).size() == 2 && mPoints.at( geometryIndex ).at( ringIndex ).at( 0 ) == mPoints.at( geometryIndex ).at( ringIndex ).at( 1 ) )
178 {
179 mPoints[geometryIndex][ringIndex].last() = p;
180 }
181 else
182 {
183 mPoints[geometryIndex][ringIndex].append( p );
184 }
185
186
187 if ( doUpdate )
188 {
189 setVisible( true );
190 updateRect();
191 update();
192 }
193}
194
195void QgsRubberBand::closePoints( bool doUpdate, int geometryIndex, int ringIndex )
196{
197 if ( geometryIndex < 0 || ringIndex < 0 || mPoints.size() <= geometryIndex || mPoints.at( geometryIndex ).size() <= ringIndex || mPoints.at( geometryIndex ).at( ringIndex ).isEmpty() )
198 {
199 return;
200 }
201
202 if ( mPoints.at( geometryIndex ).at( ringIndex ).constFirst() != mPoints.at( geometryIndex ).at( ringIndex ).constLast() )
203 {
204 mPoints[geometryIndex][ringIndex].append( mPoints.at( geometryIndex ).at( ringIndex ).constFirst() );
205 }
206
207 if ( doUpdate )
208 {
209 setVisible( true );
210 updateRect();
211 update();
212 }
213}
214
215
216void QgsRubberBand::removePoint( int index, bool doUpdate /* = true*/, int geometryIndex /* = 0*/, int ringIndex /* = 0*/ )
217{
218 if ( geometryIndex < 0
219 || ringIndex < 0
220 || mPoints.size() <= geometryIndex
221 || mPoints.at( geometryIndex ).size() <= ringIndex
222 || mPoints.at( geometryIndex ).at( ringIndex ).size() <= index
223 || mPoints.at( geometryIndex ).at( ringIndex ).size() < -index
224 || mPoints.at( geometryIndex ).at( ringIndex ).isEmpty() )
225 {
226 return;
227 }
228
229 // negative index removes from end, e.g., -1 removes last one
230 if ( index < 0 )
231 {
232 index = mPoints.at( geometryIndex ).at( ringIndex ).size() + index;
233 }
234 mPoints[geometryIndex][ringIndex].removeAt( index );
235
236 if ( doUpdate )
237 {
238 updateRect();
239 update();
240 }
241}
242
243void QgsRubberBand::removeLastPoint( int geometryIndex, bool doUpdate /* = true*/, int ringIndex /* = 0*/ )
244{
245 removePoint( -1, doUpdate, geometryIndex, ringIndex );
246}
247
248void QgsRubberBand::movePoint( const QgsPointXY &p, int geometryIndex, int ringIndex )
249{
250 if ( geometryIndex < 0 || ringIndex < 0 || mPoints.size() <= geometryIndex || mPoints.at( geometryIndex ).size() <= ringIndex || mPoints.at( geometryIndex ).at( ringIndex ).isEmpty() )
251 {
252 return;
253 }
254
255 mPoints[geometryIndex][ringIndex].last() = p;
256
257 updateRect();
258 update();
259}
260
261void QgsRubberBand::movePoint( int index, const QgsPointXY &p, int geometryIndex, int ringIndex )
262{
263 if ( geometryIndex < 0 || ringIndex < 0 || index < 0 || mPoints.size() <= geometryIndex || mPoints.at( geometryIndex ).size() <= ringIndex || mPoints.at( geometryIndex ).at( ringIndex ).size() <= index )
264 {
265 return;
266 }
267
268 mPoints[geometryIndex][ringIndex][index] = p;
269
270 updateRect();
271 update();
272}
273
275{
276 if ( geom.isNull() )
277 {
278 reset( mGeometryType );
279 return;
280 }
281
282 reset( geom.type() );
283 addGeometry( geom, layer );
284}
285
287{
288 if ( geom.isNull() )
289 {
290 reset( mGeometryType );
291 return;
292 }
293
294 reset( geom.type() );
295 addGeometry( geom, crs );
296}
297
298void QgsRubberBand::addGeometry( const QgsGeometry &geometry, QgsMapLayer *layer, bool doUpdate )
299{
300 QgsGeometry geom = geometry;
301 if ( layer )
302 {
303 QgsCoordinateTransform ct = mMapCanvas->mapSettings().layerTransform( layer );
304 try
305 {
306 geom.transform( ct );
307 }
308 catch ( QgsCsException & )
309 {
310 return;
311 }
312 }
313
314 addGeometry( geom, QgsCoordinateReferenceSystem(), doUpdate );
315}
316
317void QgsRubberBand::addGeometry( const QgsGeometry &geometry, const QgsCoordinateReferenceSystem &crs, bool doUpdate )
318{
319 if ( geometry.isEmpty() )
320 {
321 return;
322 }
323
324 //maprender object of canvas
325 const QgsMapSettings &ms = mMapCanvas->mapSettings();
326
327 int idx = mPoints.size();
328
329 QgsGeometry geom = geometry;
330 if ( crs.isValid() )
331 {
333 try
334 {
335 geom.transform( ct );
336 }
337 catch ( QgsCsException & )
338 {
339 QgsDebugError( u"Could not transform rubber band geometry to map CRS"_s );
340 return;
341 }
342 }
343
344 Qgis::WkbType geomType = geom.wkbType();
346 {
347 QgsPointXY pt = geom.asPoint();
348 addPoint( pt, false, idx );
349 }
351 {
352 const QgsMultiPointXY mpt = geom.asMultiPoint();
353 for ( const QgsPointXY &pt : mpt )
354 {
355 addPoint( pt, false, idx );
356 idx++;
357 }
358 }
359 else if ( QgsWkbTypes::geometryType( geomType ) == Qgis::GeometryType::Line && !QgsWkbTypes::isMultiType( geomType ) )
360 {
361 const QgsPolylineXY line = geom.asPolyline();
362 for ( const QgsPointXY &pt : line )
363 {
364 addPoint( pt, false, idx );
365 }
366 }
367 else if ( QgsWkbTypes::geometryType( geomType ) == Qgis::GeometryType::Line && QgsWkbTypes::isMultiType( geomType ) )
368 {
369 const QgsMultiPolylineXY mline = geom.asMultiPolyline();
370 for ( const QgsPolylineXY &line : mline )
371 {
372 if ( line.isEmpty() )
373 {
374 continue;
375 }
376 for ( const QgsPointXY &pt : line )
377 {
378 addPoint( pt, false, idx );
379 }
380 idx++;
381 }
382 }
384 {
385 const QgsPolygonXY poly = geom.asPolygon();
386 int ringIdx = 0;
387 for ( const QgsPolylineXY &ring : poly )
388 {
389 for ( const QgsPointXY &pt : ring )
390 {
391 addPoint( pt, false, idx, ringIdx );
392 }
393 ringIdx++;
394 }
395 }
397 {
398 const QgsMultiPolygonXY multipoly = geom.asMultiPolygon();
399 for ( const QgsPolygonXY &poly : multipoly )
400 {
401 if ( poly.isEmpty() )
402 continue;
403
404 int ringIdx = 0;
405 for ( const QgsPolylineXY &ring : poly )
406 {
407 for ( const QgsPointXY &pt : ring )
408 {
409 addPoint( pt, false, idx, ringIdx );
410 }
411 ringIdx++;
412 }
413 idx++;
414 }
415 }
416 else
417 {
418 return;
419 }
420
421 setVisible( true );
422 if ( doUpdate )
423 {
424 updateRect();
425 update();
426 }
427}
428
430{
431 if ( !mMapCanvas )
432 {
433 return;
434 }
435
436 const QgsMapToPixel *transform = mMapCanvas->getCoordinateTransform();
437 QgsPointXY ll = transform->toMapCoordinates( rect.left(), rect.bottom() );
438 QgsPointXY lr = transform->toMapCoordinates( rect.right(), rect.bottom() );
439 QgsPointXY ul = transform->toMapCoordinates( rect.left(), rect.top() );
440 QgsPointXY ur = transform->toMapCoordinates( rect.right(), rect.top() );
441
443 addPoint( ll, false );
444 addPoint( lr, false );
445 addPoint( ur, false );
446 addPoint( ul, true );
447}
448
450{
451 reset( other->mGeometryType );
452 mPoints = other->mPoints;
453 updateRect();
454 update();
455}
456
457void QgsRubberBand::paint( QPainter *p )
458{
459 if ( mPoints.isEmpty() )
460 return;
461
462 QgsRenderContext context;
463 if ( mMapCanvas )
464 {
465 context = QgsRenderContext::fromMapSettings( mMapCanvas->mapSettings() );
466 if ( QPaintDevice *device = p->device() )
467 {
468 context.setScaleFactor( device->physicalDpiX() / 25.4 );
469 }
470 context.setPainter( p );
471 }
472 else
473 {
474 context = QgsRenderContext::fromQPainter( p );
476 }
477
478 QVector<QVector<QPolygonF>> shapes;
479 shapes.reserve( mPoints.size() );
480 for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
481 {
482 QVector<QPolygonF> rings;
483 rings.reserve( poly.size() );
484 for ( const QgsPolylineXY &line : poly )
485 {
486 QVector<QPointF> pts;
487 pts.reserve( line.size() );
488 for ( const QgsPointXY &pt : line )
489 {
490 const QPointF cur = toCanvasCoordinates( QgsPointXY( pt.x() + mTranslationOffsetX, pt.y() + mTranslationOffsetY ) ) - pos();
491 if ( pts.isEmpty() || std::abs( pts.last().x() - cur.x() ) > 1 || std::abs( pts.last().y() - cur.y() ) > 1 )
492 pts.append( cur );
493 }
494 rings.append( pts );
495 }
496 shapes.append( rings );
497 }
498
499 if ( mComponentsToRender.testFlag( Qgis::RubberBandComponent::Symbol ) )
500 {
501 if ( QgsLineSymbol *lineSymbol = dynamic_cast<QgsLineSymbol *>( mSymbol.get() ) )
502 {
503 lineSymbol->startRender( context );
504 for ( const QVector<QPolygonF> &shape : std::as_const( shapes ) )
505 {
506 for ( const QPolygonF &ring : shape )
507 {
508 lineSymbol->renderPolyline( ring, nullptr, context );
509 }
510 }
511 lineSymbol->stopRender( context );
512 }
513 else if ( QgsFillSymbol *fillSymbol = dynamic_cast<QgsFillSymbol *>( mSymbol.get() ) )
514 {
515 fillSymbol->startRender( context );
516 for ( const QVector<QPolygonF> &shape : std::as_const( shapes ) )
517 {
518 for ( const QPolygonF &ring : shape )
519 {
520 fillSymbol->renderPolygon( ring, nullptr, nullptr, context );
521 }
522 }
523 fillSymbol->stopRender( context );
524 }
525 else
526 {
527 int iterations = mSecondaryPen.color().isValid() ? 2 : 1;
528 for ( int i = 0; i < iterations; ++i )
529 {
530 if ( i == 0 && iterations > 1 )
531 {
532 // first iteration with multi-pen painting, so use secondary pen
533 mSecondaryPen.setWidthF( mPen.widthF() + QgsGuiUtils::scaleIconSize( 2 ) );
534 p->setBrush( Qt::NoBrush );
535 p->setPen( mSecondaryPen );
536 }
537 else
538 {
539 // "top" layer, use primary pen/brush
540 p->setBrush( mBrush );
541 p->setPen( mPen );
542 }
543
544 for ( const QVector<QPolygonF> &shape : std::as_const( shapes ) )
545 {
546 drawShape( p, shape );
547 }
548 }
549 }
550 }
551
552 if ( mComponentsToRender.testFlag( Qgis::RubberBandComponent::PreviewItems ) )
553 {
554 for ( const auto &item : mPreviewItems )
555 {
556 if ( item )
557 {
558 item->render( context );
559 }
560 }
561 }
562}
563
564void QgsRubberBand::drawShape( QPainter *p, const QVector<QPolygonF> &rings )
565{
566 if ( rings.size() == 1 )
567 {
568 drawShape( p, rings.at( 0 ) );
569 }
570 else
571 {
572 QPainterPath path;
573 for ( const QPolygonF &poly : rings )
574 {
575 path.addPolygon( poly );
576 }
577 p->drawPath( path );
578 }
579}
580
581void QgsRubberBand::drawShape( QPainter *p, const QVector<QPointF> &pts )
582{
583 switch ( mGeometryType )
584 {
586 {
587 p->drawPolygon( pts );
588 }
589 break;
590
592 {
593 const auto constPts = pts;
594 for ( QPointF pt : constPts )
595 {
596 double x = pt.x();
597 double y = pt.y();
598
599 qreal s = ( mIconSize - 1 ) / 2.0;
600
601 switch ( mIconType )
602 {
604 break;
605
607 p->drawLine( QLineF( x - s, y, x + s, y ) );
608 p->drawLine( QLineF( x, y - s, x, y + s ) );
609 break;
610
612 p->drawLine( QLineF( x - s, y - s, x + s, y + s ) );
613 p->drawLine( QLineF( x - s, y + s, x + s, y - s ) );
614 break;
615
617 p->drawLine( QLineF( x - s, y - s, x + s, y - s ) );
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 break;
622
624 p->drawRect( QRectF( static_cast<int>( x - s ), static_cast<int>( y - s ), mIconSize, mIconSize ) );
625 break;
626
628 p->drawEllipse( QRectF( static_cast<int>( x - s ), static_cast<int>( y - s ), mIconSize, mIconSize ) );
629 break;
630
633 {
634 QPointF pts[] = { QPointF( x, y - s ), QPointF( x + s, y ), QPointF( x, y + s ), QPointF( x - s, y ) };
636 p->drawPolygon( pts, 4 );
637 else
638 p->drawPolyline( pts, 4 );
639 break;
640 }
641
643 {
644 QRectF viewBox = mSvgRenderer->viewBoxF();
645 QRectF r( mSvgOffset.x(), mSvgOffset.y(), viewBox.width(), viewBox.height() );
646 QgsScopedQPainterState painterState( p );
647 p->translate( pt );
648 mSvgRenderer->render( p, r );
649 break;
650 }
651 }
652 }
653 }
654 break;
655
657 default:
658 {
659 p->drawPolyline( pts );
660 }
661 break;
662 }
663}
664
666{
667 if ( mPoints.isEmpty() )
668 {
670 setVisible( false );
671 return;
672 }
673
674 const QgsMapToPixel &m2p = *( mMapCanvas->getCoordinateTransform() );
675
676#if 0 // unused?
677 double iconSize = ( mIconSize + 1 ) / 2.;
678 if ( mSvgRenderer )
679 {
680 QRectF viewBox = mSvgRenderer->viewBoxF();
681 iconSize = std::max( std::fabs( mSvgOffset.x() ) + .5 * viewBox.width(), std::fabs( mSvgOffset.y() ) + .5 * viewBox.height() );
682 }
683#endif
684
685 qreal w = ( ( mIconSize - 1 ) / 2 + mPen.widthF() ); // in canvas units
686
687 QgsRectangle r; // in canvas units
688 for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
689 {
690 for ( const QgsPointXY &point : poly.at( 0 ) )
691 {
692 QgsPointXY p( point.x() + mTranslationOffsetX, point.y() + mTranslationOffsetY );
693 p = m2p.transform( p );
694 // no need to normalize the rectangle -- we know it is already normal
695 QgsRectangle rect( p.x() - w, p.y() - w, p.x() + w, p.y() + w, false );
697 }
698 }
699
700 // This is an hack to pass QgsMapCanvasItem::setRect what it
701 // expects (encoding of position and size of the item)
702 qreal res = m2p.mapUnitsPerPixel();
703 QgsPointXY topLeft = m2p.toMapCoordinates( r.xMinimum(), r.yMinimum() );
704 QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + r.width() * res, topLeft.y() - r.height() * res );
705
706 setRect( rect );
707}
708
710{
711 return mComponentsToRender;
712}
713
715{
716 mComponentsToRender = components;
717}
718
720{
721 return mSymbol.get();
722}
723
725{
726 mSymbol.reset( symbol );
727}
728
730{
731 // re-compute rectangle
732 // See https://github.com/qgis/QGIS/issues/20566
733 // NOTE: could be optimized by saving map-extent
734 // of rubberband and simply re-projecting
735 // that to device-rectangle on "updatePosition"
736 updateRect();
737}
738
739void QgsRubberBand::setTranslationOffset( double dx, double dy )
740{
741 mTranslationOffsetX = dx;
742 mTranslationOffsetY = dy;
743 updateRect();
744}
745
747{
748 return mPoints.size();
749}
750
751int QgsRubberBand::partSize( int geometryIndex ) const
752{
753 if ( geometryIndex < 0 || geometryIndex >= mPoints.size() || mPoints.at( geometryIndex ).isEmpty() )
754 return 0;
755 return mPoints.at( geometryIndex ).at( 0 ).size();
756}
757
759{
760 int count = 0;
761 for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
762 {
763 for ( const QgsPolylineXY &ring : poly )
764 {
765 count += ring.size();
766 }
767 }
768 return count;
769}
770
771const QgsPointXY *QgsRubberBand::getPoint( int i, int j, int ringIndex ) const
772{
773 if ( i < 0 || ringIndex < 0 || j < 0 || mPoints.size() <= i || mPoints.at( i ).size() <= ringIndex || mPoints.at( i ).at( ringIndex ).size() <= j )
774 return nullptr;
775 else
776 return &mPoints[i][ringIndex][j];
777}
778
780{
781 QgsGeometry geom;
782
783 switch ( mGeometryType )
784 {
786 {
787 geom = QgsGeometry::fromMultiPolygonXY( mPoints );
788 break;
789 }
790
792 {
793 QgsMultiPointXY multiPoint;
794
795 for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
796 {
797 if ( poly.isEmpty() )
798 continue;
799 multiPoint.append( poly.at( 0 ) );
800 }
801 geom = QgsGeometry::fromMultiPointXY( multiPoint );
802 break;
803 }
804
806 default:
807 {
808 if ( !mPoints.isEmpty() )
809 {
810 if ( mPoints.size() > 1 )
811 {
812 QgsMultiPolylineXY multiPolyline;
813 for ( const QgsPolygonXY &poly : std::as_const( mPoints ) )
814 {
815 if ( poly.isEmpty() )
816 continue;
817 multiPolyline.append( poly.at( 0 ) );
818 }
819 geom = QgsGeometry::fromMultiPolylineXY( multiPolyline );
820 }
821 else
822 {
823 if ( !mPoints.at( 0 ).isEmpty() )
824 geom = QgsGeometry::fromPolylineXY( mPoints.at( 0 ).at( 0 ) );
825 else
827 }
828 }
829 break;
830 }
831 }
832 return geom;
833}
834
835//
836// QgsRubberBandPreviewItem
837//
838
842
844{
845 return mRubberBand.data();
846}
QFlags< RubberBandComponent > RubberBandComponents
Rubber band components.
Definition qgis.h:7030
RubberBandIconType
Rubber band icon type.
Definition qgis.h:7000
@ Circle
A circle is used to highlight points (○).
Definition qgis.h:7005
@ Box
A box is used to highlight points (□).
Definition qgis.h:7004
@ CrossPlus
A cross is used to highlight points (+).
Definition qgis.h:7002
@ NoIcon
No icon is used.
Definition qgis.h:7001
@ Diamond
A diamond is used to highlight points (◇).
Definition qgis.h:7007
@ BoxFilled
A filled box is used to highlight points (■).
Definition qgis.h:7006
@ SVG
An SVG image is used to highlight points.
Definition qgis.h:7009
@ CrossX
A cross is used to highlight points (x).
Definition qgis.h:7003
@ DiamondFilled
A filled diamond is used to highlight points (◆).
Definition qgis.h:7008
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:379
@ Point
Points.
Definition qgis.h:380
@ Line
Lines.
Definition qgis.h:381
@ Polygon
Polygons.
Definition qgis.h:382
@ Antialiasing
Use antialiasing while drawing.
Definition qgis.h:2951
@ Symbol
Base symbol component.
Definition qgis.h:7020
@ PreviewItems
Preview overlayer items.
Definition qgis.h:7021
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
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.
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.
Responsible for drawing transient features (e.g.
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