QGIS API Documentation  2.18.3-Las Palmas (77b8c3d)
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  QgsPointV2 v0 = vertexAt( QgsVertexId( 0, 0, 0 ) );
178  int i = 0, j = 1;
179  if ( vertexAt( QgsVertexId( 0, 0, 0 ) ) != vertexAt( QgsVertexId( 0, 0, n - 1 ) ) )
180  {
181  i = n - 1;
182  j = 0;
183  }
184  for ( ; j < n; i = j++ )
185  {
186  QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) );
187  QgsPointV2 vj = vertexAt( QgsVertexId( 0, 0, j ) );
188  vi.rx() -= v0.x();
189  vi.ry() -= v0.y();
190  vj.rx() -= v0.x();
191  vj.ry() -= v0.y();
192  double d = vi.x() * vj.y() - vj.x() * vi.y();
193  A += d;
194  Cx += ( vi.x() + vj.x() ) * d;
195  Cy += ( vi.y() + vj.y() ) * d;
196  }
197 
198  if ( A < 1E-12 )
199  {
200  Cx = Cy = 0.;
201  for ( int i = 0; i < n - 1; ++i )
202  {
203  QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) );
204  Cx += vi.x();
205  Cy += vi.y();
206  }
207  return QgsPointV2( Cx / ( n - 1 ), Cy / ( n - 1 ) );
208  }
209  else
210  {
211  return QgsPointV2( v0.x() + Cx / ( 3. * A ), v0.y() + Cy / ( 3. * A ) );
212  }
213 }
214 
216 {
217  if ( type == mWkbType )
218  return true;
219 
221  return false;
222 
223  bool needZ = QgsWKBTypes::hasZ( type );
224  bool needM = QgsWKBTypes::hasM( type );
225  if ( !needZ )
226  {
227  dropZValue();
228  }
229  else if ( !is3D() )
230  {
231  addZValue();
232  }
233 
234  if ( !needM )
235  {
236  dropMValue();
237  }
238  else if ( !isMeasure() )
239  {
240  addMValue();
241  }
242 
243  return true;
244 }
245 
247 {
248  QgsVertexId vId;
249  QgsPointV2 vertex;
250  return !nextVertex( vId, vertex );
251 }
252 
253 
255 {
256  Q_UNUSED( tolerance );
257  Q_UNUSED( toleranceType );
258  return clone();
259 }
260 
double & rx()
Returns a reference to the x-coordinate of this point.
Definition: qgspointv2.h:94
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:757
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:714
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
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:667
QString wktTypeStr() const
Returns the WKT type string of the geometry.
virtual 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:781
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
double & ry()
Returns a reference to the y-coordinate of this point.
Definition: qgspointv2.h:102
virtual QgsAbstractGeometryV2 * clone() const =0
Clones the geometry by performing a deep copy.
virtual QgsAbstractGeometryV2 * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
virtual QgsPointV2 vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.