QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 <QRegExp>
25 #include <qnumeric.h>
26 
27 #include "qgspoint.h"
28 #include "qgsrectangle.h"
29 #include "qgslogger.h"
30 
31 QgsRectangle::QgsRectangle( double newxmin, double newymin, double newxmax, double newymax )
32  : xmin( newxmin ), ymin( newymin ), xmax( newxmax ), ymax( newymax )
33 {
34  normalize();
35 }
36 
37 QgsRectangle::QgsRectangle( QgsPoint const & p1, QgsPoint const & p2 )
38 {
39  set( p1, p2 );
40 }
41 
42 QgsRectangle::QgsRectangle( QRectF const & qRectF )
43 {
44  xmin = qRectF.topLeft().x();
45  ymin = qRectF.topLeft().y();
46  xmax = qRectF.bottomRight().x();
47  ymax = qRectF.bottomRight().y();
48 }
49 
51 {
52  xmin = r.xMinimum();
53  ymin = r.yMinimum();
54  xmax = r.xMaximum();
55  ymax = r.yMaximum();
56 }
57 
58 
59 void QgsRectangle::set( const QgsPoint& p1, const QgsPoint& p2 )
60 {
61  xmin = p1.x();
62  xmax = p2.x();
63  ymin = p1.y();
64  ymax = p2.y();
65  normalize();
66 }
67 
68 void QgsRectangle::set( double xmin_, double ymin_, double xmax_, double ymax_ )
69 {
70  xmin = xmin_;
71  ymin = ymin_;
72  xmax = xmax_;
73  ymax = ymax_;
74  normalize();
75 }
76 
78 {
79  if ( xmin > xmax )
80  {
81  std::swap( xmin, xmax );
82  }
83  if ( ymin > ymax )
84  {
85  std::swap( ymin, ymax );
86  }
87 } // QgsRectangle::normalize()
88 
89 
91 {
96 }
97 
98 void QgsRectangle::scale( double scaleFactor, const QgsPoint * cp )
99 {
100  // scale from the center
101  double centerX, centerY;
102  if ( cp )
103  {
104  centerX = cp->x();
105  centerY = cp->y();
106  }
107  else
108  {
109  centerX = xmin + width() / 2;
110  centerY = ymin + height() / 2;
111  }
112  scale( scaleFactor, centerX, centerY );
113 }
114 
115 void QgsRectangle::scale( double scaleFactor, double centerX, double centerY )
116 {
117  double newWidth = width() * scaleFactor;
118  double newHeight = height() * scaleFactor;
119  xmin = centerX - newWidth / 2.0;
120  xmax = centerX + newWidth / 2.0;
121  ymin = centerY - newHeight / 2.0;
122  ymax = centerY + newHeight / 2.0;
123 }
124 
126 {
127  return QgsRectangle( xmin - width, ymin - width, xmax + width, ymax + width );
128 }
129 
131 {
132  QgsRectangle intersection = QgsRectangle();
133  //If they don't actually intersect an empty QgsRectangle should be returned
134  if ( !rect || !intersects( *rect ) )
135  {
136  return intersection;
137  }
138 
139  intersection.setXMinimum( xmin > rect->xMinimum() ? xmin : rect->xMinimum() );
140  intersection.setXMaximum( xmax < rect->xMaximum() ? xmax : rect->xMaximum() );
141  intersection.setYMinimum( ymin > rect->yMinimum() ? ymin : rect->yMinimum() );
142  intersection.setYMaximum( ymax < rect->yMaximum() ? ymax : rect->yMaximum() );
143  return intersection;
144 }
145 
146 bool QgsRectangle::intersects( const QgsRectangle& rect ) const
147 {
148  double x1 = ( xmin > rect.xmin ? xmin : rect.xmin );
149  double x2 = ( xmax < rect.xmax ? xmax : rect.xmax );
150  if ( x1 > x2 )
151  return false;
152  double y1 = ( ymin > rect.ymin ? ymin : rect.ymin );
153  double y2 = ( ymax < rect.ymax ? ymax : rect.ymax );
154  if ( y1 > y2 )
155  return false;
156  return true;
157 }
158 
159 bool QgsRectangle::contains( const QgsRectangle& rect ) const
160 {
161  return ( rect.xmin >= xmin && rect.xmax <= xmax && rect.ymin >= ymin && rect.ymax <= ymax );
162 }
163 
164 bool QgsRectangle::contains( const QgsPoint &p ) const
165 {
166  return xmin <= p.x() && p.x() <= xmax &&
167  ymin <= p.y() && p.y() <= ymax;
168 }
169 
171 {
172 
173  xmin = (( xmin < rect->xMinimum() ) ? xmin : rect->xMinimum() );
174  xmax = (( xmax > rect->xMaximum() ) ? xmax : rect->xMaximum() );
175 
176  ymin = (( ymin < rect->yMinimum() ) ? ymin : rect->yMinimum() );
177  ymax = (( ymax > rect->yMaximum() ) ? ymax : rect->yMaximum() );
178 
179 }
180 
181 void QgsRectangle::combineExtentWith( double x, double y )
182 {
183 
184  xmin = (( xmin < x ) ? xmin : x );
185  xmax = (( xmax > x ) ? xmax : x );
186 
187  ymin = (( ymin < y ) ? ymin : y );
188  ymax = (( ymax > y ) ? ymax : y );
189 
190 }
191 
193 {
194  return xmax <= xmin || ymax <= ymin;
195 }
196 
198 {
199  // rectangle created QgsRectangle() or with rect.setMinimal() ?
200  return ( xmin == 0 && xmax == 0 && ymin == 0 && ymax == 0 ) ||
203 }
204 
206 {
207  QString rep =
208  qgsDoubleToString( xmin ) + " " + qgsDoubleToString( ymin ) + ", " +
210 
211  return rep;
212 }
213 
215 {
216  QString rep =
217  QString( "POLYGON((" ) +
218  qgsDoubleToString( xmin ) + " " + qgsDoubleToString( ymin ) + ", " +
219  qgsDoubleToString( xmax ) + " " + qgsDoubleToString( ymin ) + ", " +
220  qgsDoubleToString( xmax ) + " " + qgsDoubleToString( ymax ) + ", " +
221  qgsDoubleToString( xmin ) + " " + qgsDoubleToString( ymax ) + ", " +
223  QString( "))" );
224 
225  return rep;
226 }
227 
229 //@note added in 2.0
230 QRectF QgsRectangle::toRectF() const
231 {
232  return QRectF(( qreal )xmin, ( qreal )ymin, ( qreal )xmax - xmin, ( qreal )ymax - ymin );
233 }
234 
235 // Return a string representation of the rectangle with automatic or high precision
236 QString QgsRectangle::toString( bool automaticPrecision ) const
237 {
238  if ( automaticPrecision )
239  {
240  int precision = 0;
241  if (( width() < 1 || height() < 1 ) && ( width() > 0 && height() > 0 ) )
242  {
243  precision = static_cast<int>( ceil( -1.0 * log10( qMin( width(), height() ) ) ) ) + 1;
244  // sanity check
245  if ( precision > 20 )
246  precision = 20;
247  }
248  return toString( precision );
249  }
250  else
251  return toString( 16 );
252 }
253 
254 // overloaded version of above fn to allow precision to be set
255 // Return a string representation of the rectangle with high precision
256 QString QgsRectangle::toString( int thePrecision ) const
257 {
258  QString rep;
259  if ( isEmpty() )
260  rep = "Empty";
261  else
262  rep = QString( "%1,%2 : %3,%4" )
263  .arg( xmin, 0, 'f', thePrecision )
264  .arg( ymin, 0, 'f', thePrecision )
265  .arg( xmax, 0, 'f', thePrecision )
266  .arg( ymax, 0, 'f', thePrecision );
267 
268  QgsDebugMsgLevel( QString( "Extents : %1" ).arg( rep ), 4 );
269 
270  return rep;
271 }
272 
273 
274 // Return the rectangle as a set of polygon coordinates
275 QString QgsRectangle::asPolygon() const
276 {
277 // QString rep = tmp.sprintf("%16f %16f,%16f %16f,%16f %16f,%16f %16f,%16f %16f",
278 // xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin);
279  QString rep;
280 
281  QTextStream foo( &rep );
282 
283  foo.setRealNumberPrecision( 8 );
284  foo.setRealNumberNotation( QTextStream::FixedNotation );
285  // NOTE: a polygon isn't a polygon unless its closed. In the case of
286  // a rectangle, that means 5 points (last == first)
287  foo
288  << xmin << " " << ymin << ", "
289  << xmin << " " << ymax << ", "
290  << xmax << " " << ymax << ", "
291  << xmax << " " << ymin << ", "
292  << xmin << " " << ymin;
293 
294  return rep;
295 
296 } // QgsRectangle::asPolygon() const
297 
298 
299 bool QgsRectangle::operator==( const QgsRectangle & r1 ) const
300 {
301  return r1.xMaximum() == xMaximum() &&
302  r1.xMinimum() == xMinimum() &&
303  r1.yMaximum() == yMaximum() &&
304  r1.yMinimum() == yMinimum();
305 }
306 
307 
308 bool QgsRectangle::operator!=( const QgsRectangle & r1 ) const
309 {
310  return ( ! operator==( r1 ) );
311 }
312 
313 
315 {
316  if ( &r != this )
317  {
318  xmax = r.xMaximum();
319  xmin = r.xMinimum();
320  ymax = r.yMaximum();
321  ymin = r.yMinimum();
322  }
323 
324  return *this;
325 }
326 
327 
329 {
330  if ( r.xMinimum() < xMinimum() )
331  setXMinimum( r.xMinimum() );
332  if ( r.xMaximum() > xMaximum() )
333  setXMaximum( r.xMaximum() );
334  if ( r.yMinimum() < yMinimum() )
335  setYMinimum( r.yMinimum() );
336  if ( r.yMaximum() > yMaximum() )
337  setYMaximum( r.yMaximum() );
338 }
339 
341 {
342  if ( qIsInf( xmin ) || qIsInf( ymin ) || qIsInf( xmax ) || qIsInf( ymax ) )
343  {
344  return false;
345  }
346  if ( qIsNaN( xmin ) || qIsNaN( ymin ) || qIsNaN( xmax ) || qIsNaN( ymax ) )
347  {
348  return false;
349  }
350  return true;
351 }
352 
354 {
355  double tmp;
356  tmp = xmin; xmin = ymin; ymin = tmp;
357  tmp = xmax; xmax = ymax; ymax = tmp;
358 }
void unionRect(const QgsRectangle &rect)
updates rectangle to include passed argument
QgsRectangle & operator=(const QgsRectangle &r1)
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 setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:169
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:194
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
bool isNull() const
test if the rectangle is null (all coordinates zero or after call to setMinimal()).
double x() const
Definition: qgspoint.h:110
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
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:199
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:184
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:37
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:174
QString asWktCoordinates() const
returns string representation in Wkt form
A class to represent a point geometry.
Definition: qgspoint.h:63
bool operator!=(const QgsRectangle &r1) const
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:316
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:179
QgsRectangle intersect(const QgsRectangle *rect) const
return the intersection with the given rectangle
double y() const
Definition: qgspoint.h:118
void normalize()
Normalize the rectangle so it has non-negative width/height.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:204
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:189
int max(int a, int b)
Definition: util.h:87
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:164
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:209
void invert()
swap x/y
bool operator==(const QgsRectangle &r1) const
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.