QGIS API Documentation 3.39.0-Master (f6cef42644e)
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
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
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
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
467
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
658CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
659
663CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
664
665inline 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
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
Comparison operator.
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)
Copy constructor.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
QgsRectangle & operator=(const QgsRectangle &r1)
Assignment operator.
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
Comparison operator.
~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: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:5465
#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