QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 
QString wktTypeStr() const
Returns the WKT type string of the geometry.
double & rx()
Returns a reference to the x-coordinate of this point.
Definition: qgspointv2.h:94
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool isEmpty() const
Returns true if the geometry is empty.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
virtual QgsCoordinateSequenceV2 coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
virtual QgsAbstractGeometryV2 & operator=(const QgsAbstractGeometryV2 &geom)
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.
double y() const
Returns the point&#39;s y-coordinate.
Definition: qgspointv2.h:74
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:667
int size() const
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
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.
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.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspointv2.h:34
virtual QgsAbstractGeometryV2 * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
double x() const
Returns the point&#39;s x-coordinate.
Definition: qgspointv2.h:68
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 int nCoordinates() const
Returns the number of nodes contained in the geometry.
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
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:366
virtual QgsPointV2 centroid() const
Returns the centroid of the geometry.
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 QgsRectangle calculateBoundingBox() const
Default calculator for the minimal bounding box for the geometry.
virtual QgsPointV2 vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.