QGIS API Documentation  3.5.0-Master (bc98f86)
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 <iosfwd>
23 #include <QDomDocument>
24 #include <QRectF>
25 
26 class QString;
27 class QRectF;
28 class QgsBox3d;
29 #include "qgspointxy.h"
30 
31 
40 class CORE_EXPORT QgsRectangle
41 {
42  public:
43 
45  QgsRectangle() = default; // optimised constructor for null rectangle - no need to call normalize here
46 
48  explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0 )
49  : mXmin( xMin )
50  , mYmin( yMin )
51  , mXmax( xMax )
52  , mYmax( yMax )
53  {
54  normalize();
55  }
56 
58  QgsRectangle( const QgsPointXY &p1, const QgsPointXY &p2 )
59  {
60  set( p1, p2 );
61  }
62 
64  QgsRectangle( const QRectF &qRectF )
65  {
66  mXmin = qRectF.topLeft().x();
67  mYmin = qRectF.topLeft().y();
68  mXmax = qRectF.bottomRight().x();
69  mYmax = qRectF.bottomRight().y();
70  }
71 
73  QgsRectangle( const QgsRectangle &other )
74  {
75  mXmin = other.xMinimum();
76  mYmin = other.yMinimum();
77  mXmax = other.xMaximum();
78  mYmax = other.yMaximum();
79  }
80 
81  // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
82  // because this class MUST be lightweight and we don't want the cost of the vtable here.
83  // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
84  ~QgsRectangle() = default;
85 
91  static QgsRectangle fromWkt( const QString &wkt );
92 
98  static QgsRectangle fromCenterAndSize( QgsPointXY center, double width, double height );
99 
104  void set( const QgsPointXY &p1, const QgsPointXY &p2 )
105  {
106  mXmin = p1.x();
107  mXmax = p2.x();
108  mYmin = p1.y();
109  mYmax = p2.y();
110  normalize();
111  }
112 
117  void set( double xMin, double yMin, double xMax, double yMax )
118  {
119  mXmin = xMin;
120  mYmin = yMin;
121  mXmax = xMax;
122  mYmax = yMax;
123  normalize();
124  }
125 
129  void setXMinimum( double x ) { mXmin = x; }
130 
134  void setXMaximum( double x ) { mXmax = x; }
135 
139  void setYMinimum( double y ) { mYmin = y; }
140 
144  void setYMaximum( double y ) { mYmax = y; }
145 
150  void setMinimal()
151  {
152  mXmin = std::numeric_limits<double>::max();
153  mYmin = std::numeric_limits<double>::max();
154  mXmax = -std::numeric_limits<double>::max();
155  mYmax = -std::numeric_limits<double>::max();
156  }
157 
161  double xMaximum() const { return mXmax; }
162 
166  double xMinimum() const { return mXmin; }
167 
171  double yMaximum() const { return mYmax; }
172 
176  double yMinimum() const { return mYmin; }
177 
181  void normalize()
182  {
183  if ( isNull() )
184  return;
185 
186  if ( mXmin > mXmax )
187  {
188  std::swap( mXmin, mXmax );
189  }
190  if ( mYmin > mYmax )
191  {
192  std::swap( mYmin, mYmax );
193  }
194  }
195 
201  double width() const { return mXmax - mXmin; }
202 
208  double height() const { return mYmax - mYmin; }
209 
217  double area() const { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
218 
224  double perimeter() const { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
225 
229  QgsPointXY center() const { return QgsPointXY( mXmin + width() / 2, mYmin + height() / 2 ); }
230 
234  void scale( double scaleFactor, const QgsPointXY *c = nullptr )
235  {
236  // scale from the center
237  double centerX, centerY;
238  if ( c )
239  {
240  centerX = c->x();
241  centerY = c->y();
242  }
243  else
244  {
245  centerX = mXmin + width() / 2;
246  centerY = mYmin + height() / 2;
247  }
248  scale( scaleFactor, centerX, centerY );
249  }
250 
254  void scale( double scaleFactor, double centerX, double centerY )
255  {
256  double newWidth = width() * scaleFactor;
257  double newHeight = height() * scaleFactor;
258  mXmin = centerX - newWidth / 2.0;
259  mXmax = centerX + newWidth / 2.0;
260  mYmin = centerY - newHeight / 2.0;
261  mYmax = centerY + newHeight / 2.0;
262  }
263 
268  QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
269 
274  void grow( double delta )
275  {
276  mXmin -= delta;
277  mXmax += delta;
278  mYmin -= delta;
279  mYmax += delta;
280  }
281 
285  void include( const QgsPointXY &p )
286  {
287  if ( p.x() < xMinimum() )
288  setXMinimum( p.x() );
289  else if ( p.x() > xMaximum() )
290  setXMaximum( p.x() );
291  if ( p.y() < yMinimum() )
292  setYMinimum( p.y() );
293  if ( p.y() > yMaximum() )
294  setYMaximum( p.y() );
295  }
296 
303  QgsRectangle buffered( double width ) const
304  {
305  return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
306  }
307 
311  QgsRectangle intersect( const QgsRectangle &rect ) const
312  {
313  QgsRectangle intersection = QgsRectangle();
314  if ( intersects( rect ) )
315  {
316  intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
317  intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
318  intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
319  intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
320  }
321  return intersection;
322  }
323 
327  bool intersects( const QgsRectangle &rect ) const
328  {
329  double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
330  double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
331  if ( x1 > x2 )
332  return false;
333  double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
334  double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
335  return y1 <= y2;
336  }
337 
341  bool contains( const QgsRectangle &rect ) const
342  {
343  return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
344  }
345 
349  bool contains( const QgsPointXY &p ) const
350  {
351  return mXmin <= p.x() && p.x() <= mXmax &&
352  mYmin <= p.y() && p.y() <= mYmax;
353  }
354 
358  void combineExtentWith( const QgsRectangle &rect )
359  {
360  if ( isNull() )
361  *this = rect;
362  else if ( !rect.isNull() )
363  {
364  mXmin = std::min( mXmin, rect.xMinimum() );
365  mXmax = std::max( mXmax, rect.xMaximum() );
366  mYmin = std::min( mYmin, rect.yMinimum() );
367  mYmax = std::max( mYmax, rect.yMaximum() );;
368  }
369  }
370 
374  void combineExtentWith( double x, double y )
375  {
376  if ( isNull() )
377  *this = QgsRectangle( x, y, x, y );
378  else
379  {
380  mXmin = ( ( mXmin < x ) ? mXmin : x );
381  mXmax = ( ( mXmax > x ) ? mXmax : x );
382 
383  mYmin = ( ( mYmin < y ) ? mYmin : y );
384  mYmax = ( ( mYmax > y ) ? mYmax : y );
385  }
386  }
387 
392  void combineExtentWith( const QgsPointXY &point )
393  {
394  combineExtentWith( point.x(), point.y() );
395  }
396 
401  QgsRectangle operator-( QgsVector v ) const;
402 
407  QgsRectangle operator+( QgsVector v ) const;
408 
413  QgsRectangle &operator-=( QgsVector v );
414 
419  QgsRectangle &operator+=( QgsVector v );
420 
425  bool isEmpty() const
426  {
427  return mXmax < mXmin || mYmax < mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
428  }
429 
435  bool isNull() const
436  {
437  // rectangle created QgsRectangle() or with rect.setMinimal() ?
438  return ( qgsDoubleNear( mXmin, 0.0 ) && qgsDoubleNear( mXmax, 0.0 ) && qgsDoubleNear( mYmin, 0.0 ) && qgsDoubleNear( mYmax, 0.0 ) ) ||
439  ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
440  qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
441  }
442 
446  QString asWktCoordinates() const;
447 
451  QString asWktPolygon() const;
452 
456  QRectF toRectF() const
457  {
458  return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
459  }
460 
466  QString toString( int precision = 16 ) const;
467 
471  QString asPolygon() const;
472 
477  bool operator==( const QgsRectangle &r1 ) const
478  {
479  return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
480  qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
481  qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
482  qgsDoubleNear( r1.yMinimum(), yMinimum() );
483  }
484 
489  bool operator!=( const QgsRectangle &r1 ) const
490  {
491  return ( ! operator==( r1 ) );
492  }
493 
499  {
500  if ( &r1 != this )
501  {
502  mXmax = r1.xMaximum();
503  mXmin = r1.xMinimum();
504  mYmax = r1.yMaximum();
505  mYmin = r1.yMinimum();
506  }
507 
508  return *this;
509  }
510 
515  bool isFinite() const
516  {
517  if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
518  {
519  return false;
520  }
521  if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
522  {
523  return false;
524  }
525  return true;
526  }
527 
531  void invert()
532  {
533  std::swap( mXmin, mYmin );
534  std::swap( mXmax, mYmax );
535  }
536 
542  QgsBox3d toBox3d( double zMin, double zMax ) const;
543 
545  operator QVariant() const
546  {
547  return QVariant::fromValue( *this );
548  }
549 
556  QgsRectangle snappedToGrid( double spacing ) const;
557 
558 #ifdef SIP_RUN
559  SIP_PYOBJECT __repr__();
560  % MethodCode
561  QString str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
562  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
563  % End
564 #endif
565 
566  private:
567 
568  double mXmin = 0.0;
569  double mYmin = 0.0;
570  double mXmax = 0.0;
571  double mYmax = 0.0;
572 
573 };
574 
576 
577 #ifndef SIP_RUN
578 
582 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
583 
587 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
588 
589 inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
590 {
591  return os << r.toString().toLocal8Bit().data();
592 }
593 
594 #endif
595 
596 #endif // QGSRECTANGLE_H
QgsRectangle(const QgsPointXY &p1, const QgsPointXY &p2)
Construct a rectangle from two points. The rectangle is normalized after construction.
Definition: qgsrectangle.h:58
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:341
int precision
A rectangle specified with double values.
Definition: qgsrectangle.h:40
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:150
QgsRectangle(const QRectF &qRectF)
Construct a rectangle from a QRectF. The rectangle is normalized after construction.
Definition: qgsrectangle.h:64
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:134
void combineExtentWith(const QgsPointXY &point)
Expands the rectangle so that it covers both the original rectangle and the given point...
Definition: qgsrectangle.h:392
double y
Definition: qgspointxy.h:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:234
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:278
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
Definition: qgsrectangle.h:285
double perimeter() const
Returns the perimeter of the rectangle.
Definition: qgsrectangle.h:224
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:36
Q_DECLARE_METATYPE(QModelIndex)
CORE_EXPORT QDataStream & operator<<(QDataStream &out, const QgsRectangle &rectangle)
Writes the list rectangle to stream out.
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
QgsRectangle & operator=(const QgsRectangle &r1)
Assignment operator.
Definition: qgsrectangle.h:498
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:303
void grow(double delta)
Grows the rectangle in place by the specified amount.
Definition: qgsrectangle.h:274
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:425
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:201
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:139
bool contains(const QgsPointXY &p) const
Returns true when rectangle contains a point.
Definition: qgsrectangle.h:349
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:311
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
QDateTime operator+(const QDateTime &start, QgsInterval interval)
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:515
double x
Definition: qgspointxy.h:47
A class to represent a vector.
Definition: qgsvector.h:28
QgsInterval operator-(const QDateTime &dt1, const QDateTime &dt2)
Returns the interval between two datetimes.
double area() const
Returns the area of the rectangle.
Definition: qgsrectangle.h:217
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:176
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:161
QgsRectangle(double xMin, double yMin=0, double xMax=0, double yMax=0)
Constructor.
Definition: qgsrectangle.h:48
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
Definition: qgsrectangle.h:358
bool operator==(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:477
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:456
CORE_EXPORT QDataStream & operator>>(QDataStream &in, QgsRectangle &rectangle)
Reads a rectangle from stream in into rectangle.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:144
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:435
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:166
void combineExtentWith(double x, double y)
Expands the rectangle so that it covers both the original rectangle and the given point...
Definition: qgsrectangle.h:374
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:171
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:229
void normalize()
Normalize the rectangle so it has non-negative width/height.
Definition: qgsrectangle.h:181
QgsRectangle(const QgsRectangle &other)
Copy constructor.
Definition: qgsrectangle.h:73
bool operator!=(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:489
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
Definition: qgsrectangle.h:327
void scale(double scaleFactor, double centerX, double centerY)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:254
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:129
void invert()
Swap x/y coordinates in the rectangle.
Definition: qgsrectangle.h:531
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:208