QGIS API Documentation 3.43.0-Master (1896cf2247d)
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#include <QDomDocument>
23#include <QRectF>
24
25#include "qgis_core.h"
26#include "qgis.h"
27#include "qgspointxy.h"
28
29
30class QString;
31class QRectF;
32class QgsBox3D;
33
34
43class CORE_EXPORT QgsRectangle
44{
45 Q_GADGET
46
47 Q_PROPERTY( double xMinimum READ xMinimum WRITE setXMinimum )
48 Q_PROPERTY( double xMaximum READ xMaximum WRITE setXMaximum )
49 Q_PROPERTY( double yMinimum READ yMinimum WRITE setYMinimum )
50 Q_PROPERTY( double yMaximum READ yMaximum WRITE setYMaximum )
51 Q_PROPERTY( double width READ width )
52 Q_PROPERTY( double height READ height )
53 Q_PROPERTY( double area READ area )
54 Q_PROPERTY( double perimeter READ perimeter )
55 Q_PROPERTY( QgsPointXY center READ center )
56 Q_PROPERTY( bool isEmpty READ isEmpty )
57 Q_PROPERTY( bool isNull READ isNull )
58
59 public:
60
62 QgsRectangle() = default; // optimised constructor for null rectangle - no need to call normalize here
63
70 explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0, bool normalize = true ) SIP_HOLDGIL
71 : mXmin( xMin )
72 , mYmin( yMin )
73 , mXmax( xMax )
74 , mYmax( yMax )
75 {
76 if ( normalize )
78 }
79
86 QgsRectangle( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true ) SIP_HOLDGIL
87 {
88 set( p1, p2, normalize );
89 }
90
96 QgsRectangle( const QRectF &qRectF ) SIP_HOLDGIL
97 {
98 mXmin = qRectF.topLeft().x();
99 mYmin = qRectF.topLeft().y();
100 mXmax = qRectF.bottomRight().x();
101 mYmax = qRectF.bottomRight().y();
102 }
103
105 {
106 mXmin = other.xMinimum();
107 mYmin = other.yMinimum();
108 mXmax = other.xMaximum();
109 mYmax = other.yMaximum();
110 }
111
112 // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
113 // because this class MUST be lightweight and we don't want the cost of the vtable here.
114 // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
115 ~QgsRectangle() = default;
116
121 static QgsRectangle fromWkt( const QString &wkt );
122
127 static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
128
135 void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
136 {
137 mXmin = p1.x();
138 mXmax = p2.x();
139 mYmin = p1.y();
140 mYmax = p2.y();
141 if ( normalize )
143 }
144
151 void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
152 {
153 mXmin = xMin;
154 mYmin = yMin;
155 mXmax = xMax;
156 mYmax = yMax;
157 if ( normalize )
159 }
160
164 void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
165
169 void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
170
174 void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
175
179 void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
180
192 {
193 mXmin = mYmin = std::numeric_limits<double>::max();
194 mXmax = mYmax = -std::numeric_limits<double>::max();
195 }
196
203 Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
204 {
205 setNull();
206 }
207
211 double xMaximum() const SIP_HOLDGIL { return mXmax; }
212
216 double xMinimum() const SIP_HOLDGIL { return mXmin; }
217
221 double yMaximum() const SIP_HOLDGIL { return mYmax; }
222
226 double yMinimum() const SIP_HOLDGIL { return mYmin; }
227
232 {
233 if ( isNull() )
234 return;
235
236 if ( mXmin > mXmax )
237 {
238 std::swap( mXmin, mXmax );
239 }
240 if ( mYmin > mYmax )
241 {
242 std::swap( mYmin, mYmax );
243 }
244 }
245
251 double width() const SIP_HOLDGIL { return mXmax - mXmin; }
252
258 double height() const SIP_HOLDGIL { return mYmax - mYmin; }
259
266 double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
267
272 double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
273
277 QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
278
282 void scale( double scaleFactor, const QgsPointXY *c = nullptr )
283 {
284 // scale from the center
285 double centerX, centerY;
286 if ( c )
287 {
288 centerX = c->x();
289 centerY = c->y();
290 }
291 else
292 {
293 centerX = mXmin + width() / 2;
294 centerY = mYmin + height() / 2;
295 }
296 scale( scaleFactor, centerX, centerY );
297 }
298
302 void scale( double scaleFactor, double centerX, double centerY )
303 {
304 const double newWidth = width() * scaleFactor;
305 const double newHeight = height() * scaleFactor;
306 mXmin = centerX - newWidth / 2.0;
307 mXmax = centerX + newWidth / 2.0;
308 mYmin = centerY - newHeight / 2.0;
309 mYmax = centerY + newHeight / 2.0;
310 }
311
316 QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
317
322 void grow( double delta )
323 {
324 if ( isNull() )
325 return;
326 mXmin -= delta;
327 mXmax += delta;
328 mYmin -= delta;
329 mYmax += delta;
330 }
331
335 void include( const QgsPointXY &p )
336 {
337 if ( isNull() )
338 {
339 setXMinimum( p.x() );
340 setXMaximum( p.x() );
341 setYMinimum( p.y() );
342 setYMaximum( p.y() );
343 return;
344 }
345 if ( p.x() < xMinimum() )
346 setXMinimum( p.x() );
347 if ( p.x() > xMaximum() )
348 setXMaximum( p.x() );
349 if ( p.y() < yMinimum() )
350 setYMinimum( p.y() );
351 if ( p.y() > yMaximum() )
352 setYMaximum( p.y() );
353 }
354
360 QgsRectangle buffered( double width ) const
361 {
362 if ( isNull() )
363 return QgsRectangle();
364 return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
365 }
366
371 {
372 QgsRectangle intersection = QgsRectangle();
373 if ( intersects( rect ) )
374 {
375 intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
376 intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
377 intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
378 intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
379 }
380 return intersection;
381 }
382
386 bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
387 {
388 if ( isNull() || rect.isNull() )
389 {
390 return false;
391 }
392
393 const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
394 const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
395 if ( x1 > x2 )
396 return false;
397 const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
398 const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
399 return y1 <= y2;
400 }
401
405 bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
406 {
407 return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
408 }
409
413 bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
414 {
415 return mXmin <= p.x() && p.x() <= mXmax &&
416 mYmin <= p.y() && p.y() <= mYmax;
417 }
418
424 bool contains( double x, double y ) const SIP_HOLDGIL
425 {
426 return mXmin <= x && x <= mXmax &&
427 mYmin <= y && y <= mYmax;
428 }
429
433 void combineExtentWith( const QgsRectangle &rect )
434 {
435 if ( isNull() )
436 *this = rect;
437 else if ( !rect.isNull() )
438 {
439 mXmin = std::min( mXmin, rect.xMinimum() );
440 mXmax = std::max( mXmax, rect.xMaximum() );
441 mYmin = std::min( mYmin, rect.yMinimum() );
442 mYmax = std::max( mYmax, rect.yMaximum() );
443 }
444 }
445
449 void combineExtentWith( double x, double y )
450 {
451 if ( isNull() )
452 *this = QgsRectangle( x, y, x, y );
453 else
454 {
455 mXmin = ( ( mXmin < x ) ? mXmin : x );
456 mXmax = ( ( mXmax > x ) ? mXmax : x );
457
458 mYmin = ( ( mYmin < y ) ? mYmin : y );
459 mYmax = ( ( mYmax > y ) ? mYmax : y );
460 }
461 }
462
467 void combineExtentWith( const QgsPointXY &point )
468 {
469 combineExtentWith( point.x(), point.y() );
470 }
471
476 double distance( const QgsPointXY &point ) const
477 {
478 const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
479 const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
480 return std::sqrt( dx * dx + dy * dy );
481 }
482
487
492
496 QgsRectangle &operator-=( QgsVector v );
497
501 QgsRectangle &operator+=( QgsVector v );
502
512 bool isEmpty() const
513 {
514 return isNull() || mXmax <= mXmin || mYmax <= mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
515 }
516
525 bool isNull() const
526 {
527 // rectangle created QgsRectangle() or with rect.setNull() or
528 // otherwise having NaN ordinates
529 return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
530 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
531 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
532 }
533
546 bool isMaximal() const
547 {
548 return ( std::isinf( mXmin ) || mXmin == std::numeric_limits<double>::lowest() )
549 && ( std::isinf( mYmin ) || mYmin == std::numeric_limits<double>::lowest() )
550 && ( std::isinf( mXmax ) || mXmax == std::numeric_limits<double>::max() )
551 && ( std::isinf( mYmax ) || mYmax == std::numeric_limits<double>::max() );
552 }
553
557 Q_INVOKABLE QString asWktCoordinates() const;
558
562 Q_INVOKABLE QString asWktPolygon() const;
563
567 QRectF toRectF() const
568 {
569 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
570 }
571
577 Q_INVOKABLE QString toString( int precision = 16 ) const;
578
582 QString asPolygon() const;
583
584 bool operator==( const QgsRectangle &r1 ) const
585 {
586 if ( isNull() ) return r1.isNull();
587
588 return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
589 qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
590 qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
591 qgsDoubleNear( r1.yMinimum(), yMinimum() );
592 }
593
594 bool operator!=( const QgsRectangle &r1 ) const
595 {
596 return ( ! operator==( r1 ) );
597 }
598
600 {
601 if ( &r1 != this )
602 {
603 mXmax = r1.xMaximum();
604 mXmin = r1.xMinimum();
605 mYmax = r1.yMaximum();
606 mYmin = r1.yMinimum();
607 }
608
609 return *this;
610 }
611
620 bool isFinite() const
621 {
622 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
623 {
624 return false;
625 }
626 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
627 {
628 return false;
629 }
630 return true;
631 }
632
636 void invert()
637 {
638 std::swap( mXmin, mYmin );
639 std::swap( mXmax, mYmax );
640 }
641
646 QgsBox3D toBox3d( double zMin, double zMax ) const;
647
649 operator QVariant() const
650 {
651 return QVariant::fromValue( *this );
652 }
653
660 QgsRectangle snappedToGrid( double spacing ) const;
661
662#ifdef SIP_RUN
663 SIP_PYOBJECT __repr__();
664 % MethodCode
665 QString str;
666 if ( sipCpp->isNull() )
667 str = QStringLiteral( "<QgsRectangle()>" );
668 else
669 str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
670 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
671 % End
672#endif
673
674 private:
675
676 double mXmin = std::numeric_limits<double>::max();
677 double mYmin = std::numeric_limits<double>::max();
678 double mXmax = -std::numeric_limits<double>::max();
679 double mYmax = -std::numeric_limits<double>::max();
680
681};
682
684
685#ifndef SIP_RUN
686
690CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
691
695CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
696
697inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
698{
699 return os << r.toString().toLocal8Bit().data();
700}
701
702#endif
703
704#endif // QGSRECTANGLE_H
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:43
Represents a 2D point.
Definition qgspointxy.h:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
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 truncated to the sp...
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.
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 (left side of rectangle).
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).
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 (bottom side of rectangle).
bool operator!=(const QgsRectangle &r1) const
void setXMinimum(double x)
Set the minimum x value.
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 (right side of rectangle).
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 (top side of rectangle).
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
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.
void normalize()
Normalize the rectangle so it has non-negative width/height.
bool isEmpty() const
Returns true if the rectangle has no area.
QgsRectangle(const QRectF &qRectF)
Construct a rectangle from a QRectF.
double height() const
Returns the height of the rectangle.
void setNull()
Mark a rectangle as being null (holding no spatial information).
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.
Represent a 2-dimensional vector.
Definition qgsvector.h:30
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:6302
#define SIP_DEPRECATED
Definition qgis_sip.h:106
#define SIP_HOLDGIL
Definition qgis_sip.h:171
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.
int precision