QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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 "qgis_core.h"
22 #include "qgis.h"
23 #include <iosfwd>
24 #include <QDomDocument>
25 #include <QRectF>
26 
27 class QString;
28 class QRectF;
29 class QgsBox3d;
30 #include "qgspointxy.h"
31 
32 
41 class CORE_EXPORT QgsRectangle
42 {
43  public:
44 
46  QgsRectangle() = default; // optimised constructor for null rectangle - no need to call normalize here
47 
49  explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0 ) SIP_HOLDGIL
50  : mXmin( xMin )
51  , mYmin( yMin )
52  , mXmax( xMax )
53  , mYmax( yMax )
54  {
55  normalize();
56  }
57 
60  {
61  set( p1, p2 );
62  }
63 
65  QgsRectangle( const QRectF &qRectF ) SIP_HOLDGIL
66  {
67  mXmin = qRectF.topLeft().x();
68  mYmin = qRectF.topLeft().y();
69  mXmax = qRectF.bottomRight().x();
70  mYmax = qRectF.bottomRight().y();
71  }
72 
75  {
76  mXmin = other.xMinimum();
77  mYmin = other.yMinimum();
78  mXmax = other.xMaximum();
79  mYmax = other.yMaximum();
80  }
81 
82  // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
83  // because this class MUST be lightweight and we don't want the cost of the vtable here.
84  // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
85  ~QgsRectangle() = default;
86 
92  static QgsRectangle fromWkt( const QString &wkt );
93 
99  static QgsRectangle fromCenterAndSize( QgsPointXY center, double width, double height );
100 
105  void set( const QgsPointXY &p1, const QgsPointXY &p2 )
106  {
107  mXmin = p1.x();
108  mXmax = p2.x();
109  mYmin = p1.y();
110  mYmax = p2.y();
111  normalize();
112  }
113 
118  void set( double xMin, double yMin, double xMax, double yMax )
119  {
120  mXmin = xMin;
121  mYmin = yMin;
122  mXmax = xMax;
123  mYmax = yMax;
124  normalize();
125  }
126 
130  void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
131 
135  void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
136 
140  void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
141 
145  void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
146 
152  {
153  mXmin = std::numeric_limits<double>::max();
154  mYmin = std::numeric_limits<double>::max();
155  mXmax = -std::numeric_limits<double>::max();
156  mYmax = -std::numeric_limits<double>::max();
157  }
158 
162  double xMaximum() const SIP_HOLDGIL { return mXmax; }
163 
167  double xMinimum() const SIP_HOLDGIL { return mXmin; }
168 
172  double yMaximum() const SIP_HOLDGIL { return mYmax; }
173 
177  double yMinimum() const SIP_HOLDGIL { return mYmin; }
178 
182  void normalize()
183  {
184  if ( isNull() )
185  return;
186 
187  if ( mXmin > mXmax )
188  {
189  std::swap( mXmin, mXmax );
190  }
191  if ( mYmin > mYmax )
192  {
193  std::swap( mYmin, mYmax );
194  }
195  }
196 
202  double width() const SIP_HOLDGIL { return mXmax - mXmin; }
203 
209  double height() const SIP_HOLDGIL { return mYmax - mYmin; }
210 
218  double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
219 
225  double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
226 
230  QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
231 
235  void scale( double scaleFactor, const QgsPointXY *c = nullptr )
236  {
237  // scale from the center
238  double centerX, centerY;
239  if ( c )
240  {
241  centerX = c->x();
242  centerY = c->y();
243  }
244  else
245  {
246  centerX = mXmin + width() / 2;
247  centerY = mYmin + height() / 2;
248  }
249  scale( scaleFactor, centerX, centerY );
250  }
251 
255  void scale( double scaleFactor, double centerX, double centerY )
256  {
257  double newWidth = width() * scaleFactor;
258  double newHeight = height() * scaleFactor;
259  mXmin = centerX - newWidth / 2.0;
260  mXmax = centerX + newWidth / 2.0;
261  mYmin = centerY - newHeight / 2.0;
262  mYmax = centerY + newHeight / 2.0;
263  }
264 
269  QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
270 
275  void grow( double delta )
276  {
277  mXmin -= delta;
278  mXmax += delta;
279  mYmin -= delta;
280  mYmax += delta;
281  }
282 
286  void include( const QgsPointXY &p )
287  {
288  if ( p.x() < xMinimum() )
289  setXMinimum( p.x() );
290  else if ( p.x() > xMaximum() )
291  setXMaximum( p.x() );
292  if ( p.y() < yMinimum() )
293  setYMinimum( p.y() );
294  if ( p.y() > yMaximum() )
295  setYMaximum( p.y() );
296  }
297 
304  QgsRectangle buffered( double width ) const
305  {
306  return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
307  }
308 
312  QgsRectangle intersect( const QgsRectangle &rect ) const
313  {
314  QgsRectangle intersection = QgsRectangle();
315  if ( intersects( rect ) )
316  {
317  intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
318  intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
319  intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
320  intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
321  }
322  return intersection;
323  }
324 
328  bool intersects( const QgsRectangle &rect ) const
329  {
330  double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
331  double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
332  if ( x1 > x2 )
333  return false;
334  double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
335  double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
336  return y1 <= y2;
337  }
338 
342  bool contains( const QgsRectangle &rect ) const
343  {
344  return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
345  }
346 
350  bool contains( const QgsPointXY &p ) const
351  {
352  return mXmin <= p.x() && p.x() <= mXmax &&
353  mYmin <= p.y() && p.y() <= mYmax;
354  }
355 
359  void combineExtentWith( const QgsRectangle &rect )
360  {
361  if ( isNull() )
362  *this = rect;
363  else if ( !rect.isNull() )
364  {
365  mXmin = std::min( mXmin, rect.xMinimum() );
366  mXmax = std::max( mXmax, rect.xMaximum() );
367  mYmin = std::min( mYmin, rect.yMinimum() );
368  mYmax = std::max( mYmax, rect.yMaximum() );
369  }
370  }
371 
375  void combineExtentWith( double x, double y )
376  {
377  if ( isNull() )
378  *this = QgsRectangle( x, y, x, y );
379  else
380  {
381  mXmin = ( ( mXmin < x ) ? mXmin : x );
382  mXmax = ( ( mXmax > x ) ? mXmax : x );
383 
384  mYmin = ( ( mYmin < y ) ? mYmin : y );
385  mYmax = ( ( mYmax > y ) ? mYmax : y );
386  }
387  }
388 
393  void combineExtentWith( const QgsPointXY &point )
394  {
395  combineExtentWith( point.x(), point.y() );
396  }
397 
402  double distance( const QgsPointXY &point ) const
403  {
404  const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
405  const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
406  return std::sqrt( dx * dx + dy * dy );
407  }
408 
413  QgsRectangle operator-( QgsVector v ) const;
414 
419  QgsRectangle operator+( QgsVector v ) const;
420 
425  QgsRectangle &operator-=( QgsVector v );
426 
431  QgsRectangle &operator+=( QgsVector v );
432 
437  bool isEmpty() const
438  {
439  return mXmax < mXmin || mYmax < mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
440  }
441 
447  bool isNull() const
448  {
449  // rectangle created QgsRectangle() or with rect.setMinimal() ?
450  return ( qgsDoubleNear( mXmin, 0.0 ) && qgsDoubleNear( mXmax, 0.0 ) && qgsDoubleNear( mYmin, 0.0 ) && qgsDoubleNear( mYmax, 0.0 ) ) ||
451  ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
452  qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
453  }
454 
458  QString asWktCoordinates() const;
459 
463  QString asWktPolygon() const;
464 
468  QRectF toRectF() const
469  {
470  return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
471  }
472 
478  QString toString( int precision = 16 ) const;
479 
483  QString asPolygon() const;
484 
489  bool operator==( const QgsRectangle &r1 ) const
490  {
491  return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
492  qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
493  qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
494  qgsDoubleNear( r1.yMinimum(), yMinimum() );
495  }
496 
501  bool operator!=( const QgsRectangle &r1 ) const
502  {
503  return ( ! operator==( r1 ) );
504  }
505 
511  {
512  if ( &r1 != this )
513  {
514  mXmax = r1.xMaximum();
515  mXmin = r1.xMinimum();
516  mYmax = r1.yMaximum();
517  mYmin = r1.yMinimum();
518  }
519 
520  return *this;
521  }
522 
527  bool isFinite() const
528  {
529  if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
530  {
531  return false;
532  }
533  if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
534  {
535  return false;
536  }
537  return true;
538  }
539 
543  void invert()
544  {
545  std::swap( mXmin, mYmin );
546  std::swap( mXmax, mYmax );
547  }
548 
554  QgsBox3d toBox3d( double zMin, double zMax ) const;
555 
557  operator QVariant() const
558  {
559  return QVariant::fromValue( *this );
560  }
561 
568  QgsRectangle snappedToGrid( double spacing ) const;
569 
570 #ifdef SIP_RUN
571  SIP_PYOBJECT __repr__();
572  % MethodCode
573  QString str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
574  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
575  % End
576 #endif
577 
578  private:
579 
580  double mXmin = 0.0;
581  double mYmin = 0.0;
582  double mXmax = 0.0;
583  double mYmax = 0.0;
584 
585 };
586 
588 
589 #ifndef SIP_RUN
590 
594 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
595 
599 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
600 
601 inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
602 {
603  return os << r.toString().toLocal8Bit().data();
604 }
605 
606 #endif
607 
608 #endif // QGSRECTANGLE_H
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:39
A class to represent a 2D point.
Definition: qgspointxy.h:44
double y
Definition: qgspointxy.h:48
Q_GADGET double x
Definition: qgspointxy.h:47
A rectangle specified with double values.
Definition: qgsrectangle.h:42
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.
Definition: qgsrectangle.h:235
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:342
void combineExtentWith(const QgsPointXY &point)
Expands the rectangle so that it covers both the original rectangle and the given point.
Definition: qgsrectangle.h:393
QgsRectangle()=default
Constructor for a null rectangle.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
Definition: qgsrectangle.h:286
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
void combineExtentWith(double x, double y)
Expands the rectangle so that it covers both the original rectangle and the given point.
Definition: qgsrectangle.h:375
QgsRectangle(const QRectF &qRectF) SIP_HOLDGIL
Construct a rectangle from a QRectF. The rectangle is normalized after construction.
Definition: qgsrectangle.h:65
QgsRectangle(double xMin, double yMin=0, double xMax=0, double yMax=0) SIP_HOLDGIL
Constructor.
Definition: qgsrectangle.h:49
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:140
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
Definition: qgsrectangle.h:328
void set(double xMin, double yMin, double xMax, double yMax)
Sets the rectangle from four points.
Definition: qgsrectangle.h:118
QgsRectangle(const QgsPointXY &p1, const QgsPointXY &p2) SIP_HOLDGIL
Construct a rectangle from two points. The rectangle is normalized after construction.
Definition: qgsrectangle.h:59
double area() const SIP_HOLDGIL
Returns the area of the rectangle.
Definition: qgsrectangle.h:218
bool operator!=(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:501
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:468
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:447
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:135
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:130
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
void grow(double delta)
Grows the rectangle in place by the specified amount.
Definition: qgsrectangle.h:275
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:145
bool operator==(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:489
void set(const QgsPointXY &p1, const QgsPointXY &p2)
Sets the rectangle from two QgsPoints.
Definition: qgsrectangle.h:105
~QgsRectangle()=default
void setMinimal() SIP_HOLDGIL
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:151
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:359
QgsRectangle & operator=(const QgsRectangle &r1)
Assignment operator.
Definition: qgsrectangle.h:510
void normalize()
Normalize the rectangle so it has non-negative width/height.
Definition: qgsrectangle.h:182
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:437
bool contains(const QgsPointXY &p) const
Returns true when rectangle contains a point.
Definition: qgsrectangle.h:350
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:304
void scale(double scaleFactor, double centerX, double centerY)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:255
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:312
QgsRectangle(const QgsRectangle &other) SIP_HOLDGIL
Copy constructor.
Definition: qgsrectangle.h:74
void invert()
Swap x/y coordinates in the rectangle.
Definition: qgsrectangle.h:543
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:527
double distance(const QgsPointXY &point) const
Returns the distance from point to the nearest point on the boundary of the rectangle.
Definition: qgsrectangle.h:402
double perimeter() const SIP_HOLDGIL
Returns the perimeter of the rectangle.
Definition: qgsrectangle.h:225
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
A class to represent a 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:316
#define SIP_HOLDGIL
Definition: qgis_sip.h:157
QgsInterval operator-(const QDateTime &dt1, const QDateTime &dt2)
Returns the interval between two datetimes.
QDateTime operator+(const QDateTime &start, const QgsInterval &interval)
Adds an interval to a datetime.
Q_DECLARE_METATYPE(QgsMeshTimeSettings)
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