QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
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 
54  explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0, bool normalize = true ) SIP_HOLDGIL
55  : mXmin( xMin )
56  , mYmin( yMin )
57  , mXmax( xMax )
58  , mYmax( yMax )
59  {
60  if ( normalize )
62  }
63 
70  QgsRectangle( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true ) SIP_HOLDGIL
71  {
72  set( p1, p2, normalize );
73  }
74 
80  QgsRectangle( const QRectF &qRectF ) SIP_HOLDGIL
81  {
82  mXmin = qRectF.topLeft().x();
83  mYmin = qRectF.topLeft().y();
84  mXmax = qRectF.bottomRight().x();
85  mYmax = qRectF.bottomRight().y();
86  }
87 
90  {
91  mXmin = other.xMinimum();
92  mYmin = other.yMinimum();
93  mXmax = other.xMaximum();
94  mYmax = other.yMaximum();
95  }
96 
97  // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
98  // because this class MUST be lightweight and we don't want the cost of the vtable here.
99  // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
100  ~QgsRectangle() = default;
101 
106  static QgsRectangle fromWkt( const QString &wkt );
107 
112  static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
113 
120  void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
121  {
122  mXmin = p1.x();
123  mXmax = p2.x();
124  mYmin = p1.y();
125  mYmax = p2.y();
126  if ( normalize )
128  }
129 
136  void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
137  {
138  mXmin = xMin;
139  mYmin = yMin;
140  mXmax = xMax;
141  mYmax = yMax;
142  if ( normalize )
144  }
145 
149  void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
150 
154  void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
155 
159  void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
160 
164  void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
165 
177  {
178  mXmin = mYmin = std::numeric_limits<double>::max();
179  mXmax = mYmax = -std::numeric_limits<double>::max();
180  }
181 
188  Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
189  {
190  setNull();
191  }
192 
196  double xMaximum() const SIP_HOLDGIL { return mXmax; }
197 
201  double xMinimum() const SIP_HOLDGIL { return mXmin; }
202 
206  double yMaximum() const SIP_HOLDGIL { return mYmax; }
207 
211  double yMinimum() const SIP_HOLDGIL { return mYmin; }
212 
216  void normalize()
217  {
218  if ( isNull() )
219  return;
220 
221  if ( mXmin > mXmax )
222  {
223  std::swap( mXmin, mXmax );
224  }
225  if ( mYmin > mYmax )
226  {
227  std::swap( mYmin, mYmax );
228  }
229  }
230 
236  double width() const SIP_HOLDGIL { return mXmax - mXmin; }
237 
243  double height() const SIP_HOLDGIL { return mYmax - mYmin; }
244 
251  double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
252 
257  double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
258 
262  QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
263 
267  void scale( double scaleFactor, const QgsPointXY *c = nullptr )
268  {
269  // scale from the center
270  double centerX, centerY;
271  if ( c )
272  {
273  centerX = c->x();
274  centerY = c->y();
275  }
276  else
277  {
278  centerX = mXmin + width() / 2;
279  centerY = mYmin + height() / 2;
280  }
281  scale( scaleFactor, centerX, centerY );
282  }
283 
287  void scale( double scaleFactor, double centerX, double centerY )
288  {
289  const double newWidth = width() * scaleFactor;
290  const double newHeight = height() * scaleFactor;
291  mXmin = centerX - newWidth / 2.0;
292  mXmax = centerX + newWidth / 2.0;
293  mYmin = centerY - newHeight / 2.0;
294  mYmax = centerY + newHeight / 2.0;
295  }
296 
301  QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
302 
307  void grow( double delta )
308  {
309  if ( isNull() )
310  return;
311  mXmin -= delta;
312  mXmax += delta;
313  mYmin -= delta;
314  mYmax += delta;
315  }
316 
320  void include( const QgsPointXY &p )
321  {
322  if ( isNull() )
323  {
324  setXMinimum( p.x() );
325  setXMaximum( p.x() );
326  setYMinimum( p.y() );
327  setYMaximum( p.y() );
328  return;
329  }
330  if ( p.x() < xMinimum() )
331  setXMinimum( p.x() );
332  if ( p.x() > xMaximum() )
333  setXMaximum( p.x() );
334  if ( p.y() < yMinimum() )
335  setYMinimum( p.y() );
336  if ( p.y() > yMaximum() )
337  setYMaximum( p.y() );
338  }
339 
345  QgsRectangle buffered( double width ) const
346  {
347  if ( isNull() )
348  return QgsRectangle();
349  return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
350  }
351 
355  QgsRectangle intersect( const QgsRectangle &rect ) const
356  {
357  QgsRectangle intersection = QgsRectangle();
358  if ( intersects( rect ) )
359  {
360  intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
361  intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
362  intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
363  intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
364  }
365  return intersection;
366  }
367 
371  bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
372  {
373  const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
374  const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
375  if ( x1 > x2 )
376  return false;
377  const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
378  const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
379  return y1 <= y2;
380  }
381 
385  bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
386  {
387  return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
388  }
389 
393  bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
394  {
395  return mXmin <= p.x() && p.x() <= mXmax &&
396  mYmin <= p.y() && p.y() <= mYmax;
397  }
398 
404  bool contains( double x, double y ) const SIP_HOLDGIL
405  {
406  return mXmin <= x && x <= mXmax &&
407  mYmin <= y && y <= mYmax;
408  }
409 
413  void combineExtentWith( const QgsRectangle &rect )
414  {
415  if ( isNull() )
416  *this = rect;
417  else if ( !rect.isNull() )
418  {
419  mXmin = std::min( mXmin, rect.xMinimum() );
420  mXmax = std::max( mXmax, rect.xMaximum() );
421  mYmin = std::min( mYmin, rect.yMinimum() );
422  mYmax = std::max( mYmax, rect.yMaximum() );
423  }
424  }
425 
429  void combineExtentWith( double x, double y )
430  {
431  if ( isNull() )
432  *this = QgsRectangle( x, y, x, y );
433  else
434  {
435  mXmin = ( ( mXmin < x ) ? mXmin : x );
436  mXmax = ( ( mXmax > x ) ? mXmax : x );
437 
438  mYmin = ( ( mYmin < y ) ? mYmin : y );
439  mYmax = ( ( mYmax > y ) ? mYmax : y );
440  }
441  }
442 
447  void combineExtentWith( const QgsPointXY &point )
448  {
449  combineExtentWith( point.x(), point.y() );
450  }
451 
456  double distance( const QgsPointXY &point ) const
457  {
458  const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
459  const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
460  return std::sqrt( dx * dx + dy * dy );
461  }
462 
466  QgsRectangle operator-( QgsVector v ) const;
467 
471  QgsRectangle operator+( QgsVector v ) const;
472 
476  QgsRectangle &operator-=( QgsVector v );
477 
481  QgsRectangle &operator+=( QgsVector v );
482 
492  bool isEmpty() const
493  {
494  return isNull() || mXmax <= mXmin || mYmax <= mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
495  }
496 
505  bool isNull() const
506  {
507  // rectangle created QgsRectangle() or with rect.setNull() or
508  // otherwise having NaN ordinates
509  return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
510  ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
511  qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
512  }
513 
517  QString asWktCoordinates() const;
518 
522  QString asWktPolygon() const;
523 
527  QRectF toRectF() const
528  {
529  return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
530  }
531 
537  QString toString( int precision = 16 ) const;
538 
542  QString asPolygon() const;
543 
548  bool operator==( const QgsRectangle &r1 ) const
549  {
550  if ( isNull() ) return r1.isNull();
551 
552  return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
553  qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
554  qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
555  qgsDoubleNear( r1.yMinimum(), yMinimum() );
556  }
557 
562  bool operator!=( const QgsRectangle &r1 ) const
563  {
564  return ( ! operator==( r1 ) );
565  }
566 
572  {
573  if ( &r1 != this )
574  {
575  mXmax = r1.xMaximum();
576  mXmin = r1.xMinimum();
577  mYmax = r1.yMaximum();
578  mYmin = r1.yMinimum();
579  }
580 
581  return *this;
582  }
583 
588  bool isFinite() const
589  {
590  if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
591  {
592  return false;
593  }
594  if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
595  {
596  return false;
597  }
598  return true;
599  }
600 
604  void invert()
605  {
606  std::swap( mXmin, mYmin );
607  std::swap( mXmax, mYmax );
608  }
609 
614  QgsBox3D toBox3d( double zMin, double zMax ) const;
615 
617  operator QVariant() const
618  {
619  return QVariant::fromValue( *this );
620  }
621 
628  QgsRectangle snappedToGrid( double spacing ) const;
629 
630 #ifdef SIP_RUN
631  SIP_PYOBJECT __repr__();
632  % MethodCode
633  QString str;
634  if ( sipCpp->isNull() )
635  str = QStringLiteral( "<QgsRectangle()>" );
636  else
637  str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
638  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
639  % End
640 #endif
641 
642  private:
643 
644  double mXmin = std::numeric_limits<double>::max();
645  double mYmin = std::numeric_limits<double>::max();
646  double mXmax = -std::numeric_limits<double>::max();
647  double mYmax = -std::numeric_limits<double>::max();
648 
649 };
650 
652 
653 #ifndef SIP_RUN
654 
658 CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
659 
663 CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
664 
665 inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
666 {
667  return os << r.toString().toLocal8Bit().data();
668 }
669 
670 #endif
671 
672 #endif // QGSRECTANGLE_H
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:43
A class to represent a 2D point.
Definition: qgspointxy.h:60
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsRectangle(double xMin, double yMin=0, double xMax=0, double yMax=0, bool normalize=true)
Constructs a QgsRectangle from a set of x and y minimum and maximum coordinates.
Definition: qgsrectangle.h:54
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:267
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:385
Q_DECL_DEPRECATED void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:188
void combineExtentWith(const QgsPointXY &point)
Expands the rectangle so that it covers both the original rectangle and the given point.
Definition: qgsrectangle.h:447
QgsRectangle()=default
Constructor for a null rectangle.
double area() const
Returns the area of the rectangle.
Definition: qgsrectangle.h:251
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
Definition: qgsrectangle.h:320
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:201
void combineExtentWith(double x, double y)
Expands the rectangle so that it covers both the original rectangle and the given point.
Definition: qgsrectangle.h:429
QgsRectangle(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Construct a rectangle from two points.
Definition: qgsrectangle.h:70
bool contains(double x, double y) const
Returns true when rectangle contains the point at (x, y).
Definition: qgsrectangle.h:404
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:159
bool intersects(const QgsRectangle &rect) const
Returns true when rectangle intersects with other rectangle.
Definition: qgsrectangle.h:371
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:211
bool operator!=(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:562
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:149
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:236
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:527
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:196
bool isNull() const
Test if the rectangle is null (holding no spatial information).
Definition: qgsrectangle.h:505
QgsRectangle(const QgsRectangle &other)
Copy constructor.
Definition: qgsrectangle.h:89
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:206
void set(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Sets the rectangle from two QgsPoints.
Definition: qgsrectangle.h:120
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:164
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:262
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:154
void grow(double delta)
Grows the rectangle in place by the specified amount.
Definition: qgsrectangle.h:307
bool operator==(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:548
~QgsRectangle()=default
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:413
double perimeter() const
Returns the perimeter of the rectangle.
Definition: qgsrectangle.h:257
void set(double xMin, double yMin, double xMax, double yMax, bool normalize=true)
Sets the rectangle from four points.
Definition: qgsrectangle.h:136
QgsRectangle & operator=(const QgsRectangle &r1)
Assignment operator.
Definition: qgsrectangle.h:571
void normalize()
Normalize the rectangle so it has non-negative width/height.
Definition: qgsrectangle.h:216
bool isEmpty() const
Returns true if the rectangle has no area.
Definition: qgsrectangle.h:492
QgsRectangle(const QRectF &qRectF)
Construct a rectangle from a QRectF.
Definition: qgsrectangle.h:80
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:243
void setNull()
Mark a rectangle as being null (holding no spatial information).
Definition: qgsrectangle.h:176
bool contains(const QgsPointXY &p) const
Returns true when rectangle contains a point.
Definition: qgsrectangle.h:393
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:345
void scale(double scaleFactor, double centerX, double centerY)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:287
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:355
void invert()
Swap x/y coordinates in the rectangle.
Definition: qgsrectangle.h:604
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:588
double distance(const QgsPointXY &point) const
Returns the distance from point to the nearest point on the boundary of the rectangle.
Definition: qgsrectangle.h:456
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
#define str(x)
Definition: qgis.cpp:38
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5172
#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