QGIS API Documentation  3.21.0-Master (56b4176581)
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.isMultipart() )
38  return QgsRectangle();
39 
40  const QgsPolygonXY poly = geom.asPolygon();
41 
42  if ( poly.size() != 1 )
43  return QgsRectangle();
44 
45  const QgsPolylineXY polyline = geom.asPolygon().at( 0 );
46  if ( polyline.size() == 5 && polyline.at( 0 ) == polyline.at( 4 ) && geom.isGeosValid() )
47  return QgsRectangle( polyline.at( 0 ).x(), polyline.at( 0 ).y(), polyline.at( 2 ).x(), polyline.at( 2 ).y() );
48  else
49  return QgsRectangle();
50 }
51 
52 QgsRectangle QgsRectangle::fromCenterAndSize( QgsPointXY center, double width, double height )
53 {
54  const double xMin = center.x() - width / 2.0;
55  const double xMax = xMin + width;
56  const double yMin = center.y() - height / 2.0;
57  const double yMax = yMin + height;
58  return QgsRectangle( xMin, yMin, xMax, yMax );
59 }
60 
61 QgsRectangle QgsRectangle::scaled( double scaleFactor, const QgsPointXY *center ) const
62 {
63  QgsRectangle scaledRect = QgsRectangle( *this );
64  scaledRect.scale( scaleFactor, center );
65  return scaledRect;
66 }
67 
69 {
70  const double xmin = mXmin - v.x();
71  const double xmax = mXmax - v.x();
72  const double ymin = mYmin - v.y();
73  const double ymax = mYmax - v.y();
74  return QgsRectangle( xmin, ymin, xmax, ymax );
75 }
76 
78 {
79  const double xmin = mXmin + v.x();
80  const double xmax = mXmax + v.x();
81  const double ymin = mYmin + v.y();
82  const double ymax = mYmax + v.y();
83  return QgsRectangle( xmin, ymin, xmax, ymax );
84 }
85 
87 {
88  mXmin -= v.x();
89  mXmax -= v.x();
90  mYmin -= v.y();
91  mYmax -= v.y();
92  return *this;
93 }
94 
96 {
97  mXmin += v.x();
98  mXmax += v.x();
99  mYmin += v.y();
100  mYmax += v.y();
101  return *this;
102 }
103 
105 {
106  QString rep =
107  qgsDoubleToString( mXmin ) + ' ' + qgsDoubleToString( mYmin ) + QLatin1String( ", " ) +
108  qgsDoubleToString( mXmax ) + ' ' + qgsDoubleToString( mYmax );
109 
110  return rep;
111 }
112 
114 {
115  QString rep =
116  QLatin1String( "POLYGON((" ) +
117  qgsDoubleToString( mXmin ) + ' ' + qgsDoubleToString( mYmin ) + QLatin1String( ", " ) +
118  qgsDoubleToString( mXmax ) + ' ' + qgsDoubleToString( mYmin ) + QLatin1String( ", " ) +
119  qgsDoubleToString( mXmax ) + ' ' + qgsDoubleToString( mYmax ) + QLatin1String( ", " ) +
120  qgsDoubleToString( mXmin ) + ' ' + qgsDoubleToString( mYmax ) + QLatin1String( ", " ) +
121  qgsDoubleToString( mXmin ) + ' ' + qgsDoubleToString( mYmin ) +
122  QStringLiteral( "))" );
123 
124  return rep;
125 }
126 
127 QString QgsRectangle::toString( int precision ) const
128 {
129  QString rep;
130 
131  if ( precision < 0 )
132  {
133  precision = 0;
134  if ( ( width() < 10 || height() < 10 ) && ( width() > 0 && height() > 0 ) )
135  {
136  precision = static_cast<int>( std::ceil( -1.0 * std::log10( std::min( width(), height() ) ) ) ) + 1;
137  // sanity check
138  if ( precision > 20 )
139  precision = 20;
140  }
141  }
142 
143  if ( isEmpty() )
144  rep = QStringLiteral( "Empty" );
145  else
146  rep = QStringLiteral( "%1,%2 : %3,%4" )
147  .arg( mXmin, 0, 'f', precision )
148  .arg( mYmin, 0, 'f', precision )
149  .arg( mXmax, 0, 'f', precision )
150  .arg( mYmax, 0, 'f', precision );
151 
152  QgsDebugMsgLevel( QStringLiteral( "Extents : %1" ).arg( rep ), 4 );
153 
154  return rep;
155 }
156 
157 QString QgsRectangle::asPolygon() const
158 {
159 // QString rep = tmp.sprintf("%16f %16f,%16f %16f,%16f %16f,%16f %16f,%16f %16f",
160 // xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin);
161  QString rep;
162 
163  QTextStream foo( &rep );
164 
165  foo.setRealNumberPrecision( 8 );
166  foo.setRealNumberNotation( QTextStream::FixedNotation );
167  // NOTE: a polygon isn't a polygon unless its closed. In the case of
168  // a rectangle, that means 5 points (last == first)
169  foo
170  << mXmin << ' ' << mYmin << ", "
171  << mXmin << ' ' << mYmax << ", "
172  << mXmax << ' ' << mYmax << ", "
173  << mXmax << ' ' << mYmin << ", "
174  << mXmin << ' ' << mYmin;
175 
176  return rep;
177 
178 }
179 
180 QgsBox3d QgsRectangle::toBox3d( double zMin, double zMax ) const
181 {
182  return QgsBox3d( mXmin, mYmin, zMin, mXmax, mYmax, zMax );
183 }
184 
186 {
187  // helper function
188  auto gridifyValue = []( double value, double spacing ) -> double
189  {
190  if ( spacing > 0 )
191  return std::round( value / spacing ) * spacing;
192  else
193  return value;
194  };
195 
196  return QgsRectangle(
197  gridifyValue( mXmin, spacing ),
198  gridifyValue( mYmin, spacing ),
199  gridifyValue( mXmax, spacing ),
200  gridifyValue( mYmax, spacing )
201  );
202 }
203 
204 QDataStream &operator<<( QDataStream &out, const QgsRectangle &rectangle )
205 {
206  out << rectangle.xMinimum() << rectangle.yMinimum() << rectangle.xMaximum() << rectangle.yMaximum();
207  return out;
208 }
209 
210 QDataStream &operator>>( QDataStream &in, QgsRectangle &rectangle )
211 {
212  double xmin, ymin, xmax, ymax;
213  in >> xmin >> ymin >> xmax >> ymax;
214  rectangle.setXMinimum( xmin );
215  rectangle.setYMinimum( ymin );
216  rectangle.setXMaximum( xmax );
217  rectangle.setYMaximum( ymax );
218  return in;
219 }
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:39
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
static QgsGeometry fromWkt(const QString &wkt)
Creates a new geometry from a WKT string.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
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:256
QgsRectangle & operator+=(QgsVector v)
Moves this rectangle in the direction of the vector.
QgsRectangle()=default
Constructor for a null rectangle.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
QgsBox3d toBox3d(double zMin, double zMax) const
Converts the rectangle to a 3D box, with the specified zMin and zMax z values.
static QgsRectangle fromWkt(const QString &wkt)
Creates a new rectangle from a wkt string.
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:161
QgsRectangle & operator-=(QgsVector v)
Moves this rectangle in the direction of the reversed vector.
QString asWktPolygon() const
Returns a string representation of the rectangle as a WKT Polygon.
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:156
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.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:151
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsRectangle scaled(double scaleFactor, const QgsPointXY *center=nullptr) const
Scale the rectangle around its center point.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:166
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
static QgsRectangle fromCenterAndSize(QgsPointXY center, double width, double height)
Creates a new rectangle, given the specified center point and width and height.
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
QString asPolygon() const
Returns the rectangle as a polygon.
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.
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
A class to represent a vector.
Definition: qgsvector.h:30
double y() const SIP_HOLDGIL
Returns the vector's y-component.
Definition: qgsvector.h:156
double x() const SIP_HOLDGIL
Returns the vector's x-component.
Definition: qgsvector.h:147
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:1085
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition: qgsgeometry.h:75
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:51
#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