QGIS API Documentation  2.14.0-Essen
qgsabstractgeometryv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsabstractgeometryv2.cpp
3  -------------------------------------------------------------------
4 Date : 04 Sept 2014
5 Copyright : (C) 2014 by Marco Hugentobler
6 email : marco.hugentobler at sourcepole dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsapplication.h"
17 #include "qgsabstractgeometryv2.h"
18 #include "qgswkbptr.h"
19 #include "qgsgeos.h"
20 #include "qgsmaptopixel.h"
21 
22 #include <limits>
23 #include <QTransform>
24 
26 {
27 }
28 
30 {
31 }
32 
34 {
35  mWkbType = geom.mWkbType;
36 }
37 
39 {
40  if ( &geom != this )
41  {
42  clear();
43  mWkbType = geom.mWkbType;
44  }
45  return *this;
46 }
47 
49 {
50  return QgsWKBTypes::hasZ( mWkbType );
51 }
52 
54 {
55  return QgsWKBTypes::hasM( mWkbType );
56 }
57 
58 #if 0
59 void QgsAbstractGeometryV2::clip( const QgsRectangle& rect )
60 {
61  // TODO
62  // - Implementation
63  // - API doc in header
64 
65  // Don't insert Q_UNUSED, so we have a warning that reminds us of this TODO
66 }
67 #endif
68 
70 {
71  if ( !subgeom )
72  {
73  return;
74  }
75 
76  //special handling for 25d types:
77  if ( baseGeomType == QgsWKBTypes::LineString &&
78  ( subgeom->wkbType() == QgsWKBTypes::Point25D || subgeom->wkbType() == QgsWKBTypes::LineString25D ) )
79  {
81  return;
82  }
83  else if ( baseGeomType == QgsWKBTypes::Polygon &&
84  ( subgeom->wkbType() == QgsWKBTypes::Point25D || subgeom->wkbType() == QgsWKBTypes::LineString25D ) )
85  {
87  return;
88  }
89 
90  bool hasZ = subgeom->is3D();
91  bool hasM = subgeom->isMeasure();
92 
93  if ( hasZ && hasM )
94  {
95  mWkbType = QgsWKBTypes::addM( QgsWKBTypes::addZ( baseGeomType ) );
96  }
97  else if ( hasZ )
98  {
99  mWkbType = QgsWKBTypes::addZ( baseGeomType );
100  }
101  else if ( hasM )
102  {
103  mWkbType = QgsWKBTypes::addM( baseGeomType );
104  }
105  else
106  {
107  mWkbType = baseGeomType;
108  }
109 }
110 
112 {
113  double xmin = std::numeric_limits<double>::max();
114  double ymin = std::numeric_limits<double>::max();
115  double xmax = -std::numeric_limits<double>::max();
116  double ymax = -std::numeric_limits<double>::max();
117 
118  QgsVertexId id;
119  QgsPointV2 vertex;
120  double x, y;
121  while ( nextVertex( id, vertex ) )
122  {
123  x = vertex.x();
124  y = vertex.y();
125  if ( x < xmin )
126  xmin = x;
127  if ( x > xmax )
128  xmax = x;
129  if ( y < ymin )
130  ymin = y;
131  if ( y > ymax )
132  ymax = y;
133  }
134 
135  return QgsRectangle( xmin, ymin, xmax, ymax );
136 }
137 
139 {
140  int nCoords = 0;
141 
142  Q_FOREACH ( const QgsRingSequenceV2 &r, coordinateSequence() )
143  {
144  Q_FOREACH ( const QgsPointSequenceV2 &p, r )
145  {
146  nCoords += p.size();
147  }
148  }
149 
150  return nCoords;
151 }
152 
154 {
155  QString wkt = geometryType();
156  if ( is3D() )
157  wkt += 'Z';
158  if ( isMeasure() )
159  wkt += 'M';
160  return wkt;
161 }
162 
164 {
165  // http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
166  // Pick the first ring of first part for the moment
167 
168  int n = vertexCount( 0, 0 );
169  if ( n == 1 )
170  {
171  return vertexAt( QgsVertexId( 0, 0, 0 ) );
172  }
173 
174  double A = 0.;
175  double Cx = 0.;
176  double Cy = 0.;
177  int i = 0, j = 1;
178  if ( vertexAt( QgsVertexId( 0, 0, 0 ) ) != vertexAt( QgsVertexId( 0, 0, n - 1 ) ) )
179  {
180  i = n - 1;
181  j = 0;
182  }
183  for ( ; j < n; i = j++ )
184  {
185  QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) );
186  QgsPointV2 vj = vertexAt( QgsVertexId( 0, 0, j ) );
187  double d = vi.x() * vj.y() - vj.x() * vi.y();
188  A += d;
189  Cx += ( vi.x() + vj.x() ) * d;
190  Cy += ( vi.y() + vj.y() ) * d;
191  }
192 
193  if ( A < 1E-12 )
194  {
195  Cx = Cy = 0.;
196  for ( int i = 0; i < n - 1; ++i )
197  {
198  QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) );
199  Cx += vi.x();
200  Cy += vi.y();
201  }
202  return QgsPointV2( Cx / ( n - 1 ), Cy / ( n - 1 ) );
203  }
204  else
205  {
206  return QgsPointV2( Cx / ( 3. * A ), Cy / ( 3. * A ) );
207  }
208 }
209 
211 {
212  if ( type == mWkbType )
213  return true;
214 
216  return false;
217 
218  bool needZ = QgsWKBTypes::hasZ( type );
219  bool needM = QgsWKBTypes::hasM( type );
220  if ( !needZ )
221  {
222  dropZValue();
223  }
224  else if ( !is3D() )
225  {
226  addZValue();
227  }
228 
229  if ( !needM )
230  {
231  dropMValue();
232  }
233  else if ( !isMeasure() )
234  {
235  addMValue();
236  }
237 
238  return true;
239 }
240 
242 {
243  QgsVertexId vId;
244  QgsPointV2 vertex;
245  return !nextVertex( vId, vertex );
246 }
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
virtual QgsPointV2 centroid() const
Returns the centroid of the geometry.
virtual QgsCoordinateSequenceV2 coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
virtual QgsAbstractGeometryV2 & operator=(const QgsAbstractGeometryV2 &geom)
double x() const
Returns the point&#39;s x-coordinate.
Definition: qgspointv2.h:68
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:746
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:703
Abstract base class for all geometries.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:656
QString wktTypeStr() const
Returns the WKT type string of the geometry.
int nCoordinates() const
Returns the number of nodes contained in the geometry.
int size() const
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
double y() const
Returns the point&#39;s y-coordinate.
Definition: qgspointv2.h:74
virtual void clear()=0
Clears the geometry, ie reset it to a null geometry.
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:770
Utility class for identifying a unique vertex within a geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
virtual QgsRectangle calculateBoundingBox() const
Default calculator for the minimal bounding box for the geometry.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspointv2.h:34
void setZMTypeFromSubGeometry(const QgsAbstractGeometryV2 *subggeom, QgsWKBTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual bool nextVertex(QgsVertexId &id, QgsPointV2 &vertex) const =0
Returns next vertex id and coordinates.
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
virtual bool convertTo(QgsWKBTypes::Type type)
Converts the geometry to a specified type.
virtual int vertexCount(int part=0, int ring=0) const =0
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:36
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:366
virtual QgsPointV2 vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.