QGIS API Documentation 4.3.0-Master (9dce731a7a1)
Loading...
Searching...
No Matches
qgsrectangle.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsrectangle.h - description
3 -------------------
4 begin : Sat Jun 22 2002
5 copyright : (C) 2002 by Gary E.Sherman
6 email : sherman at mrcc.com
7***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#ifndef QGSRECTANGLE_H
19#define QGSRECTANGLE_H
20
21#include <iosfwd>
22
23#include "qgis.h"
24#include "qgis_core.h"
25#include "qgspointxy.h"
26
27#include <QDomDocument>
28#include <QRectF>
29#include <QString>
30
31using namespace Qt::StringLiterals;
32
33class QString;
34class QRectF;
35class QgsBox3D;
36
37
46class CORE_EXPORT QgsRectangle
47{
48 Q_GADGET
49
50 Q_PROPERTY( double xMinimum READ xMinimum WRITE setXMinimum )
51 Q_PROPERTY( double xMaximum READ xMaximum WRITE setXMaximum )
52 Q_PROPERTY( double yMinimum READ yMinimum WRITE setYMinimum )
53 Q_PROPERTY( double yMaximum READ yMaximum WRITE setYMaximum )
54 Q_PROPERTY( double width READ width )
55 Q_PROPERTY( double height READ height )
56 Q_PROPERTY( double area READ area )
57 Q_PROPERTY( double perimeter READ perimeter )
58 Q_PROPERTY( QgsPointXY center READ center )
59 Q_PROPERTY( bool isEmpty READ isEmpty )
60 Q_PROPERTY( bool isNull READ isNull )
61 Q_PROPERTY( bool isValid READ isValid )
62
63 public:
65 QgsRectangle() = default; // optimised constructor for null rectangle - no need to call normalize here
66
67 // clang-format off
77 explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0, bool normalize = true ) SIP_HOLDGIL
78 // clang-format on
79 : mXmin( xMin )
80 , mYmin( yMin )
81 , mXmax( xMax )
82 , mYmax( yMax )
83 {
84 if ( normalize )
86 }
87
94 QgsRectangle( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true ) SIP_HOLDGIL
95 {
96 set( p1, p2, normalize );
97 }
98
104 QgsRectangle( const QRectF &qRectF ) SIP_HOLDGIL
105 {
106 mXmin = qRectF.topLeft().x();
107 mYmin = qRectF.topLeft().y();
108 mXmax = qRectF.bottomRight().x();
109 mYmax = qRectF.bottomRight().y();
110 }
111
113 {
114 mXmin = other.xMinimum();
115 mYmin = other.yMinimum();
116 mXmax = other.xMaximum();
117 mYmax = other.yMaximum();
118 }
119
120 // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
121 // because this class MUST be lightweight and we don't want the cost of the vtable here.
122 // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
123 ~QgsRectangle() = default;
124
129 static QgsRectangle fromWkt( const QString &wkt );
130
135 static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
136
147 static QgsRectangle fromEdges( double left, double top, double right, double bottom );
148
155 void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
156 {
157 mXmin = p1.x();
158 mXmax = p2.x();
159 mYmin = p1.y();
160 mYmax = p2.y();
161 if ( normalize )
163 }
164
171 void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
172 {
173 mXmin = xMin;
174 mYmin = yMin;
175 mXmax = xMax;
176 mYmax = yMax;
177 if ( normalize )
179 }
180
184 void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
185
189 void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
190
194 void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
195
199 void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
200
212 {
213 mXmin = mYmin = std::numeric_limits<double>::max();
214 mXmax = mYmax = -std::numeric_limits<double>::max();
215 }
216
223 Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
224 {
225 setNull();
226 }
227
238 double xMaximum() const SIP_HOLDGIL { return mXmax; }
239
250 double xMinimum() const SIP_HOLDGIL { return mXmin; }
251
260 double yMaximum() const SIP_HOLDGIL { return mYmax; }
261
270 double yMinimum() const SIP_HOLDGIL { return mYmin; }
271
282 double left() const SIP_HOLDGIL { return mXmin; }
283
294 double right() const SIP_HOLDGIL { return mXmax; }
295
305 double top() const SIP_HOLDGIL { return mYmax; }
306
316 double bottom() const SIP_HOLDGIL { return mYmin; }
317
322 {
323 if ( isNull() )
324 return;
325
326 if ( mXmin > mXmax )
327 {
328 std::swap( mXmin, mXmax );
329 }
330 if ( mYmin > mYmax )
331 {
332 std::swap( mYmin, mYmax );
333 }
334 }
335
341 double width() const SIP_HOLDGIL { return mXmax - mXmin; }
342
348 double height() const SIP_HOLDGIL { return mYmax - mYmin; }
349
356 double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
357
362 double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
363
367 QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
368
372 void scale( double scaleFactor, const QgsPointXY *c = nullptr )
373 {
374 // scale from the center
375 double centerX, centerY;
376 if ( c )
377 {
378 centerX = c->x();
379 centerY = c->y();
380 }
381 else
382 {
383 centerX = mXmin + width() / 2;
384 centerY = mYmin + height() / 2;
385 }
386 scale( scaleFactor, centerX, centerY );
387 }
388
392 void scale( double scaleFactor, double centerX, double centerY )
393 {
394 const double newWidth = width() * scaleFactor;
395 const double newHeight = height() * scaleFactor;
396 mXmin = centerX - newWidth / 2.0;
397 mXmax = centerX + newWidth / 2.0;
398 mYmin = centerY - newHeight / 2.0;
399 mYmax = centerY + newHeight / 2.0;
400 }
401
406 QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
407
412 void grow( double delta )
413 {
414 if ( isNull() )
415 return;
416 mXmin -= delta;
417 mXmax += delta;
418 mYmin -= delta;
419 mYmax += delta;
420 }
421
425 void include( const QgsPointXY &p )
426 {
427 if ( isNull() )
428 {
429 setXMinimum( p.x() );
430 setXMaximum( p.x() );
431 setYMinimum( p.y() );
432 setYMaximum( p.y() );
433 return;
434 }
435 if ( p.x() < xMinimum() )
436 setXMinimum( p.x() );
437 if ( p.x() > xMaximum() )
438 setXMaximum( p.x() );
439 if ( p.y() < yMinimum() )
440 setYMinimum( p.y() );
441 if ( p.y() > yMaximum() )
442 setYMaximum( p.y() );
443 }
444
451 {
452 if ( isNull() )
453 return QgsRectangle();
454 return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
455 }
456
461 {
462 QgsRectangle intersection = QgsRectangle();
463 if ( intersects( rect ) )
464 {
465 intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
466 intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
467 intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
468 intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
469 }
470 return intersection;
471 }
472
476 bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
477 {
478 if ( isNull() || rect.isNull() )
479 {
480 return false;
481 }
482
483 const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
484 const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
485 if ( x1 > x2 )
486 return false;
487 const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
488 const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
489 return y1 <= y2;
490 }
491
495 bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
496 {
497 return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
498 }
499
503 bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
504 {
505 return mXmin <= p.x() && p.x() <= mXmax &&
506 mYmin <= p.y() && p.y() <= mYmax;
507 }
508
514 bool contains( double x, double y ) const SIP_HOLDGIL
515 {
516 return mXmin <= x && x <= mXmax &&
517 mYmin <= y && y <= mYmax;
518 }
519
523 void combineExtentWith( const QgsRectangle &rect )
524 {
525 if ( isNull() )
526 *this = rect;
527 else if ( !rect.isNull() )
528 {
529 mXmin = std::min( mXmin, rect.xMinimum() );
530 mXmax = std::max( mXmax, rect.xMaximum() );
531 mYmin = std::min( mYmin, rect.yMinimum() );
532 mYmax = std::max( mYmax, rect.yMaximum() );
533 }
534 }
535
539 void combineExtentWith( double x, double y )
540 {
541 if ( isNull() )
542 *this = QgsRectangle( x, y, x, y );
543 else
544 {
545 mXmin = ( ( mXmin < x ) ? mXmin : x );
546 mXmax = ( ( mXmax > x ) ? mXmax : x );
547
548 mYmin = ( ( mYmin < y ) ? mYmin : y );
549 mYmax = ( ( mYmax > y ) ? mYmax : y );
550 }
551 }
552
557 void combineExtentWith( const QgsPointXY &point )
558 {
559 combineExtentWith( point.x(), point.y() );
560 }
561
566 double distance( const QgsPointXY &point ) const
567 {
568 const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
569 const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
570 return std::sqrt( dx * dx + dy * dy );
571 }
572
577
582
586 QgsRectangle &operator-=( QgsVector v );
587
591 QgsRectangle &operator+=( QgsVector v );
592
607 bool isEmpty() const
608 {
609 return isNull() || mXmax <= mXmin || mYmax <= mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
610 }
611
621 bool isPoint() const
622 {
623 return qgsDoubleNear( mXmax, mXmin ) && qgsDoubleNear( mYmax, mYmin ) && !isNull();
624 }
625
636 bool isNull() const
637 {
638 // rectangle created QgsRectangle() or with rect.setNull() or
639 // otherwise having NaN ordinates
640 return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
641 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
642 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
643 }
644
654 bool isValid() const
655 {
656 if ( ( !isFinite() ) || ( mXmax <= mXmin ) || ( mYmax <= mYmin ) )
657 {
658 return false;
659 }
660 return true;
661 }
662
675 bool isMaximal() const
676 {
677 return ( std::isinf( mXmin ) || mXmin == std::numeric_limits<double>::lowest() )
678 && ( std::isinf( mYmin ) || mYmin == std::numeric_limits<double>::lowest() )
679 && ( std::isinf( mXmax ) || mXmax == std::numeric_limits<double>::max() )
680 && ( std::isinf( mYmax ) || mYmax == std::numeric_limits<double>::max() );
681 }
682
686 Q_INVOKABLE QString asWktCoordinates() const;
687
691 Q_INVOKABLE QString asWktPolygon() const;
692
696 QRectF toRectF() const
697 {
698 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
699 }
700
706 Q_INVOKABLE QString toString( int precision = 16 ) const;
707
711 QString asPolygon() const;
712
713 bool operator==( const QgsRectangle &r1 ) const
714 {
715 if ( isNull() ) return r1.isNull();
716
717 return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
718 qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
719 qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
721 }
722
723 bool operator!=( const QgsRectangle &r1 ) const
724 {
725 return ( ! operator==( r1 ) );
726 }
727
729 {
730 if ( &r1 != this )
731 {
732 mXmax = r1.xMaximum();
733 mXmin = r1.xMinimum();
734 mYmax = r1.yMaximum();
735 mYmin = r1.yMinimum();
736 }
737
738 return *this;
739 }
740
749 bool isFinite() const
750 {
751 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
752 {
753 return false;
754 }
755 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
756 {
757 return false;
758 }
759 return true;
760 }
761
765 void invert()
766 {
767 std::swap( mXmin, mYmin );
768 std::swap( mXmax, mYmax );
769 }
770
775 QgsBox3D toBox3d( double zMin, double zMax ) const;
776
778 operator QVariant() const
779 {
780 return QVariant::fromValue( *this );
781 }
782
789 QgsRectangle snappedToGrid( double spacing ) const;
790
791#ifdef SIP_RUN
792// clang-format off
793 SIP_PYOBJECT __repr__();
794 % MethodCode
795 QString str;
796 if ( sipCpp->isNull() )
797 str = u"<QgsRectangle()>"_s;
798 else
799 str = u"<QgsRectangle: %1>"_s.arg( sipCpp->asWktCoordinates() );
800 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
801 % End
802// clang-format on
803#endif
804
805 private:
806
807 double mXmin = std::numeric_limits<double>::max();
808 double mYmin = std::numeric_limits<double>::max();
809 double mXmax = -std::numeric_limits<double>::max();
810 double mYmax = -std::numeric_limits<double>::max();
811
812};
813
815
816#ifndef SIP_RUN
817
821CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
822
826CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
827
828inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
829{
830 return os << r.toString().toLocal8Bit().data();
831}
832
833#endif
834
835#endif // QGSRECTANGLE_H
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:45
Represents a 2D point.
Definition qgspointxy.h:62
double y
Definition qgspointxy.h:66
double x
Definition qgspointxy.h:65
A rectangle specified with double values.
Q_INVOKABLE QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be rounded to the spec...
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
double xMinimum
Q_DECL_DEPRECATED void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
void combineExtentWith(const QgsPointXY &point)
Expands the rectangle so that it covers both the original rectangle and the given point.
QgsRectangle()=default
Constructor for a null rectangle.
double area() const
Returns the area of the rectangle.
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
bool isMaximal() const
Test if the rectangle is the maximal possible rectangle.
double yMinimum
double xMinimum() const
Returns the x minimum value.
double xMaximum
void combineExtentWith(double x, double y)
Expands the rectangle so that it covers both the original rectangle and the given point.
QgsRectangle(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Construct a rectangle from two points.
bool contains(double x, double y) const
Returns true when rectangle contains the point at (x, y).
static QgsRectangle fromWkt(const QString &wkt)
Creates a new rectangle from a wkt string.
void setYMinimum(double y)
Set the minimum y value.
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
double yMinimum() const
Returns the y minimum value.
bool operator!=(const QgsRectangle &r1) const
void setXMinimum(double x)
Set the minimum x value.
static QgsRectangle fromEdges(double left, double top, double right, double bottom)
Creates a rectangle from the left, top, right and bottom edges.
double width() const
Returns the width of the rectangle.
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
double xMaximum() const
Returns the x maximum value.
bool isNull() const
Test if the rectangle is null (holding no spatial information).
QgsRectangle(const QgsRectangle &other)
double yMaximum() const
Returns the y maximum value.
QgsRectangle & operator=(const QgsRectangle &r1)
void set(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Sets the rectangle from two QgsPoints.
void setYMaximum(double y)
Set the maximum y value.
QgsPointXY center() const
Returns the center point of the rectangle.
void setXMaximum(double x)
Set the maximum x value.
void grow(double delta)
Grows the rectangle in place by the specified amount.
bool operator==(const QgsRectangle &r1) const
~QgsRectangle()=default
bool isValid() const
Test if the rectangle is valid.
double perimeter
double yMaximum
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
double perimeter() const
Returns the perimeter of the rectangle.
void set(double xMin, double yMin, double xMax, double yMax, bool normalize=true)
Sets the rectangle from four points.
double left() const
Returns the left side of the rectangle.
void normalize()
Normalize the rectangle so it has non-negative width/height.
double right() const
Returns the right side of the rectangle.
bool isEmpty() const
Returns true if the rectangle has no area.
QgsRectangle(const QRectF &qRectF)
Construct a rectangle from a QRectF.
static QgsRectangle fromCenterAndSize(const QgsPointXY &center, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
double height() const
Returns the height of the rectangle.
QgsPointXY center
void setNull()
Mark a rectangle as being null (holding no spatial information).
bool isPoint() const
Returns true if the rectangle represents a point.
double bottom() const
Returns the bottom side of the rectangle.
bool contains(const QgsPointXY &p) const
Returns true when rectangle contains a point.
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
void scale(double scaleFactor, double centerX, double centerY)
Scale the rectangle around its center point.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
void invert()
Swap x/y coordinates in the rectangle.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
double distance(const QgsPointXY &point) const
Returns the distance from point to the nearest point on the boundary of the rectangle.
double top() const
Returns the top side of the rectangle.
Represent a 2-dimensional vector.
Definition qgsvector.h:34
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7783
#define SIP_DEPRECATED
Definition qgis_sip.h:113
#define SIP_HOLDGIL
Definition qgis_sip.h:183
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
QgsInterval operator-(QDate date1, QDate date2)
Returns the interval between two dates.
QDateTime operator+(const QDateTime &start, const QgsInterval &interval)
Adds an interval to a datetime.
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsRectangle &rectangle)
Writes the list rectangle to stream out.
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsRectangle &rectangle)
Reads a rectangle from stream in into rectangle.