QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
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
23#include "qgis.h"
24#include "qgis_core.h"
25#include "qgspointxy.h"
26
27#include <QDomDocument>
28#include <QRectF>
29#include <QString>
30
31using namespace Qt::StringLiterals;
32
33class QString;
34class QRectF;
35class QgsBox3D;
36
37
46class CORE_EXPORT QgsRectangle
47{
48 Q_GADGET
49
50 Q_PROPERTY( double xMinimum READ xMinimum WRITE setXMinimum )
51 Q_PROPERTY( double xMaximum READ xMaximum WRITE setXMaximum )
52 Q_PROPERTY( double yMinimum READ yMinimum WRITE setYMinimum )
53 Q_PROPERTY( double yMaximum READ yMaximum WRITE setYMaximum )
54 Q_PROPERTY( double width READ width )
55 Q_PROPERTY( double height READ height )
56 Q_PROPERTY( double area READ area )
57 Q_PROPERTY( double perimeter READ perimeter )
58 Q_PROPERTY( QgsPointXY center READ center )
59 Q_PROPERTY( bool isEmpty READ isEmpty )
60 Q_PROPERTY( bool isNull READ isNull )
61 Q_PROPERTY( bool isValid READ isValid )
62
63 public:
65 QgsRectangle() = default; // optimised constructor for null rectangle - no need to call normalize here
66
67 // clang-format off
74 explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0, bool normalize = true ) SIP_HOLDGIL
75 // clang-format on
76 : mXmin( xMin )
77 , mYmin( yMin )
78 , mXmax( xMax )
79 , mYmax( yMax )
80 {
81 if ( normalize )
83 }
84
91 QgsRectangle( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true ) SIP_HOLDGIL
92 {
93 set( p1, p2, normalize );
94 }
95
101 QgsRectangle( const QRectF &qRectF ) SIP_HOLDGIL
102 {
103 mXmin = qRectF.topLeft().x();
104 mYmin = qRectF.topLeft().y();
105 mXmax = qRectF.bottomRight().x();
106 mYmax = qRectF.bottomRight().y();
107 }
108
110 {
111 mXmin = other.xMinimum();
112 mYmin = other.yMinimum();
113 mXmax = other.xMaximum();
114 mYmax = other.yMaximum();
115 }
116
117 // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
118 // because this class MUST be lightweight and we don't want the cost of the vtable here.
119 // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
120 ~QgsRectangle() = default;
121
126 static QgsRectangle fromWkt( const QString &wkt );
127
132 static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
133
140 void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
141 {
142 mXmin = p1.x();
143 mXmax = p2.x();
144 mYmin = p1.y();
145 mYmax = p2.y();
146 if ( normalize )
148 }
149
156 void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
157 {
158 mXmin = xMin;
159 mYmin = yMin;
160 mXmax = xMax;
161 mYmax = yMax;
162 if ( normalize )
164 }
165
169 void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
170
174 void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
175
179 void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
180
184 void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
185
197 {
198 mXmin = mYmin = std::numeric_limits<double>::max();
199 mXmax = mYmax = -std::numeric_limits<double>::max();
200 }
201
208 Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
209 {
210 setNull();
211 }
212
216 double xMaximum() const SIP_HOLDGIL { return mXmax; }
217
221 double xMinimum() const SIP_HOLDGIL { return mXmin; }
222
226 double yMaximum() const SIP_HOLDGIL { return mYmax; }
227
231 double yMinimum() const SIP_HOLDGIL { return mYmin; }
232
237 {
238 if ( isNull() )
239 return;
240
241 if ( mXmin > mXmax )
242 {
243 std::swap( mXmin, mXmax );
244 }
245 if ( mYmin > mYmax )
246 {
247 std::swap( mYmin, mYmax );
248 }
249 }
250
256 double width() const SIP_HOLDGIL { return mXmax - mXmin; }
257
263 double height() const SIP_HOLDGIL { return mYmax - mYmin; }
264
271 double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
272
277 double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
278
282 QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
283
287 void scale( double scaleFactor, const QgsPointXY *c = nullptr )
288 {
289 // scale from the center
290 double centerX, centerY;
291 if ( c )
292 {
293 centerX = c->x();
294 centerY = c->y();
295 }
296 else
297 {
298 centerX = mXmin + width() / 2;
299 centerY = mYmin + height() / 2;
300 }
301 scale( scaleFactor, centerX, centerY );
302 }
303
307 void scale( double scaleFactor, double centerX, double centerY )
308 {
309 const double newWidth = width() * scaleFactor;
310 const double newHeight = height() * scaleFactor;
311 mXmin = centerX - newWidth / 2.0;
312 mXmax = centerX + newWidth / 2.0;
313 mYmin = centerY - newHeight / 2.0;
314 mYmax = centerY + newHeight / 2.0;
315 }
316
321 QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
322
327 void grow( double delta )
328 {
329 if ( isNull() )
330 return;
331 mXmin -= delta;
332 mXmax += delta;
333 mYmin -= delta;
334 mYmax += delta;
335 }
336
340 void include( const QgsPointXY &p )
341 {
342 if ( isNull() )
343 {
344 setXMinimum( p.x() );
345 setXMaximum( p.x() );
346 setYMinimum( p.y() );
347 setYMaximum( p.y() );
348 return;
349 }
350 if ( p.x() < xMinimum() )
351 setXMinimum( p.x() );
352 if ( p.x() > xMaximum() )
353 setXMaximum( p.x() );
354 if ( p.y() < yMinimum() )
355 setYMinimum( p.y() );
356 if ( p.y() > yMaximum() )
357 setYMaximum( p.y() );
358 }
359
366 {
367 if ( isNull() )
368 return QgsRectangle();
369 return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
370 }
371
376 {
377 QgsRectangle intersection = QgsRectangle();
378 if ( intersects( rect ) )
379 {
380 intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
381 intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
382 intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
383 intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
384 }
385 return intersection;
386 }
387
391 bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
392 {
393 if ( isNull() || rect.isNull() )
394 {
395 return false;
396 }
397
398 const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
399 const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
400 if ( x1 > x2 )
401 return false;
402 const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
403 const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
404 return y1 <= y2;
405 }
406
410 bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
411 {
412 return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
413 }
414
418 bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
419 {
420 return mXmin <= p.x() && p.x() <= mXmax &&
421 mYmin <= p.y() && p.y() <= mYmax;
422 }
423
429 bool contains( double x, double y ) const SIP_HOLDGIL
430 {
431 return mXmin <= x && x <= mXmax &&
432 mYmin <= y && y <= mYmax;
433 }
434
438 void combineExtentWith( const QgsRectangle &rect )
439 {
440 if ( isNull() )
441 *this = rect;
442 else if ( !rect.isNull() )
443 {
444 mXmin = std::min( mXmin, rect.xMinimum() );
445 mXmax = std::max( mXmax, rect.xMaximum() );
446 mYmin = std::min( mYmin, rect.yMinimum() );
447 mYmax = std::max( mYmax, rect.yMaximum() );
448 }
449 }
450
454 void combineExtentWith( double x, double y )
455 {
456 if ( isNull() )
457 *this = QgsRectangle( x, y, x, y );
458 else
459 {
460 mXmin = ( ( mXmin < x ) ? mXmin : x );
461 mXmax = ( ( mXmax > x ) ? mXmax : x );
462
463 mYmin = ( ( mYmin < y ) ? mYmin : y );
464 mYmax = ( ( mYmax > y ) ? mYmax : y );
465 }
466 }
467
472 void combineExtentWith( const QgsPointXY &point )
473 {
474 combineExtentWith( point.x(), point.y() );
475 }
476
481 double distance( const QgsPointXY &point ) const
482 {
483 const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
484 const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
485 return std::sqrt( dx * dx + dy * dy );
486 }
487
492
497
501 QgsRectangle &operator-=( QgsVector v );
502
506 QgsRectangle &operator+=( QgsVector v );
507
517 bool isEmpty() const
518 {
519 return isNull() || mXmax <= mXmin || mYmax <= mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
520 }
521
532 bool isNull() const
533 {
534 // rectangle created QgsRectangle() or with rect.setNull() or
535 // otherwise having NaN ordinates
536 return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
537 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
538 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
539 }
540
550 bool isValid() const
551 {
552 if ( ( !isFinite() ) || ( mXmax <= mXmin ) || ( mYmax <= mYmin ) )
553 {
554 return false;
555 }
556 return true;
557 }
558
571 bool isMaximal() const
572 {
573 return ( std::isinf( mXmin ) || mXmin == std::numeric_limits<double>::lowest() )
574 && ( std::isinf( mYmin ) || mYmin == std::numeric_limits<double>::lowest() )
575 && ( std::isinf( mXmax ) || mXmax == std::numeric_limits<double>::max() )
576 && ( std::isinf( mYmax ) || mYmax == std::numeric_limits<double>::max() );
577 }
578
582 Q_INVOKABLE QString asWktCoordinates() const;
583
587 Q_INVOKABLE QString asWktPolygon() const;
588
592 QRectF toRectF() const
593 {
594 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
595 }
596
602 Q_INVOKABLE QString toString( int precision = 16 ) const;
603
607 QString asPolygon() const;
608
609 bool operator==( const QgsRectangle &r1 ) const
610 {
611 if ( isNull() ) return r1.isNull();
612
613 return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
614 qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
615 qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
617 }
618
619 bool operator!=( const QgsRectangle &r1 ) const
620 {
621 return ( ! operator==( r1 ) );
622 }
623
625 {
626 if ( &r1 != this )
627 {
628 mXmax = r1.xMaximum();
629 mXmin = r1.xMinimum();
630 mYmax = r1.yMaximum();
631 mYmin = r1.yMinimum();
632 }
633
634 return *this;
635 }
636
645 bool isFinite() const
646 {
647 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
648 {
649 return false;
650 }
651 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
652 {
653 return false;
654 }
655 return true;
656 }
657
661 void invert()
662 {
663 std::swap( mXmin, mYmin );
664 std::swap( mXmax, mYmax );
665 }
666
671 QgsBox3D toBox3d( double zMin, double zMax ) const;
672
674 operator QVariant() const
675 {
676 return QVariant::fromValue( *this );
677 }
678
685 QgsRectangle snappedToGrid( double spacing ) const;
686
687#ifdef SIP_RUN
688// clang-format off
689 SIP_PYOBJECT __repr__();
690 % MethodCode
691 QString str;
692 if ( sipCpp->isNull() )
693 str = u"<QgsRectangle()>"_s;
694 else
695 str = u"<QgsRectangle: %1>"_s.arg( sipCpp->asWktCoordinates() );
696 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
697 % End
698// clang-format on
699#endif
700
701 private:
702
703 double mXmin = std::numeric_limits<double>::max();
704 double mYmin = std::numeric_limits<double>::max();
705 double mXmax = -std::numeric_limits<double>::max();
706 double mYmax = -std::numeric_limits<double>::max();
707
708};
709
711
712#ifndef SIP_RUN
713
717CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
718
722CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
723
724inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
725{
726 return os << r.toString().toLocal8Bit().data();
727}
728
729#endif
730
731#endif // QGSRECTANGLE_H
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:45
Represents a 2D point.
Definition qgspointxy.h:62
double y
Definition qgspointxy.h:66
double x
Definition qgspointxy.h:65
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 rounded to the spec...
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.
QgsRectangle()=default
Constructor for a null rectangle.
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).
static QgsRectangle fromWkt(const QString &wkt)
Creates a new rectangle from a wkt string.
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
bool isValid() const
Test if the rectangle is valid.
double perimeter
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.
static QgsRectangle fromCenterAndSize(const QgsPointXY &center, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
double height() const
Returns the height of the rectangle.
QgsPointXY center
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:34
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:6975
#define SIP_DEPRECATED
Definition qgis_sip.h:113
#define SIP_HOLDGIL
Definition qgis_sip.h:178
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.