QGIS API Documentation  3.37.0-Master (a5b4d9743e8)
qgsrectangle.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrectangle.cpp - 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 #include "qgsgeometry.h"
19 #include "qgspointxy.h"
20 #include "qgsrectangle.h"
21 #include "qgslogger.h"
22 #include "qgsbox3d.h"
23 #include "qgspolygon.h"
24 #include "qgslinestring.h"
25 
26 #include <QString>
27 #include <QTextStream>
28 #include <QTransform>
29 
30 #include <algorithm>
31 #include <cmath>
32 #include <limits>
33 
34 QgsRectangle QgsRectangle::fromWkt( const QString &wkt )
35 {
36  const QgsGeometry geom = QgsGeometry::fromWkt( wkt );
37  if ( geom.isEmpty() )
38  return QgsRectangle();
39 
40  if ( const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( geom.constGet()->simplifiedTypeRef() ) )
41  {
42  if ( polygon->numInteriorRings() > 0 )
43  return QgsRectangle();
44 
45  if ( const QgsLineString *exterior = qgsgeometry_cast< QgsLineString * >( polygon->exteriorRing() ) )
46  {
47  if ( exterior->numPoints() == 5
48  && qgsDoubleNear( exterior->xAt( 0 ), exterior->xAt( 4 ) )
49  && qgsDoubleNear( exterior->yAt( 0 ), exterior->yAt( 4 ) )
50  && geom.isGeosValid() )
51  return QgsRectangle( exterior->xAt( 0 ), exterior->yAt( 0 ), exterior->xAt( 2 ), exterior->yAt( 2 ) );
52  }
53  }
54  return QgsRectangle();
55 }
56 
57 QgsRectangle QgsRectangle::fromCenterAndSize( const QgsPointXY &center, double width, double height )
58 {
59  const double xMin = center.x() - width / 2.0;
60  const double xMax = xMin + width;
61  const double yMin = center.y() - height / 2.0;
62  const double yMax = yMin + height;
63  return QgsRectangle( xMin, yMin, xMax, yMax );
64 }
65 
66 QgsRectangle QgsRectangle::scaled( double scaleFactor, const QgsPointXY *center ) const
67 {
68  QgsRectangle scaledRect = QgsRectangle( *this );
69  scaledRect.scale( scaleFactor, center );
70  return scaledRect;
71 }
72 
74 {
75  const double xmin = mXmin - v.x();
76  const double xmax = mXmax - v.x();
77  const double ymin = mYmin - v.y();
78  const double ymax = mYmax - v.y();
79  return QgsRectangle( xmin, ymin, xmax, ymax );
80 }
81 
83 {
84  const double xmin = mXmin + v.x();
85  const double xmax = mXmax + v.x();
86  const double ymin = mYmin + v.y();
87  const double ymax = mYmax + v.y();
88  return QgsRectangle( xmin, ymin, xmax, ymax );
89 }
90 
92 {
93  mXmin -= v.x();
94  mXmax -= v.x();
95  mYmin -= v.y();
96  mYmax -= v.y();
97  return *this;
98 }
99 
101 {
102  mXmin += v.x();
103  mXmax += v.x();
104  mYmin += v.y();
105  mYmax += v.y();
106  return *this;
107 }
108 
110 {
111  QString rep =
112  qgsDoubleToString( mXmin ) + ' ' + qgsDoubleToString( mYmin ) + QLatin1String( ", " ) +
113  qgsDoubleToString( mXmax ) + ' ' + qgsDoubleToString( mYmax );
114 
115  return rep;
116 }
117 
119 {
120  if ( isNull() )
121  {
122  return QStringLiteral( "POLYGON EMPTY" );
123  }
124 
125  return QStringLiteral( "POLYGON((%1 %2, %3 %2, %3 %4, %1 %4, %1 %2))" ).arg(
126  qgsDoubleToString( mXmin ),
127  qgsDoubleToString( mYmin ),
128  qgsDoubleToString( mXmax ),
129  qgsDoubleToString( mYmax )
130  );
131 }
132 
133 QString QgsRectangle::toString( int precision ) const
134 {
135  QString rep;
136 
137  if ( precision < 0 )
138  {
139  precision = 0;
140  if ( ( width() < 10 || height() < 10 ) && ( width() > 0 && height() > 0 ) )
141  {
142  precision = static_cast<int>( std::ceil( -1.0 * std::log10( std::min( width(), height() ) ) ) ) + 1;
143  // sanity check
144  if ( precision > 20 )
145  precision = 20;
146  }
147  }
148 
149  if ( isNull() )
150  rep = QStringLiteral( "Null" );
151  else
152  rep = QStringLiteral( "%1,%2 : %3,%4" )
153  .arg( mXmin, 0, 'f', precision )
154  .arg( mYmin, 0, 'f', precision )
155  .arg( mXmax, 0, 'f', precision )
156  .arg( mYmax, 0, 'f', precision );
157 
158  QgsDebugMsgLevel( QStringLiteral( "Extents : %1" ).arg( rep ), 4 );
159 
160  return rep;
161 }
162 
163 QString QgsRectangle::asPolygon() const
164 {
165  if ( isNull() )
166  {
167  return QStringLiteral( "EMPTY" );
168  }
169 
170  QString rep;
171 
172  QTextStream foo( &rep );
173 
174  foo.setRealNumberPrecision( 8 );
175  foo.setRealNumberNotation( QTextStream::FixedNotation );
176  // NOTE: a polygon isn't a polygon unless its closed. In the case of
177  // a rectangle, that means 5 points (last == first)
178  foo
179  << mXmin << ' ' << mYmin << ", "
180  << mXmin << ' ' << mYmax << ", "
181  << mXmax << ' ' << mYmax << ", "
182  << mXmax << ' ' << mYmin << ", "
183  << mXmin << ' ' << mYmin;
184 
185  return rep;
186 
187 }
188 
189 QgsBox3D QgsRectangle::toBox3d( double zMin, double zMax ) const
190 {
191  return QgsBox3D( mXmin, mYmin, zMin, mXmax, mYmax, zMax );
192 }
193 
195 {
196  if ( isNull() ) return *this;
197 
198  // helper function
199  auto gridifyValue = []( double value, double spacing ) -> double
200  {
201  if ( spacing > 0 )
202  return std::round( value / spacing ) * spacing;
203  else
204  return value;
205  };
206 
207  return QgsRectangle(
208  gridifyValue( mXmin, spacing ),
209  gridifyValue( mYmin, spacing ),
210  gridifyValue( mXmax, spacing ),
211  gridifyValue( mYmax, spacing )
212  );
213 }
214 
215 QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle )
216 {
217  out << rectangle.xMinimum() << rectangle.yMinimum() << rectangle.xMaximum() << rectangle.yMaximum();
218  return out;
219 }
220 
221 QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle )
222 {
223  double xmin, ymin, xmax, ymax;
224  in >> xmin >> ymin >> xmax >> ymax;
225  rectangle.setXMinimum( xmin );
226  rectangle.setYMinimum( ymin );
227  rectangle.setXMaximum( xmax );
228  rectangle.setYMaximum( ymax );
229  return in;
230 }
virtual const QgsAbstractGeometry * simplifiedTypeRef() const
Returns a reference to the simplest lossless representation of this geometry, e.g.
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:43
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:162
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:45
A class to represent a 2D point.
Definition: qgspointxy.h:60
double y
Definition: qgspointxy.h:64
Q_GADGET double x
Definition: qgspointxy.h:63
Polygon geometry type.
Definition: qgspolygon.h:33
A rectangle specified with double values.
Definition: qgsrectangle.h:42
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.
Definition: qgsrectangle.h:267
QgsRectangle & operator+=(QgsVector v)
Moves this rectangle in the direction of the vector.
QgsRectangle()=default
Constructor for a null rectangle.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:201
static QgsRectangle fromWkt(const QString &wkt)
Creates a new rectangle from a wkt string.
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:159
QgsRectangle & operator-=(QgsVector v)
Moves this rectangle in the direction of the reversed vector.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:211
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:149
QString asWktPolygon() const
Returns a string representation of the rectangle as a WKT Polygon.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:236
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:196
bool isNull() const
Test if the rectangle is null (holding no spatial information).
Definition: qgsrectangle.h:505
QString asWktCoordinates() const
Returns a string representation of the rectangle in WKT format.
QgsRectangle operator-(QgsVector v) const
Returns a rectangle offset from this one in the direction of the reversed vector.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:206
QgsRectangle scaled(double scaleFactor, const QgsPointXY *center=nullptr) const
Scale the rectangle around its center point.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:164
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:262
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:154
static QgsRectangle fromCenterAndSize(const QgsPointXY &center, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
QString asPolygon() const
Returns the rectangle as a polygon.
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:243
QgsRectangle snappedToGrid(double spacing) const
Returns a copy of this rectangle that is snapped to a grid with the specified spacing between the gri...
QgsRectangle operator+(QgsVector v) const
Returns a rectangle offset from this one in the direction of the vector.
QgsBox3D toBox3d(double zMin, double zMax) const
Converts the rectangle to a 3D box, with the specified zMin and zMax z values.
A class to represent a vector.
Definition: qgsvector.h:30
double y() const
Returns the vector's y-component.
Definition: qgsvector.h:152
double x() const
Returns the vector's x-component.
Definition: qgsvector.h:143
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:5089
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5172
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QDataStream & operator>>(QDataStream &in, QgsRectangle &rectangle)
Reads a rectangle from stream in into rectangle.
QDataStream & operator<<(QDataStream &out, const QgsRectangle &rectangle)
Writes the list rectangle to stream out.
int precision