QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 QRectF QgsRectangle::toRectF() const
230 {
231  return QRectF(( qreal )xmin, ( qreal )ymin, ( qreal )xmax - xmin, ( qreal )ymax - ymin );
232 }
233 
234 // Return a string representation of the rectangle with automatic or high precision
235 QString QgsRectangle::toString( bool automaticPrecision ) const
236 {
237  if ( automaticPrecision )
238  {
239  int precision = 0;
240  if (( width() < 1 || height() < 1 ) && ( width() > 0 && height() > 0 ) )
241  {
242  precision = static_cast<int>( ceil( -1.0 * log10( qMin( width(), height() ) ) ) ) + 1;
243  // sanity check
244  if ( precision > 20 )
245  precision = 20;
246  }
247  return toString( precision );
248  }
249  else
250  return toString( 16 );
251 }
252 
253 // overloaded version of above fn to allow precision to be set
254 // Return a string representation of the rectangle with high precision
255 QString QgsRectangle::toString( int thePrecision ) const
256 {
257  QString rep;
258  if ( isEmpty() )
259  rep = "Empty";
260  else
261  rep = QString( "%1,%2 : %3,%4" )
262  .arg( xmin, 0, 'f', thePrecision )
263  .arg( ymin, 0, 'f', thePrecision )
264  .arg( xmax, 0, 'f', thePrecision )
265  .arg( ymax, 0, 'f', thePrecision );
266 
267  QgsDebugMsgLevel( QString( "Extents : %1" ).arg( rep ), 4 );
268 
269  return rep;
270 }
271 
272 
273 // Return the rectangle as a set of polygon coordinates
274 QString QgsRectangle::asPolygon() const
275 {
276 // QString rep = tmp.sprintf("%16f %16f,%16f %16f,%16f %16f,%16f %16f,%16f %16f",
277 // xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin);
278  QString rep;
279 
280  QTextStream foo( &rep );
281 
282  foo.setRealNumberPrecision( 8 );
283  foo.setRealNumberNotation( QTextStream::FixedNotation );
284  // NOTE: a polygon isn't a polygon unless its closed. In the case of
285  // a rectangle, that means 5 points (last == first)
286  foo
287  << xmin << " " << ymin << ", "
288  << xmin << " " << ymax << ", "
289  << xmax << " " << ymax << ", "
290  << xmax << " " << ymin << ", "
291  << xmin << " " << ymin;
292 
293  return rep;
294 
295 } // QgsRectangle::asPolygon() const
296 
297 
298 bool QgsRectangle::operator==( const QgsRectangle & r1 ) const
299 {
300  return r1.xMaximum() == xMaximum() &&
301  r1.xMinimum() == xMinimum() &&
302  r1.yMaximum() == yMaximum() &&
303  r1.yMinimum() == yMinimum();
304 }
305 
306 
307 bool QgsRectangle::operator!=( const QgsRectangle & r1 ) const
308 {
309  return ( ! operator==( r1 ) );
310 }
311 
312 
314 {
315  if ( &r != this )
316  {
317  xmax = r.xMaximum();
318  xmin = r.xMinimum();
319  ymax = r.yMaximum();
320  ymin = r.yMinimum();
321  }
322 
323  return *this;
324 }
325 
326 
328 {
329  if ( r.xMinimum() < xMinimum() )
330  setXMinimum( r.xMinimum() );
331  if ( r.xMaximum() > xMaximum() )
332  setXMaximum( r.xMaximum() );
333  if ( r.yMinimum() < yMinimum() )
334  setYMinimum( r.yMinimum() );
335  if ( r.yMaximum() > yMaximum() )
336  setYMaximum( r.yMaximum() );
337 }
338 
340 {
341  if ( qIsInf( xmin ) || qIsInf( ymin ) || qIsInf( xmax ) || qIsInf( ymax ) )
342  {
343  return false;
344  }
345  if ( qIsNaN( xmin ) || qIsNaN( ymin ) || qIsNaN( xmax ) || qIsNaN( ymax ) )
346  {
347  return false;
348  }
349  return true;
350 }
351 
353 {
354  double tmp;
355  tmp = xmin; xmin = ymin; ymin = tmp;
356  tmp = xmax; xmax = ymax; ymax = tmp;
357 }
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:163
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:188
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:126
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:193
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:178
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:34
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:168
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
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:313
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:173
QgsRectangle intersect(const QgsRectangle *rect) const
return the intersection with the given rectangle
double y() const
Definition: qgspoint.h:134
void normalize()
Normalize the rectangle so it has non-negative width/height.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:198
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:183
int max(int a, int b)
Definition: util.h:87
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:158
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:203
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.