QGIS API Documentation 3.41.0-Master (3440c17df1d)
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 "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 Q_GADGET
44
45 Q_PROPERTY( double xMinimum READ xMinimum WRITE setXMinimum )
46 Q_PROPERTY( double xMaximum READ xMaximum WRITE setXMaximum )
47 Q_PROPERTY( double yMinimum READ yMinimum WRITE setYMinimum )
48 Q_PROPERTY( double yMaximum READ yMaximum WRITE setYMaximum )
49 Q_PROPERTY( double width READ width )
50 Q_PROPERTY( double height READ height )
51 Q_PROPERTY( double area READ area )
52 Q_PROPERTY( double perimeter READ perimeter )
53 Q_PROPERTY( QgsPointXY center READ center )
54 Q_PROPERTY( bool isEmpty READ isEmpty )
55 Q_PROPERTY( bool isNull READ isNull )
56
57 public:
58
60 QgsRectangle() = default; // optimised constructor for null rectangle - no need to call normalize here
61
68 explicit QgsRectangle( double xMin, double yMin = 0, double xMax = 0, double yMax = 0, bool normalize = true ) SIP_HOLDGIL
69 : mXmin( xMin )
70 , mYmin( yMin )
71 , mXmax( xMax )
72 , mYmax( yMax )
73 {
74 if ( normalize )
76 }
77
84 QgsRectangle( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true ) SIP_HOLDGIL
85 {
86 set( p1, p2, normalize );
87 }
88
94 QgsRectangle( const QRectF &qRectF ) SIP_HOLDGIL
95 {
96 mXmin = qRectF.topLeft().x();
97 mYmin = qRectF.topLeft().y();
98 mXmax = qRectF.bottomRight().x();
99 mYmax = qRectF.bottomRight().y();
100 }
101
103 {
104 mXmin = other.xMinimum();
105 mYmin = other.yMinimum();
106 mXmax = other.xMaximum();
107 mYmax = other.yMaximum();
108 }
109
110 // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
111 // because this class MUST be lightweight and we don't want the cost of the vtable here.
112 // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
113 ~QgsRectangle() = default;
114
119 static QgsRectangle fromWkt( const QString &wkt );
120
125 static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
126
133 void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
134 {
135 mXmin = p1.x();
136 mXmax = p2.x();
137 mYmin = p1.y();
138 mYmax = p2.y();
139 if ( normalize )
141 }
142
149 void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
150 {
151 mXmin = xMin;
152 mYmin = yMin;
153 mXmax = xMax;
154 mYmax = yMax;
155 if ( normalize )
157 }
158
162 void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
163
167 void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
168
172 void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
173
177 void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
178
190 {
191 mXmin = mYmin = std::numeric_limits<double>::max();
192 mXmax = mYmax = -std::numeric_limits<double>::max();
193 }
194
201 Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
202 {
203 setNull();
204 }
205
209 double xMaximum() const SIP_HOLDGIL { return mXmax; }
210
214 double xMinimum() const SIP_HOLDGIL { return mXmin; }
215
219 double yMaximum() const SIP_HOLDGIL { return mYmax; }
220
224 double yMinimum() const SIP_HOLDGIL { return mYmin; }
225
230 {
231 if ( isNull() )
232 return;
233
234 if ( mXmin > mXmax )
235 {
236 std::swap( mXmin, mXmax );
237 }
238 if ( mYmin > mYmax )
239 {
240 std::swap( mYmin, mYmax );
241 }
242 }
243
249 double width() const SIP_HOLDGIL { return mXmax - mXmin; }
250
256 double height() const SIP_HOLDGIL { return mYmax - mYmin; }
257
264 double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
265
270 double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
271
275 QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
276
280 void scale( double scaleFactor, const QgsPointXY *c = nullptr )
281 {
282 // scale from the center
283 double centerX, centerY;
284 if ( c )
285 {
286 centerX = c->x();
287 centerY = c->y();
288 }
289 else
290 {
291 centerX = mXmin + width() / 2;
292 centerY = mYmin + height() / 2;
293 }
294 scale( scaleFactor, centerX, centerY );
295 }
296
300 void scale( double scaleFactor, double centerX, double centerY )
301 {
302 const double newWidth = width() * scaleFactor;
303 const double newHeight = height() * scaleFactor;
304 mXmin = centerX - newWidth / 2.0;
305 mXmax = centerX + newWidth / 2.0;
306 mYmin = centerY - newHeight / 2.0;
307 mYmax = centerY + newHeight / 2.0;
308 }
309
314 QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
315
320 void grow( double delta )
321 {
322 if ( isNull() )
323 return;
324 mXmin -= delta;
325 mXmax += delta;
326 mYmin -= delta;
327 mYmax += delta;
328 }
329
333 void include( const QgsPointXY &p )
334 {
335 if ( isNull() )
336 {
337 setXMinimum( p.x() );
338 setXMaximum( p.x() );
339 setYMinimum( p.y() );
340 setYMaximum( p.y() );
341 return;
342 }
343 if ( p.x() < xMinimum() )
344 setXMinimum( p.x() );
345 if ( p.x() > xMaximum() )
346 setXMaximum( p.x() );
347 if ( p.y() < yMinimum() )
348 setYMinimum( p.y() );
349 if ( p.y() > yMaximum() )
350 setYMaximum( p.y() );
351 }
352
358 QgsRectangle buffered( double width ) const
359 {
360 if ( isNull() )
361 return QgsRectangle();
362 return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
363 }
364
369 {
370 QgsRectangle intersection = QgsRectangle();
371 if ( intersects( rect ) )
372 {
373 intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
374 intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
375 intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
376 intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
377 }
378 return intersection;
379 }
380
384 bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
385 {
386 if ( isNull() || rect.isNull() )
387 {
388 return false;
389 }
390
391 const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
392 const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
393 if ( x1 > x2 )
394 return false;
395 const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
396 const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
397 return y1 <= y2;
398 }
399
403 bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
404 {
405 return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
406 }
407
411 bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
412 {
413 return mXmin <= p.x() && p.x() <= mXmax &&
414 mYmin <= p.y() && p.y() <= mYmax;
415 }
416
422 bool contains( double x, double y ) const SIP_HOLDGIL
423 {
424 return mXmin <= x && x <= mXmax &&
425 mYmin <= y && y <= mYmax;
426 }
427
431 void combineExtentWith( const QgsRectangle &rect )
432 {
433 if ( isNull() )
434 *this = rect;
435 else if ( !rect.isNull() )
436 {
437 mXmin = std::min( mXmin, rect.xMinimum() );
438 mXmax = std::max( mXmax, rect.xMaximum() );
439 mYmin = std::min( mYmin, rect.yMinimum() );
440 mYmax = std::max( mYmax, rect.yMaximum() );
441 }
442 }
443
447 void combineExtentWith( double x, double y )
448 {
449 if ( isNull() )
450 *this = QgsRectangle( x, y, x, y );
451 else
452 {
453 mXmin = ( ( mXmin < x ) ? mXmin : x );
454 mXmax = ( ( mXmax > x ) ? mXmax : x );
455
456 mYmin = ( ( mYmin < y ) ? mYmin : y );
457 mYmax = ( ( mYmax > y ) ? mYmax : y );
458 }
459 }
460
465 void combineExtentWith( const QgsPointXY &point )
466 {
467 combineExtentWith( point.x(), point.y() );
468 }
469
474 double distance( const QgsPointXY &point ) const
475 {
476 const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
477 const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
478 return std::sqrt( dx * dx + dy * dy );
479 }
480
485
490
494 QgsRectangle &operator-=( QgsVector v );
495
499 QgsRectangle &operator+=( QgsVector v );
500
510 bool isEmpty() const
511 {
512 return isNull() || mXmax <= mXmin || mYmax <= mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
513 }
514
523 bool isNull() const
524 {
525 // rectangle created QgsRectangle() or with rect.setNull() or
526 // otherwise having NaN ordinates
527 return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
528 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
529 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
530 }
531
535 Q_INVOKABLE QString asWktCoordinates() const;
536
540 Q_INVOKABLE QString asWktPolygon() const;
541
545 QRectF toRectF() const
546 {
547 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
548 }
549
555 Q_INVOKABLE QString toString( int precision = 16 ) const;
556
560 QString asPolygon() const;
561
562 bool operator==( const QgsRectangle &r1 ) const
563 {
564 if ( isNull() ) return r1.isNull();
565
566 return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
567 qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
568 qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
569 qgsDoubleNear( r1.yMinimum(), yMinimum() );
570 }
571
572 bool operator!=( const QgsRectangle &r1 ) const
573 {
574 return ( ! operator==( r1 ) );
575 }
576
578 {
579 if ( &r1 != this )
580 {
581 mXmax = r1.xMaximum();
582 mXmin = r1.xMinimum();
583 mYmax = r1.yMaximum();
584 mYmin = r1.yMinimum();
585 }
586
587 return *this;
588 }
589
594 bool isFinite() const
595 {
596 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
597 {
598 return false;
599 }
600 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
601 {
602 return false;
603 }
604 return true;
605 }
606
610 void invert()
611 {
612 std::swap( mXmin, mYmin );
613 std::swap( mXmax, mYmax );
614 }
615
620 QgsBox3D toBox3d( double zMin, double zMax ) const;
621
623 operator QVariant() const
624 {
625 return QVariant::fromValue( *this );
626 }
627
634 QgsRectangle snappedToGrid( double spacing ) const;
635
636#ifdef SIP_RUN
637 SIP_PYOBJECT __repr__();
638 % MethodCode
639 QString str;
640 if ( sipCpp->isNull() )
641 str = QStringLiteral( "<QgsRectangle()>" );
642 else
643 str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
644 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
645 % End
646#endif
647
648 private:
649
650 double mXmin = std::numeric_limits<double>::max();
651 double mYmin = std::numeric_limits<double>::max();
652 double mXmax = -std::numeric_limits<double>::max();
653 double mYmax = -std::numeric_limits<double>::max();
654
655};
656
658
659#ifndef SIP_RUN
660
664CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
665
669CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
670
671inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
672{
673 return os << r.toString().toLocal8Bit().data();
674}
675
676#endif
677
678#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
double x
Definition qgspointxy.h:63
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 truncated to the sp...
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.
double area() const
Returns the area of the rectangle.
void include(const QgsPointXY &p)
Updates the rectangle to include the specified point.
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).
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
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.
double height() const
Returns the height of the rectangle.
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.
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:39
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:5958
#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