QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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 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
89 {
90 mXmin = other.xMinimum();
91 mYmin = other.yMinimum();
92 mXmax = other.xMaximum();
93 mYmax = other.yMaximum();
94 }
95
96 // IMPORTANT - while QgsRectangle is inherited by QgsReferencedRectangle, we do NOT want a virtual destructor here
97 // because this class MUST be lightweight and we don't want the cost of the vtable here.
98 // see https://github.com/qgis/QGIS/pull/4720#issuecomment-308652392
99 ~QgsRectangle() = default;
100
105 static QgsRectangle fromWkt( const QString &wkt );
106
111 static QgsRectangle fromCenterAndSize( const QgsPointXY &center, double width, double height );
112
119 void set( const QgsPointXY &p1, const QgsPointXY &p2, bool normalize = true )
120 {
121 mXmin = p1.x();
122 mXmax = p2.x();
123 mYmin = p1.y();
124 mYmax = p2.y();
125 if ( normalize )
127 }
128
135 void set( double xMin, double yMin, double xMax, double yMax, bool normalize = true )
136 {
137 mXmin = xMin;
138 mYmin = yMin;
139 mXmax = xMax;
140 mYmax = yMax;
141 if ( normalize )
143 }
144
148 void setXMinimum( double x ) SIP_HOLDGIL { mXmin = x; }
149
153 void setXMaximum( double x ) SIP_HOLDGIL { mXmax = x; }
154
158 void setYMinimum( double y ) SIP_HOLDGIL { mYmin = y; }
159
163 void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }
164
176 {
177 mXmin = mYmin = std::numeric_limits<double>::max();
178 mXmax = mYmax = -std::numeric_limits<double>::max();
179 }
180
187 Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
188 {
189 setNull();
190 }
191
195 double xMaximum() const SIP_HOLDGIL { return mXmax; }
196
200 double xMinimum() const SIP_HOLDGIL { return mXmin; }
201
205 double yMaximum() const SIP_HOLDGIL { return mYmax; }
206
210 double yMinimum() const SIP_HOLDGIL { return mYmin; }
211
216 {
217 if ( isNull() )
218 return;
219
220 if ( mXmin > mXmax )
221 {
222 std::swap( mXmin, mXmax );
223 }
224 if ( mYmin > mYmax )
225 {
226 std::swap( mYmin, mYmax );
227 }
228 }
229
235 double width() const SIP_HOLDGIL { return mXmax - mXmin; }
236
242 double height() const SIP_HOLDGIL { return mYmax - mYmin; }
243
250 double area() const SIP_HOLDGIL { return ( mXmax - mXmin ) * ( mYmax - mYmin ); }
251
256 double perimeter() const SIP_HOLDGIL { return 2 * ( mXmax - mXmin ) + 2 * ( mYmax - mYmin ); }
257
261 QgsPointXY center() const SIP_HOLDGIL { return QgsPointXY( mXmax * 0.5 + mXmin * 0.5, mYmin * 0.5 + mYmax * 0.5 ); }
262
266 void scale( double scaleFactor, const QgsPointXY *c = nullptr )
267 {
268 // scale from the center
269 double centerX, centerY;
270 if ( c )
271 {
272 centerX = c->x();
273 centerY = c->y();
274 }
275 else
276 {
277 centerX = mXmin + width() / 2;
278 centerY = mYmin + height() / 2;
279 }
280 scale( scaleFactor, centerX, centerY );
281 }
282
286 void scale( double scaleFactor, double centerX, double centerY )
287 {
288 const double newWidth = width() * scaleFactor;
289 const double newHeight = height() * scaleFactor;
290 mXmin = centerX - newWidth / 2.0;
291 mXmax = centerX + newWidth / 2.0;
292 mYmin = centerY - newHeight / 2.0;
293 mYmax = centerY + newHeight / 2.0;
294 }
295
300 QgsRectangle scaled( double scaleFactor, const QgsPointXY *center = nullptr ) const;
301
306 void grow( double delta )
307 {
308 if ( isNull() )
309 return;
310 mXmin -= delta;
311 mXmax += delta;
312 mYmin -= delta;
313 mYmax += delta;
314 }
315
319 void include( const QgsPointXY &p )
320 {
321 if ( isNull() )
322 {
323 setXMinimum( p.x() );
324 setXMaximum( p.x() );
325 setYMinimum( p.y() );
326 setYMaximum( p.y() );
327 return;
328 }
329 if ( p.x() < xMinimum() )
330 setXMinimum( p.x() );
331 if ( p.x() > xMaximum() )
332 setXMaximum( p.x() );
333 if ( p.y() < yMinimum() )
334 setYMinimum( p.y() );
335 if ( p.y() > yMaximum() )
336 setYMaximum( p.y() );
337 }
338
344 QgsRectangle buffered( double width ) const
345 {
346 if ( isNull() )
347 return QgsRectangle();
348 return QgsRectangle( mXmin - width, mYmin - width, mXmax + width, mYmax + width );
349 }
350
355 {
356 QgsRectangle intersection = QgsRectangle();
357 if ( intersects( rect ) )
358 {
359 intersection.setXMinimum( mXmin > rect.xMinimum() ? mXmin : rect.xMinimum() );
360 intersection.setXMaximum( mXmax < rect.xMaximum() ? mXmax : rect.xMaximum() );
361 intersection.setYMinimum( mYmin > rect.yMinimum() ? mYmin : rect.yMinimum() );
362 intersection.setYMaximum( mYmax < rect.yMaximum() ? mYmax : rect.yMaximum() );
363 }
364 return intersection;
365 }
366
370 bool intersects( const QgsRectangle &rect ) const SIP_HOLDGIL
371 {
372 if ( isNull() || rect.isNull() )
373 {
374 return false;
375 }
376
377 const double x1 = ( mXmin > rect.mXmin ? mXmin : rect.mXmin );
378 const double x2 = ( mXmax < rect.mXmax ? mXmax : rect.mXmax );
379 if ( x1 > x2 )
380 return false;
381 const double y1 = ( mYmin > rect.mYmin ? mYmin : rect.mYmin );
382 const double y2 = ( mYmax < rect.mYmax ? mYmax : rect.mYmax );
383 return y1 <= y2;
384 }
385
389 bool contains( const QgsRectangle &rect ) const SIP_HOLDGIL
390 {
391 return ( rect.mXmin >= mXmin && rect.mXmax <= mXmax && rect.mYmin >= mYmin && rect.mYmax <= mYmax );
392 }
393
397 bool contains( const QgsPointXY &p ) const SIP_HOLDGIL
398 {
399 return mXmin <= p.x() && p.x() <= mXmax &&
400 mYmin <= p.y() && p.y() <= mYmax;
401 }
402
408 bool contains( double x, double y ) const SIP_HOLDGIL
409 {
410 return mXmin <= x && x <= mXmax &&
411 mYmin <= y && y <= mYmax;
412 }
413
417 void combineExtentWith( const QgsRectangle &rect )
418 {
419 if ( isNull() )
420 *this = rect;
421 else if ( !rect.isNull() )
422 {
423 mXmin = std::min( mXmin, rect.xMinimum() );
424 mXmax = std::max( mXmax, rect.xMaximum() );
425 mYmin = std::min( mYmin, rect.yMinimum() );
426 mYmax = std::max( mYmax, rect.yMaximum() );
427 }
428 }
429
433 void combineExtentWith( double x, double y )
434 {
435 if ( isNull() )
436 *this = QgsRectangle( x, y, x, y );
437 else
438 {
439 mXmin = ( ( mXmin < x ) ? mXmin : x );
440 mXmax = ( ( mXmax > x ) ? mXmax : x );
441
442 mYmin = ( ( mYmin < y ) ? mYmin : y );
443 mYmax = ( ( mYmax > y ) ? mYmax : y );
444 }
445 }
446
451 void combineExtentWith( const QgsPointXY &point )
452 {
453 combineExtentWith( point.x(), point.y() );
454 }
455
460 double distance( const QgsPointXY &point ) const
461 {
462 const double dx = std::max( std::max( mXmin - point.x(), 0.0 ), point.x() - mXmax );
463 const double dy = std::max( std::max( mYmin - point.y(), 0.0 ), point.y() - mYmax );
464 return std::sqrt( dx * dx + dy * dy );
465 }
466
471
476
480 QgsRectangle &operator-=( QgsVector v );
481
485 QgsRectangle &operator+=( QgsVector v );
486
496 bool isEmpty() const
497 {
498 return isNull() || mXmax <= mXmin || mYmax <= mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
499 }
500
509 bool isNull() const
510 {
511 // rectangle created QgsRectangle() or with rect.setNull() or
512 // otherwise having NaN ordinates
513 return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
514 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
515 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
516 }
517
521 QString asWktCoordinates() const;
522
526 QString asWktPolygon() const;
527
531 QRectF toRectF() const
532 {
533 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
534 }
535
541 QString toString( int precision = 16 ) const;
542
546 QString asPolygon() const;
547
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
558 bool operator!=( const QgsRectangle &r1 ) const
559 {
560 return ( ! operator==( r1 ) );
561 }
562
564 {
565 if ( &r1 != this )
566 {
567 mXmax = r1.xMaximum();
568 mXmin = r1.xMinimum();
569 mYmax = r1.yMaximum();
570 mYmin = r1.yMinimum();
571 }
572
573 return *this;
574 }
575
580 bool isFinite() const
581 {
582 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
583 {
584 return false;
585 }
586 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
587 {
588 return false;
589 }
590 return true;
591 }
592
596 void invert()
597 {
598 std::swap( mXmin, mYmin );
599 std::swap( mXmax, mYmax );
600 }
601
606 QgsBox3D toBox3d( double zMin, double zMax ) const;
607
609 operator QVariant() const
610 {
611 return QVariant::fromValue( *this );
612 }
613
620 QgsRectangle snappedToGrid( double spacing ) const;
621
622#ifdef SIP_RUN
623 SIP_PYOBJECT __repr__();
624 % MethodCode
625 QString str;
626 if ( sipCpp->isNull() )
627 str = QStringLiteral( "<QgsRectangle()>" );
628 else
629 str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
630 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
631 % End
632#endif
633
634 private:
635
636 double mXmin = std::numeric_limits<double>::max();
637 double mYmin = std::numeric_limits<double>::max();
638 double mXmax = -std::numeric_limits<double>::max();
639 double mYmax = -std::numeric_limits<double>::max();
640
641};
642
644
645#ifndef SIP_RUN
646
650CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
651
655CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
656
657inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
658{
659 return os << r.toString().toLocal8Bit().data();
660}
661
662#endif
663
664#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.
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.
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.
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.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
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
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