QGIS API Documentation 3.33.0-Master (01a999a9a0)
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
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 ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
483 ( qgsDoubleNear( mXmin, 0.0 ) && qgsDoubleNear( mXmax, 0.0 ) && qgsDoubleNear( mYmin, 0.0 ) && qgsDoubleNear( mYmax, 0.0 ) ) ||
484 ( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
485 qgsDoubleNear( mXmax, -std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmax, -std::numeric_limits<double>::max() ) );
486 }
487
491 QString asWktCoordinates() const;
492
496 QString asWktPolygon() const;
497
501 QRectF toRectF() const
502 {
503 return QRectF( static_cast< qreal >( mXmin ), static_cast< qreal >( mYmin ), static_cast< qreal >( mXmax - mXmin ), static_cast< qreal >( mYmax - mYmin ) );
504 }
505
511 QString toString( int precision = 16 ) const;
512
516 QString asPolygon() const;
517
522 bool operator==( const QgsRectangle &r1 ) const
523 {
524 return qgsDoubleNear( r1.xMaximum(), xMaximum() ) &&
525 qgsDoubleNear( r1.xMinimum(), xMinimum() ) &&
526 qgsDoubleNear( r1.yMaximum(), yMaximum() ) &&
527 qgsDoubleNear( r1.yMinimum(), yMinimum() );
528 }
529
534 bool operator!=( const QgsRectangle &r1 ) const
535 {
536 return ( ! operator==( r1 ) );
537 }
538
544 {
545 if ( &r1 != this )
546 {
547 mXmax = r1.xMaximum();
548 mXmin = r1.xMinimum();
549 mYmax = r1.yMaximum();
550 mYmin = r1.yMinimum();
551 }
552
553 return *this;
554 }
555
560 bool isFinite() const
561 {
562 if ( std::isinf( mXmin ) || std::isinf( mYmin ) || std::isinf( mXmax ) || std::isinf( mYmax ) )
563 {
564 return false;
565 }
566 if ( std::isnan( mXmin ) || std::isnan( mYmin ) || std::isnan( mXmax ) || std::isnan( mYmax ) )
567 {
568 return false;
569 }
570 return true;
571 }
572
576 void invert()
577 {
578 std::swap( mXmin, mYmin );
579 std::swap( mXmax, mYmax );
580 }
581
587 QgsBox3D toBox3d( double zMin, double zMax ) const;
588
590 operator QVariant() const
591 {
592 return QVariant::fromValue( *this );
593 }
594
601 QgsRectangle snappedToGrid( double spacing ) const;
602
603#ifdef SIP_RUN
604 SIP_PYOBJECT __repr__();
605 % MethodCode
606 QString str = QStringLiteral( "<QgsRectangle: %1>" ).arg( sipCpp->asWktCoordinates() );
607 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
608 % End
609#endif
610
611 private:
612
613 double mXmin = 0.0;
614 double mYmin = 0.0;
615 double mXmax = 0.0;
616 double mYmax = 0.0;
617
618};
619
621
622#ifndef SIP_RUN
623
627CORE_EXPORT QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle );
628
632CORE_EXPORT QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle );
633
634inline std::ostream &operator << ( std::ostream &os, const QgsRectangle &r )
635{
636 return os << r.toString().toLocal8Bit().data();
637}
638
639#endif
640
641#endif // QGSRECTANGLE_H
A 3-dimensional box composed of x, y, z coordinates.
Definition qgsbox3d.h:44
A class to represent a 2D point.
Definition qgspointxy.h:59
double y
Definition qgspointxy.h:63
double x
Definition qgspointxy.h:62
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.
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).
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
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 (all coordinates zero or after call to setMinimal()).
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 is empty.
QgsRectangle(const QRectF &qRectF)
Construct a rectangle from a QRectF.
double height() const
Returns the height of the rectangle.
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:4260
#define SIP_HOLDGIL
Definition qgis_sip.h:166
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