QGIS API Documentation  2.12.0-Lyon
qgscompoundcurvev2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscompoundcurvev2.cpp
3  ----------------------
4  begin : September 2014
5  copyright : (C) 2014 by Marco Hugentobler
6  email : marco at sourcepole dot ch
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 "qgscompoundcurvev2.h"
19 #include "qgsapplication.h"
20 #include "qgscircularstringv2.h"
21 #include "qgsgeometryutils.h"
22 #include "qgslinestringv2.h"
23 #include "qgswkbptr.h"
24 #include <QPainter>
25 #include <QPainterPath>
26 
27 
29 {
30 
31 }
32 
34 {
35  clear();
36 }
37 
39 {
40  Q_FOREACH ( const QgsCurveV2* c, curve.mCurves )
41  {
42  mCurves.append( static_cast<QgsCurveV2*>( c->clone() ) );
43  }
44 }
45 
47 {
48  if ( &curve != this )
49  {
50  QgsCurveV2::operator=( curve );
51  Q_FOREACH ( const QgsCurveV2* c, curve.mCurves )
52  {
53  mCurves.append( static_cast<QgsCurveV2*>( c->clone() ) );
54  }
55  }
56  return *this;
57 }
58 
60 {
61  return new QgsCompoundCurveV2( *this );
62 }
63 
65 {
66  qDeleteAll( mCurves );
67  mCurves.clear();
69 }
70 
72 {
73  if ( mCurves.size() < 1 )
74  {
75  return QgsRectangle();
76  }
77 
78  QgsRectangle bbox = mCurves.at( 0 )->calculateBoundingBox();
79  for ( int i = 1; i < mCurves.size(); ++i )
80  {
81  QgsRectangle curveBox = mCurves.at( i )->calculateBoundingBox();
82  bbox.combineExtentWith( &curveBox );
83  }
84  return bbox;
85 }
86 
87 bool QgsCompoundCurveV2::fromWkb( const unsigned char* wkb )
88 {
89  clear();
90  if ( !wkb )
91  {
92  return false;
93  }
94 
95  QgsConstWkbPtr wkbPtr( wkb );
96  QgsWKBTypes::Type type = wkbPtr.readHeader();
98  {
99  return false;
100  }
101  mWkbType = type;
102 
103  int nCurves;
104  wkbPtr >> nCurves;
105  QgsCurveV2* currentCurve = 0;
106  int currentCurveSize = 0;
107  for ( int i = 0; i < nCurves; ++i )
108  {
109  wkbPtr += 1; //skip endian
110  QgsWKBTypes::Type curveType;
111  wkbPtr >> curveType;
112  wkbPtr -= ( 1 + sizeof( int ) );
113  if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::LineString )
114  {
115  currentCurve = new QgsLineStringV2();
116  }
117  else if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::CircularString )
118  {
119  currentCurve = new QgsCircularStringV2();
120  }
121  else
122  {
123  return false;
124  }
125  currentCurve->fromWkb( wkbPtr );
126  currentCurveSize = currentCurve->wkbSize();
127  mCurves.append( currentCurve );
128  wkbPtr += currentCurveSize;
129  }
130  return true;
131 }
132 
134 {
135  clear();
136 
138 
139  if ( QgsWKBTypes::flatType( parts.first ) != QgsWKBTypes::parseType( geometryType() ) )
140  return false;
141  mWkbType = parts.first;
142 
143  QString defaultChildWkbType = QString( "LineString%1%2" ).arg( is3D() ? "Z" : "", isMeasure() ? "M" : "" );
144 
145  Q_FOREACH ( const QString& childWkt, QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType ) )
146  {
148 
149  if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::LineString )
150  mCurves.append( new QgsLineStringV2() );
151  else if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::CircularString )
152  mCurves.append( new QgsCircularStringV2() );
153  else
154  {
155  clear();
156  return false;
157  }
158  if ( !mCurves.back()->fromWkt( childWkt ) )
159  {
160  clear();
161  return false;
162  }
163  }
164 
165  //scan through curves and check if dimensionality of curves is different to compound curve.
166  //if so, update the type dimensionality of the compound curve to match
167  bool hasZ = false;
168  bool hasM = false;
169  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
170  {
171  hasZ = hasZ || curve->is3D();
172  hasM = hasM || curve->isMeasure();
173  if ( hasZ && hasM )
174  break;
175  }
176  if ( hasZ )
177  addZValue( 0 );
178  if ( hasM )
179  addMValue( 0 );
180 
181  return true;
182 }
183 
185 {
186  int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
187  Q_FOREACH ( const QgsCurveV2 *curve, mCurves )
188  {
189  size += curve->wkbSize();
190  }
191  return size;
192 }
193 
194 unsigned char* QgsCompoundCurveV2::asWkb( int& binarySize ) const
195 {
196  binarySize = wkbSize();
197  unsigned char* geomPtr = new unsigned char[binarySize];
198  QgsWkbPtr wkb( geomPtr );
199  wkb << static_cast<char>( QgsApplication::endian() );
200  wkb << static_cast<quint32>( wkbType() );
201  wkb << static_cast<quint32>( mCurves.size() );
202  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
203  {
204  int curveWkbLen = 0;
205  unsigned char* curveWkb = curve->asWkb( curveWkbLen );
206  memcpy( wkb, curveWkb, curveWkbLen );
207  wkb += curveWkbLen;
208  delete[] curveWkb;
209  }
210  return geomPtr;
211 }
212 
213 QString QgsCompoundCurveV2::asWkt( int precision ) const
214 {
215  QString wkt = wktTypeStr() + " (";
216  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
217  {
218  QString childWkt = curve->asWkt( precision );
219  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
220  {
221  // Type names of linear geometries are omitted
222  childWkt = childWkt.mid( childWkt.indexOf( "(" ) );
223  }
224  wkt += childWkt + ",";
225  }
226  if ( wkt.endsWith( "," ) )
227  {
228  wkt.chop( 1 );
229  }
230  wkt += ")";
231  return wkt;
232 }
233 
234 QDomElement QgsCompoundCurveV2::asGML2( QDomDocument& doc, int precision, const QString& ns ) const
235 {
236  // GML2 does not support curves
237  QgsLineStringV2* line = curveToLine();
238  QDomElement gml = line->asGML2( doc, precision, ns );
239  delete line;
240  return gml;
241 }
242 
243 QDomElement QgsCompoundCurveV2::asGML3( QDomDocument& doc, int precision, const QString& ns ) const
244 {
245  QDomElement elemCurve = doc.createElementNS( ns, "Curve" );
246 
247  QDomElement elemSegments = doc.createElementNS( ns, "segments" );
248 
249  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
250  {
251  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
252  {
253  QList<QgsPointV2> pts;
254  curve->points( pts );
255 
256  QDomElement elemLineStringSegment = doc.createElementNS( ns, "LineStringSegment" );
257  elemLineStringSegment.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, is3D() ) );
258  elemSegments.appendChild( elemLineStringSegment );
259  }
260  else if ( dynamic_cast<const QgsCircularStringV2*>( curve ) )
261  {
262  QList<QgsPointV2> pts;
263  curve->points( pts );
264 
265  QDomElement elemArcString = doc.createElementNS( ns, "ArcString" );
266  elemArcString.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, is3D() ) );
267  elemSegments.appendChild( elemArcString );
268  }
269  }
270  elemCurve.appendChild( elemSegments );
271  return elemCurve;
272 }
273 
274 QString QgsCompoundCurveV2::asJSON( int precision ) const
275 {
276  // GeoJSON does not support curves
277  QgsLineStringV2* line = curveToLine();
278  QString json = line->asJSON( precision );
279  delete line;
280  return json;
281 }
282 
284 {
285  double length = 0;
287  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
288  {
289  length += ( *curveIt )->length();
290  }
291  return length;
292 }
293 
295 {
296  if ( mCurves.size() < 1 )
297  {
298  return QgsPointV2();
299  }
300  return mCurves.at( 0 )->startPoint();
301 }
302 
304 {
305  if ( mCurves.size() < 1 )
306  {
307  return QgsPointV2();
308  }
309  return mCurves.at( mCurves.size() - 1 )->endPoint();
310 }
311 
313 {
314  pts.clear();
315  if ( mCurves.size() < 1 )
316  {
317  return;
318  }
319 
320  mCurves[0]->points( pts );
321  for ( int i = 1; i < mCurves.size(); ++i )
322  {
323  QList<QgsPointV2> pList;
324  mCurves[i]->points( pList );
325  pList.removeFirst(); //first vertex already added in previous line
326  pts.append( pList );
327  }
328 }
329 
331 {
332  int nPoints = 0;
333  int nCurves = mCurves.size();
334  if ( nCurves < 1 )
335  {
336  return 0;
337  }
338 
339  for ( int i = 0; i < nCurves; ++i )
340  {
341  nPoints += mCurves.at( i )->numPoints() - 1; //last vertex is equal to first of next section
342  }
343  nPoints += 1; //last vertex was removed above
344  return nPoints;
345 }
346 
348 {
350  QgsLineStringV2* line = new QgsLineStringV2();
351  QgsLineStringV2* currentLine = 0;
352  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
353  {
354  currentLine = ( *curveIt )->curveToLine();
355  line->append( currentLine );
356  delete currentLine;
357  }
358  return line;
359 }
360 
362 {
363  if ( i >= mCurves.size() )
364  {
365  return 0;
366  }
367  return mCurves.at( i );
368 }
369 
371 {
372  if ( c )
373  {
374  mCurves.append( c );
375 
377  {
379  }
380  }
381 }
382 
384 {
385  if ( mCurves.size() - 1 < i )
386  {
387  return;
388  }
389 
390  delete( mCurves[i] );
391  mCurves.removeAt( i );
392 }
393 
395 {
397  {
399  }
400 
401  //is last curve QgsLineStringV2
402  QgsCurveV2* lastCurve = 0;
403  if ( mCurves.size() > 0 )
404  {
405  lastCurve = mCurves.at( mCurves.size() - 1 );
406  }
407 
408  QgsLineStringV2* line = 0;
409  if ( !lastCurve || lastCurve->geometryType() != "LineString" )
410  {
411  line = new QgsLineStringV2();
412  mCurves.append( line );
413  if ( lastCurve )
414  {
415  line->addVertex( lastCurve->endPoint() );
416  }
417  lastCurve = line;
418  }
419  else //create new QgsLineStringV2* with point in it
420  {
421  line = static_cast<QgsLineStringV2*>( lastCurve );
422  }
423  line->addVertex( pt );
424 }
425 
427 {
429  for ( ; it != mCurves.constEnd(); ++it )
430  {
431  ( *it )->draw( p );
432  }
433 }
434 
436 {
437  QList< QgsCurveV2* >::iterator it = mCurves.begin();
438  for ( ; it != mCurves.end(); ++it )
439  {
440  ( *it )->transform( ct, d );
441  }
442 }
443 
445 {
446  QList< QgsCurveV2* >::iterator it = mCurves.begin();
447  for ( ; it != mCurves.end(); ++it )
448  {
449  ( *it )->transform( t );
450  }
451 }
452 
454 {
455  QPainterPath pp;
457  for ( ; it != mCurves.constEnd(); ++it )
458  {
459  ( *it )->addToPainterPath( pp );
460  }
461  path.addPath( pp );
462 }
463 
465 {
466  QPainterPath pp;
468  for ( ; it != mCurves.constEnd(); ++it )
469  {
470  ( *it )->addToPainterPath( pp );
471  }
472  p.drawPath( pp );
473 }
474 
475 bool QgsCompoundCurveV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex )
476 {
477  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
478  if ( curveIds.size() < 1 )
479  {
480  return false;
481  }
482  int curveId = curveIds.at( 0 ).first;
483  if ( curveId >= mCurves.size() )
484  {
485  return false;
486  }
487 
488  bool success = mCurves[curveId]->insertVertex( curveIds.at( 0 ).second, vertex );
489  if ( success )
490  {
491  mBoundingBox = QgsRectangle(); //bbox changed
492  }
493  return success;
494 }
495 
496 bool QgsCompoundCurveV2::moveVertex( const QgsVertexId& position, const QgsPointV2& newPos )
497 {
498  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
499  QList< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
500  for ( ; idIt != curveIds.constEnd(); ++idIt )
501  {
502  mCurves[idIt->first]->moveVertex( idIt->second, newPos );
503  }
504 
505  bool success = curveIds.size() > 0;
506  if ( success )
507  {
508  mBoundingBox = QgsRectangle(); //bbox changed
509  }
510  return success;
511 }
512 
514 {
515  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
516  QList< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
517  for ( ; idIt != curveIds.constEnd(); ++idIt )
518  {
519  mCurves[idIt->first]->deleteVertex( idIt->second );
520  }
521 
522  bool success = curveIds.size() > 0;
523  if ( success )
524  {
525  mBoundingBox = QgsRectangle(); //bbox changed
526  }
527  return success;
528 }
529 
530 QList< QPair<int, QgsVertexId> > QgsCompoundCurveV2::curveVertexId( const QgsVertexId& id ) const
531 {
533 
534  int currentVertexIndex = 0;
535  for ( int i = 0; i < mCurves.size(); ++i )
536  {
537  int increment = mCurves.at( i )->numPoints() - 1;
538  if ( id.vertex >= currentVertexIndex && id.vertex <= currentVertexIndex + increment )
539  {
540  int curveVertexId = id.vertex - currentVertexIndex;
541  QgsVertexId vid; vid.part = 0; vid.ring = 0; vid.vertex = curveVertexId;
542  curveIds.append( qMakePair( i, vid ) );
543  if ( curveVertexId == increment && i < ( mCurves.size() - 1 ) ) //add first vertex of next curve
544  {
545  vid.vertex = 0;
546  curveIds.append( qMakePair( i + 1, vid ) );
547  }
548  }
549  currentVertexIndex += increment;
550  }
551 
552  return curveIds;
553 }
554 
555 double QgsCompoundCurveV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
556 {
557  return QgsGeometryUtils::closestSegmentFromComponents( mCurves, QgsGeometryUtils::VERTEX, pt, segmentPt, vertexAfter, leftOf, epsilon );
558 }
559 
561 {
562  int currentVertexId = 0;
563  for ( int j = 0; j < mCurves.size(); ++j )
564  {
565  int nCurvePoints = mCurves.at( j )->numPoints();
566  if (( i - currentVertexId ) < nCurvePoints )
567  {
568  return ( mCurves.at( j )->pointAt( i - currentVertexId, vertex, type ) );
569  }
570  currentVertexId += ( nCurvePoints - 1 );
571  }
572  return false;
573 }
574 
575 void QgsCompoundCurveV2::sumUpArea( double& sum ) const
576 {
578  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
579  {
580  ( *curveIt )->sumUpArea( sum );
581  }
582 }
583 
585 {
586  if ( numPoints() < 1 || isClosed() )
587  {
588  return;
589  }
590  addVertex( startPoint() );
591 }
592 
594 {
596  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
597  {
598  if (( *curveIt )->hasCurvedSegments() )
599  {
600  return true;
601  }
602  }
603  return false;
604 }
605 
606 double QgsCompoundCurveV2::vertexAngle( const QgsVertexId& vertex ) const
607 {
608  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( vertex );
609  if ( curveIds.size() == 1 )
610  {
611  QgsCurveV2* curve = mCurves[curveIds.at( 0 ).first];
612  return curve->vertexAngle( curveIds.at( 0 ).second );
613  }
614  else if ( curveIds.size() > 1 )
615  {
616  QgsCurveV2* curve1 = mCurves[curveIds.at( 0 ).first];
617  QgsCurveV2* curve2 = mCurves[curveIds.at( 1 ).first];
618  double angle1 = curve1->vertexAngle( curveIds.at( 0 ).second );
619  double angle2 = curve2->vertexAngle( curveIds.at( 1 ).second );
620  return QgsGeometryUtils::averageAngle( angle1, angle2 );
621  }
622  else
623  {
624  return 0.0;
625  }
626 }
627 
628 bool QgsCompoundCurveV2::addZValue( double zValue )
629 {
630  if ( QgsWKBTypes::hasZ( mWkbType ) )
631  return false;
632 
634 
635  Q_FOREACH ( QgsCurveV2* curve, mCurves )
636  {
637  curve->addZValue( zValue );
638  }
639  return true;
640 }
641 
642 bool QgsCompoundCurveV2::addMValue( double mValue )
643 {
644  if ( QgsWKBTypes::hasM( mWkbType ) )
645  return false;
646 
648 
649  Q_FOREACH ( QgsCurveV2* curve, mCurves )
650  {
651  curve->addMValue( mValue );
652  }
653  return true;
654 }
655 
void addPath(const QPainterPath &path)
void clear()
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry.
virtual QgsLineStringV2 * curveToLine() const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
virtual double vertexAngle(const QgsVertexId &vertex) const =0
Returns approximate rotation angle for a vertex.
static QPair< QgsWKBTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
void close()
Appends first point if not already closed.
virtual QgsAbstractGeometryV2 & operator=(const QgsAbstractGeometryV2 &geom)
QDomNode appendChild(const QDomNode &newChild)
bool pointAt(int i, QgsPointV2 &vertex, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Angle between two linear segments.
Circular string geometry type.
virtual void points(QList< QgsPointV2 > &pt) const =0
Returns a list of points within the curve.
virtual QgsPointV2 endPoint() const override
Returns the end point of the curve.
virtual bool deleteVertex(const QgsVertexId &position) override
Deletes a vertex within the geometry.
virtual QgsPointV2 startPoint() const override
Returns the starting point of the curve.
void removeFirst()
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform) override
Transforms the geometry using a coordinate transform.
const T & at(int i) const
void removeAt(int i)
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry.
virtual bool insertVertex(const QgsVertexId &position, const QgsPointV2 &vertex) override
Inserts a vertex into the geometry.
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType="")
Parses a WKT string and returns of list of blocks contained in the WKT.
TransformDirection
Enum used to indicate the direction (forward or inverse) of the transform.
unsigned char * asWkb(int &binarySize) const override
Returns a WKB representation of the geometry.
static double closestSegmentFromComponents(T &container, componentType ctype, const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon)
virtual QgsRectangle calculateBoundingBox() const override
Calculates the minimal bounding box for the geometry.
void append(const QgsLineStringV2 *line)
void sumUpArea(double &sum) const override
Calculates the area of the curve.
double vertexAngle(const QgsVertexId &vertex) const override
Returns approximate rotation angle for a vertex.
QDomElement createElementNS(const QString &nsURI, const QString &qName)
void chop(int n)
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path.
static endian_t endian()
Returns whether this machine uses big or little endian.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
virtual int wkbSize() const =0
Returns the size of the WKB representation of the geometry.
QgsCompoundCurveV2 & operator=(const QgsCompoundCurveV2 &curve)
void removeCurve(int i)
Removes a curve from the geometry.
int size() const
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
virtual QgsLineStringV2 * curveToLine() const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
QgsWKBTypes::Type readHeader() const
Definition: qgswkbptr.cpp:8
static Type flatType(Type type)
Definition: qgswkbtypes.cpp:46
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
void append(const T &value)
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Utility class for identifying a unique vertex within a geometry.
bool isMeasure() const
Returns true if the geometry contains m values.
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
Line string geometry type.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
virtual QString geometryType() const override
Returns a unique string representing the geometry type.
void addVertex(const QgsPointV2 &pt)
Adds a vertex to the end of the geometry.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
virtual bool fromWkb(const unsigned char *wkb)=0
Sets the geometry from a WKB string.
Point geometry type.
Definition: qgspointv2.h:29
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
virtual unsigned char * asWkb(int &binarySize) const =0
Returns a WKB representation of the geometry.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
const QgsCurveV2 * curveAt(int i) const
Returns the curve at the specified index.
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 addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
T & first()
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
Compound curve geometry type.
iterator end()
static QDomElement pointsToGML3(const QList< QgsPointV2 > &points, QDomDocument &doc, int precision, const QString &ns, bool is3D)
Returns a gml::posList DOM element.
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
void addCurve(QgsCurveV2 *c)
Adds a curve to the geometr (takes ownership)
void addVertex(const QgsPointV2 &pt)
virtual QgsPointV2 endPoint() const =0
Returns the end point of the curve.
QString mid(int position, int n) const
void drawPath(const QPainterPath &path)
virtual bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
virtual QgsCompoundCurveV2 * clone() const override
Clones the geometry by performing a deep copy.
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry.
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:27
int wkbSize() const override
Returns the size of the WKB representation of the geometry.
virtual void points(QList< QgsPointV2 > &pts) const override
Returns a list of points within the curve.
Class for doing transforms between two map coordinate systems.
virtual QString asWkt(int precision=17) const =0
Returns a WKT representation of the geometry.
virtual double closestSegment(const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon) const override
Searches for the closest segment of the geometry to a given point.
static Type parseType(const QString &wktStr)
Definition: qgswkbtypes.cpp:56
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'.
const_iterator constEnd() const
const_iterator constBegin() const
virtual QgsAbstractGeometryV2 * clone() const =0
Clones the geometry by performing a deep copy.
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
virtual bool fromWkb(const unsigned char *wkb) override
Sets the geometry from a WKB string.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
virtual int numPoints() const override
Returns the number of points in the curve.
QDomElement asGML3(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML3 representation of the geometry.
virtual double length() const override
Returns the length of the geometry.
T & back()
int nCurves() const
Returns the number of curves in the geometry.
iterator begin()
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
virtual void clear() override
Clears the geometry, ie reset it to a null geometry.
virtual bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.