QGIS API Documentation  2.12.0-Lyon
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 <algorithm>
19 #include <cmath>
20 #include <limits>
21 #include <QRectF>
22 #include <QString>
23 #include <QTextStream>
24 #include <QTransform>
25 #include <QRegExp>
26 #include <qnumeric.h>
27 
28 #include "qgspoint.h"
29 #include "qgsrectangle.h"
30 #include "qgslogger.h"
31 
32 QgsRectangle::QgsRectangle( double newxmin, double newymin, double newxmax, double newymax )
33  : xmin( newxmin ), ymin( newymin ), xmax( newxmax ), ymax( newymax )
34 {
35  normalize();
36 }
37 
38 QgsRectangle::QgsRectangle( QgsPoint const & p1, QgsPoint const & p2 )
39 {
40  set( p1, p2 );
41 }
42 
44 {
45  xmin = qRectF.topLeft().x();
46  ymin = qRectF.topLeft().y();
47  xmax = qRectF.bottomRight().x();
48  ymax = qRectF.bottomRight().y();
49 }
50 
52 {
53  xmin = r.xMinimum();
54  ymin = r.yMinimum();
55  xmax = r.xMaximum();
56  ymax = r.yMaximum();
57 }
58 
59 
60 void QgsRectangle::set( const QgsPoint& p1, const QgsPoint& p2 )
61 {
62  xmin = p1.x();
63  xmax = p2.x();
64  ymin = p1.y();
65  ymax = p2.y();
66  normalize();
67 }
68 
69 void QgsRectangle::set( double xmin_, double ymin_, double xmax_, double ymax_ )
70 {
71  xmin = xmin_;
72  ymin = ymin_;
73  xmax = xmax_;
74  ymax = ymax_;
75  normalize();
76 }
77 
79 {
80  if ( isNull() )
81  return;
82 
83  if ( xmin > xmax )
84  {
85  std::swap( xmin, xmax );
86  }
87  if ( ymin > ymax )
88  {
89  std::swap( ymin, ymax );
90  }
91 } // QgsRectangle::normalize()
92 
93 
95 {
100 }
101 
102 void QgsRectangle::scale( double scaleFactor, const QgsPoint * cp )
103 {
104  // scale from the center
105  double centerX, centerY;
106  if ( cp )
107  {
108  centerX = cp->x();
109  centerY = cp->y();
110  }
111  else
112  {
113  centerX = xmin + width() / 2;
114  centerY = ymin + height() / 2;
115  }
116  scale( scaleFactor, centerX, centerY );
117 }
118 
119 void QgsRectangle::scale( double scaleFactor, double centerX, double centerY )
120 {
121  double newWidth = width() * scaleFactor;
122  double newHeight = height() * scaleFactor;
123  xmin = centerX - newWidth / 2.0;
124  xmax = centerX + newWidth / 2.0;
125  ymin = centerY - newHeight / 2.0;
126  ymax = centerY + newHeight / 2.0;
127 }
128 
129 void QgsRectangle::grow( double delta )
130 {
131  xmin -= delta;
132  xmax += delta;
133  ymin -= delta;
134  ymax += delta;
135 }
136 
138 {
139  if ( p.x() < xMinimum() )
140  setXMinimum( p.x() );
141  else if ( p.x() > xMaximum() )
142  setXMaximum( p.x() );
143  if ( p.y() < yMinimum() )
144  setYMinimum( p.y() );
145  if ( p.y() > yMaximum() )
146  setYMaximum( p.y() );
147 }
148 
150 {
151  return QgsRectangle( xmin - width, ymin - width, xmax + width, ymax + width );
152 }
153 
155 {
156  QgsRectangle intersection = QgsRectangle();
157  //If they don't actually intersect an empty QgsRectangle should be returned
158  if ( !rect || !intersects( *rect ) )
159  {
160  return intersection;
161  }
162 
163  intersection.setXMinimum( xmin > rect->xMinimum() ? xmin : rect->xMinimum() );
164  intersection.setXMaximum( xmax < rect->xMaximum() ? xmax : rect->xMaximum() );
165  intersection.setYMinimum( ymin > rect->yMinimum() ? ymin : rect->yMinimum() );
166  intersection.setYMaximum( ymax < rect->yMaximum() ? ymax : rect->yMaximum() );
167  return intersection;
168 }
169 
170 bool QgsRectangle::intersects( const QgsRectangle& rect ) const
171 {
172  double x1 = ( xmin > rect.xmin ? xmin : rect.xmin );
173  double x2 = ( xmax < rect.xmax ? xmax : rect.xmax );
174  if ( x1 > x2 )
175  return false;
176  double y1 = ( ymin > rect.ymin ? ymin : rect.ymin );
177  double y2 = ( ymax < rect.ymax ? ymax : rect.ymax );
178  if ( y1 > y2 )
179  return false;
180  return true;
181 }
182 
183 bool QgsRectangle::contains( const QgsRectangle& rect ) const
184 {
185  return ( rect.xmin >= xmin && rect.xmax <= xmax && rect.ymin >= ymin && rect.ymax <= ymax );
186 }
187 
188 bool QgsRectangle::contains( const QgsPoint &p ) const
189 {
190  return xmin <= p.x() && p.x() <= xmax &&
191  ymin <= p.y() && p.y() <= ymax;
192 }
193 
195 {
196 
197  xmin = (( xmin < rect->xMinimum() ) ? xmin : rect->xMinimum() );
198  xmax = (( xmax > rect->xMaximum() ) ? xmax : rect->xMaximum() );
199 
200  ymin = (( ymin < rect->yMinimum() ) ? ymin : rect->yMinimum() );
201  ymax = (( ymax > rect->yMaximum() ) ? ymax : rect->yMaximum() );
202 
203 }
204 
205 void QgsRectangle::combineExtentWith( double x, double y )
206 {
207 
208  xmin = (( xmin < x ) ? xmin : x );
209  xmax = (( xmax > x ) ? xmax : x );
210 
211  ymin = (( ymin < y ) ? ymin : y );
212  ymax = (( ymax > y ) ? ymax : y );
213 
214 }
215 
217 {
218  return xmax <= xmin || ymax <= ymin;
219 }
220 
222 {
223  // rectangle created QgsRectangle() or with rect.setMinimal() ?
224  return ( xmin == 0 && xmax == 0 && ymin == 0 && ymax == 0 ) ||
227 }
228 
230 {
231  QString rep =
232  qgsDoubleToString( xmin ) + " " + qgsDoubleToString( ymin ) + ", " +
234 
235  return rep;
236 }
237 
239 {
240  QString rep =
241  QString( "POLYGON((" ) +
242  qgsDoubleToString( xmin ) + " " + qgsDoubleToString( ymin ) + ", " +
243  qgsDoubleToString( xmax ) + " " + qgsDoubleToString( ymin ) + ", " +
244  qgsDoubleToString( xmax ) + " " + qgsDoubleToString( ymax ) + ", " +
245  qgsDoubleToString( xmin ) + " " + qgsDoubleToString( ymax ) + ", " +
247  QString( "))" );
248 
249  return rep;
250 }
251 
254 {
255  return QRectF(( qreal )xmin, ( qreal )ymin, ( qreal )xmax - xmin, ( qreal )ymax - ymin );
256 }
257 
258 // Return a string representation of the rectangle with automatic or high precision
259 QString QgsRectangle::toString( bool automaticPrecision ) const
260 {
261  if ( automaticPrecision )
262  {
263  int precision = 0;
264  if (( width() < 1 || height() < 1 ) && ( width() > 0 && height() > 0 ) )
265  {
266  precision = static_cast<int>( ceil( -1.0 * log10( qMin( width(), height() ) ) ) ) + 1;
267  // sanity check
268  if ( precision > 20 )
269  precision = 20;
270  }
271  return toString( precision );
272  }
273  else
274  return toString( 16 );
275 }
276 
277 // overloaded version of above fn to allow precision to be set
278 // Return a string representation of the rectangle with high precision
279 QString QgsRectangle::toString( int thePrecision ) const
280 {
281  QString rep;
282  if ( isEmpty() )
283  rep = "Empty";
284  else
285  rep = QString( "%1,%2 : %3,%4" )
286  .arg( xmin, 0, 'f', thePrecision )
287  .arg( ymin, 0, 'f', thePrecision )
288  .arg( xmax, 0, 'f', thePrecision )
289  .arg( ymax, 0, 'f', thePrecision );
290 
291  QgsDebugMsgLevel( QString( "Extents : %1" ).arg( rep ), 4 );
292 
293  return rep;
294 }
295 
296 
297 // Return the rectangle as a set of polygon coordinates
299 {
300 // QString rep = tmp.sprintf("%16f %16f,%16f %16f,%16f %16f,%16f %16f,%16f %16f",
301 // xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin);
302  QString rep;
303 
304  QTextStream foo( &rep );
305 
306  foo.setRealNumberPrecision( 8 );
307  foo.setRealNumberNotation( QTextStream::FixedNotation );
308  // NOTE: a polygon isn't a polygon unless its closed. In the case of
309  // a rectangle, that means 5 points (last == first)
310  foo
311  << xmin << " " << ymin << ", "
312  << xmin << " " << ymax << ", "
313  << xmax << " " << ymax << ", "
314  << xmax << " " << ymin << ", "
315  << xmin << " " << ymin;
316 
317  return rep;
318 
319 } // QgsRectangle::asPolygon() const
320 
321 
322 bool QgsRectangle::operator==( const QgsRectangle & r1 ) const
323 {
324  return r1.xMaximum() == xMaximum() &&
325  r1.xMinimum() == xMinimum() &&
326  r1.yMaximum() == yMaximum() &&
327  r1.yMinimum() == yMinimum();
328 }
329 
330 
331 bool QgsRectangle::operator!=( const QgsRectangle & r1 ) const
332 {
333  return ( ! operator==( r1 ) );
334 }
335 
336 
338 {
339  if ( &r != this )
340  {
341  xmax = r.xMaximum();
342  xmin = r.xMinimum();
343  ymax = r.yMaximum();
344  ymin = r.yMinimum();
345  }
346 
347  return *this;
348 }
349 
350 
352 {
353  if ( r.xMinimum() < xMinimum() )
354  setXMinimum( r.xMinimum() );
355  if ( r.xMaximum() > xMaximum() )
356  setXMaximum( r.xMaximum() );
357  if ( r.yMinimum() < yMinimum() )
358  setYMinimum( r.yMinimum() );
359  if ( r.yMaximum() > yMaximum() )
360  setYMaximum( r.yMaximum() );
361 }
362 
364 {
365  if ( qIsInf( xmin ) || qIsInf( ymin ) || qIsInf( xmax ) || qIsInf( ymax ) )
366  {
367  return false;
368  }
369  if ( qIsNaN( xmin ) || qIsNaN( ymin ) || qIsNaN( xmax ) || qIsNaN( ymax ) )
370  {
371  return false;
372  }
373  return true;
374 }
375 
377 {
378  double tmp;
379  tmp = xmin; xmin = ymin; ymin = tmp;
380  tmp = xmax; xmax = ymax; ymax = tmp;
381 }
382 
383 QDataStream& operator<<( QDataStream& out, const QgsRectangle& rectangle )
384 {
385  out << rectangle.xMinimum() << rectangle.yMinimum() << rectangle.xMaximum() << rectangle.yMaximum();
386  return out;
387 }
388 
390 {
391  double xmin, ymin, xmax, ymax;
392  in >> xmin >> ymin >> xmax >> ymax;
393  rectangle.setXMinimum( xmin );
394  rectangle.setYMinimum( ymin );
395  rectangle.setXMaximum( xmax );
396  rectangle.setYMaximum( ymax );
397  return in;
398 }
void unionRect(const QgsRectangle &rect)
Updates rectangle to include passed argument.
QgsRectangle & operator=(const QgsRectangle &r1)
Assignment operator.
bool intersects(const QgsRectangle &rect) const
returns true when rectangle intersects with other rectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool isEmpty() const
test if rectangle is empty.
QRectF toRectF() const
returns a QRectF with same coordinates.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
void setRealNumberNotation(RealNumberNotation notation)
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:171
QgsRectangle buffer(double width)
Get rectangle enlarged by buffer.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:196
void setRealNumberPrecision(int precision)
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
QDataStream & operator>>(QDataStream &in, QgsRectangle &rectangle)
Reads a rectangle from stream in into rectangle.
bool isNull() const
test if the rectangle is null (all coordinates zero or after call to setMinimal()).
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
qreal x() const
qreal y() const
QgsRectangle(double xmin=0, double ymin=0, double xmax=0, double ymax=0)
Constructor.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:201
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:186
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
void grow(double delta)
Grow the rectangle by the specified amount.
void include(const QgsPoint &p)
Updates the rectangle to include the specified point.
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:176
QPointF topLeft() const
QString asWktCoordinates() const
returns string representation in Wkt form
A class to represent a point.
Definition: qgspoint.h:63
bool operator!=(const QgsRectangle &r1) const
Comparison operator.
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:257
QString asWktPolygon() const
returns string representation as WKT Polygon
QString asPolygon() const
returns rectangle as a polygon
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:181
QgsRectangle intersect(const QgsRectangle *rect) const
return the intersection with the given rectangle
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
QPointF bottomRight() const
void normalize()
Normalize the rectangle so it has non-negative width/height.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:206
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:191
QDataStream & operator<<(QDataStream &out, const QgsRectangle &rectangle)
Writes the list rectangle to stream out.
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:166
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:211
void invert()
swap x/y
bool operator==(const QgsRectangle &r1) const
Comparison operator.
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.