QGIS API Documentation 3.27.0-Master (75dc696944)
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
27class QString;
28class QRectF;
29class QgsBox3d;
30#include "qgspointxy.h"
31
32
41class 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
107 static QgsRectangle fromWkt( const QString &wkt );
108
114 static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
115
122 void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
123 {
124 mXmin = p1.x();
125 mXmax = p2.x();
126 mYmin = p1.y();
127 mYmax = p2.y();
128 if ( normalize )
130 }
131
138 void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
139 {
140 mXmin = xMin;
141 mYmin = yMin;
142 mXmax = xMax;
143 mYmax = yMax;
144 if ( normalize )
146 }
147
151 void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
152
156 void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
157
161 void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
162
166 void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
167
173 {
174 mXmin = std::numeric_limits<double>::max();
175 mYmin = std::numeric_limits<double>::max();
176 mXmax = -std::numeric_limits<double>::max();
177 mYmax = -std::numeric_limits<double>::max();
178 }
179
183 double xMaximum() const SIP_HOLDGIL { return mXmax; }
184
188 double xMinimum() const SIP_HOLDGIL { return mXmin; }
189
193 double yMaximum() const SIP_HOLDGIL { return mYmax; }
194
198 double yMinimum() const SIP_HOLDGIL { return mYmin; }
199
204 {
205 if ( isNull() )
206 return;
207
208 if ( mXmin > mXmax )
209 {
210 std::swap( mXmin, mXmax );
211 }
212 if ( mYmin > mYmax )
213 {
214 std::swap( mYmin, mYmax );
215 }
216 }
217
223 double width() const SIP_HOLDGIL { return mXmax - mXmin; }
224
230 double height() const SIP_HOLDGIL { return mYmax - mYmin; }
231
239 double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
240
246 double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
247
251 QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
252
256 void scale( double scaleFactor, const QgsPointXY *c = nullptr )
257 {
258 // scale from the center
259 double centerX, centerY;
260 if ( c )
261 {
262 centerX = c->x();
263 centerY = c->y();
264 }
265 else
266 {
267 centerX = mXmin + width() / 2;
268 centerY = mYmin + height() / 2;
269 }
270 scale( scaleFactor, centerX, centerY );
271 }
272
276 void scale( double scaleFactor, double centerX, double centerY )
277 {
278 const double newWidth = width() * scaleFactor;
279 const double newHeight = height() * scaleFactor;
280 mXmin = centerX - newWidth / 2.0;
281 mXmax = centerX + newWidth / 2.0;
282 mYmin = centerY - newHeight / 2.0;
283 mYmax = centerY + newHeight / 2.0;
284 }
285
290 QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
291
296 void grow( double delta )
297 {
298 mXmin -= delta;
299 mXmax += delta;
300 mYmin -= delta;
301 mYmax += delta;
302 }
303
307 void include( const QgsPointXY &p )
308 {
309 if ( p.x() < xMinimum() )
310 setXMinimum( p.x() );
311 if ( p.x() > xMaximum() )
312 setXMaximum( p.x() );
313 if ( p.y() < yMinimum() )
314 setYMinimum( p.y() );
315 if ( p.y() > yMaximum() )
316 setYMaximum( p.y() );
317 }
318
325 QgsRectangle buffered( double width ) const
326 {
327 return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
328 }
329
334 {
335 QgsRectangle intersection = QgsRectangle();
336 if ( intersects( rect ) )
337 {
338 intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
339 intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
340 intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
341 intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
342 }
343 return intersection;
344 }
345
349 bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
350 {
351 const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
352 const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
353 if ( x1 > x2 )
354 return false;
355 const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
356 const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
357 return y1 <= y2;
358 }
359
363 bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
364 {
365 return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
366 }
367
371 bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
372 {
373 return mXmin <= p.x() && p.x() <= mXmax &&
374 mYmin <= p.y() && p.y() <= mYmax;
375 }
376
382 bool contains( double x, double y ) const SIP_HOLDGIL
383 {
384 return mXmin <= x && x <= mXmax &&
385 mYmin <= y && y <= mYmax;
386 }
387
391 void combineExtentWith( const QgsRectangle &rect )
392 {
393 if ( isNull() )
394 *this = rect;
395 else if ( !rect.isNull() )
396 {
397 mXmin = std::min( mXmin, rect.xMinimum() );
398 mXmax = std::max( mXmax, rect.xMaximum() );
399 mYmin = std::min( mYmin, rect.yMinimum() );
400 mYmax = std::max( mYmax, rect.yMaximum() );
401 }
402 }
403
407 void combineExtentWith( double x, double y )
408 {
409 if ( isNull() )
410 *this = QgsRectangle( x, y, x, y );
411 else
412 {
413 mXmin = ( ( mXmin < x ) ? mXmin : x );
414 mXmax = ( ( mXmax > x ) ? mXmax : x );
415
416 mYmin = ( ( mYmin < y ) ? mYmin : y );
417 mYmax = ( ( mYmax > y ) ? mYmax : y );
418 }
419 }
420
425 void combineExtentWith( const QgsPointXY &point )
426 {
427 combineExtentWith( point.x(), point.y() );
428 }
429
434 double distance( const QgsPointXY &point ) const
435 {
436 const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
437 const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
438 return std::sqrt( dx * dx + dy * dy );
439 }
440
446
452
457 QgsRectangle &operator-=( QgsVector v );
458
463 QgsRectangle &operator+=( QgsVector v );
464
469 bool isEmpty() const
470 {
471 return mXmax < mXmin || mYmax < mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
472 }
473
479 bool isNull() const
480 {
481 // rectangle created QgsRectangle() or with rect.setMinimal() ?
482 return ( qgsDoubleNear( mXmin, 0.0 ) && qgsDoubleNear( mXmax, 0.0 ) && qgsDoubleNear( mYmin, 0.0 ) && qgsDoubleNear( mYmax, 0.0 ) ) ||
483 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
484 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
485 }
486
490 QString asWktCoordinates() const;
491
495 QString asWktPolygon() const;
496
500 QRectF toRectF() const
501 {
502 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
503 }
504
510 QString toString( int precision = 16 ) const;
511
515 QString asPolygon() const;
516
521 bool operator==( const QgsRectangle &r1 ) const
522 {
523 return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
524 qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
525 qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
526 qgsDoubleNear( r1.yMinimum(), yMinimum() );
527 }
528
533 bool operator!=( const QgsRectangle &r1 ) const
534 {
535 return ( ! operator==( r1 ) );
536 }
537
543 {
544 if ( &r1 != this )
545 {
546 mXmax = r1.xMaximum();
547 mXmin = r1.xMinimum();
548 mYmax = r1.yMaximum();
549 mYmin = r1.yMinimum();
550 }
551
552 return *this;
553 }
554
559 bool isFinite() const
560 {
561 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
562 {
563 return false;
564 }
565 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
566 {
567 return false;
568 }
569 return true;
570 }
571
575 void invert()
576 {
577 std::swap( mXmin, mYmin );
578 std::swap( mXmax, mYmax );
579 }
580
586 QgsBox3d toBox3d( double zMin, double zMax ) const;
587
589 operator QVariant() const
590 {
591 return QVariant::fromValue( *this );
592 }
593
600 QgsRectangle snappedToGrid( double spacing ) const;
601
602#ifdef SIP_RUN
603 SIP_PYOBJECT __repr__();
604 % MethodCode
605 QString str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
606 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
607 % End
608#endif
609
610 private:
611
612 double mXmin = 0.0;
613 double mYmin = 0.0;
614 double mXmax = 0.0;
615 double mYmax = 0.0;
616
617};
618
620
621#ifndef SIP_RUN
622
626CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
627
631CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
632
633inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
634{
635 return os << r.toString().toLocal8Bit().data();
636}
637
638#endif
639
640#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:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
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:256
void combineExtentWith(const QgsPointXY &point)
Expands the rectangle so that it covers both the original rectangle and the given point.
Definition: qgsrectangle.h:425
QgsRectangle()=default
Constructor for a null rectangle.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
bool contains(const QgsPointXY &p) const SIP_HOLDGIL
Returns true when rectangle contains a point.
Definition: qgsrectangle.h:371
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
Definition: qgsrectangle.h:307
bool intersects(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle intersects with other rectangle.
Definition: qgsrectangle.h:349
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
void combineExtentWith(double x, double y)
Expands the rectangle so that it covers both the original rectangle and the given point.
Definition: qgsrectangle.h:407
QgsRectangle(const QRectF &qRectF) SIP_HOLDGIL
Construct a rectangle from a QRectF.
Definition: qgsrectangle.h:80
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:161
double area() const SIP_HOLDGIL
Returns the area of the rectangle.
Definition: qgsrectangle.h:239
bool operator!=(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:533
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:500
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:156
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:151
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsRectangle & operator=(const QgsRectangle &r1)
Assignment operator.
Definition: qgsrectangle.h:542
void set(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Sets the rectangle from two QgsPoints.
Definition: qgsrectangle.h:122
QgsRectangle(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true) SIP_HOLDGIL
Construct a rectangle from two points.
Definition: qgsrectangle.h:70
void grow(double delta)
Grows the rectangle in place by the specified amount.
Definition: qgsrectangle.h:296
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:166
QgsRectangle(double xMin, double yMin=0, double xMax=0, double yMax=0, bool normalize=true) SIP_HOLDGIL
Constructs a QgsRectangle from a set of x and y minimum and maximum coordinates.
Definition: qgsrectangle.h:54
bool operator==(const QgsRectangle &r1) const
Comparison operator.
Definition: qgsrectangle.h:521
~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:172
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
void set(double xMin, double yMin, double xMax, double yMax, bool normalize=true)
Sets the rectangle from four points.
Definition: qgsrectangle.h:138
void normalize()
Normalize the rectangle so it has non-negative width/height.
Definition: qgsrectangle.h:203
bool contains(double x, double y) const SIP_HOLDGIL
Returns true when rectangle contains the point at (x, y).
Definition: qgsrectangle.h:382
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:325
void scale(double scaleFactor, double centerX, double centerY)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:276
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:333
QgsRectangle(const QgsRectangle &other) SIP_HOLDGIL
Copy constructor.
Definition: qgsrectangle.h:89
void invert()
Swap x/y coordinates in the rectangle.
Definition: qgsrectangle.h:575
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:363
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:559
double distance(const QgsPointXY &point) const
Returns the distance from point to the nearest point on the boundary of the rectangle.
Definition: qgsrectangle.h:434
double perimeter() const SIP_HOLDGIL
Returns the perimeter of the rectangle.
Definition: qgsrectangle.h:246
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
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:37
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2404
#define SIP_HOLDGIL
Definition: qgis_sip.h:166
Q_DECLARE_METATYPE(QgsDatabaseQueryLogEntry)
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.
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