QGIS API Documentation  2.14.18-Essen
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 
38 bool QgsCompoundCurveV2::operator==( const QgsCurveV2& other ) const
39 {
40  const QgsCompoundCurveV2* otherCurve = dynamic_cast< const QgsCompoundCurveV2* >( &other );
41  if ( !otherCurve )
42  return false;
43 
44  return *otherCurve == *this;
45 }
46 
47 bool QgsCompoundCurveV2::operator!=( const QgsCurveV2& other ) const
48 {
49  return !operator==( other );
50 }
51 
53 {
54  Q_FOREACH ( const QgsCurveV2* c, curve.mCurves )
55  {
56  mCurves.append( static_cast<QgsCurveV2*>( c->clone() ) );
57  }
58 }
59 
61 {
62  if ( &curve != this )
63  {
64  clearCache();
65  QgsCurveV2::operator=( curve );
66  Q_FOREACH ( const QgsCurveV2* c, curve.mCurves )
67  {
68  mCurves.append( static_cast<QgsCurveV2*>( c->clone() ) );
69  }
70  }
71  return *this;
72 }
73 
75 {
76  return new QgsCompoundCurveV2( *this );
77 }
78 
80 {
81  qDeleteAll( mCurves );
82  mCurves.clear();
84  clearCache();
85 }
86 
88 {
89  if ( mCurves.size() < 1 )
90  {
91  return QgsRectangle();
92  }
93 
94  QgsRectangle bbox = mCurves.at( 0 )->boundingBox();
95  for ( int i = 1; i < mCurves.size(); ++i )
96  {
97  QgsRectangle curveBox = mCurves.at( i )->boundingBox();
98  bbox.combineExtentWith( &curveBox );
99  }
100  return bbox;
101 }
102 
104 {
105  clear();
106  if ( !wkbPtr )
107  {
108  return false;
109  }
110 
111  QgsWKBTypes::Type type = wkbPtr.readHeader();
113  {
114  return false;
115  }
116  mWkbType = type;
117 
118  int nCurves;
119  wkbPtr >> nCurves;
120  QgsCurveV2* currentCurve = nullptr;
121  int currentCurveSize = 0;
122  for ( int i = 0; i < nCurves; ++i )
123  {
124  QgsWKBTypes::Type curveType = wkbPtr.readHeader();
125  wkbPtr -= 1 + sizeof( int );
126  if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::LineString )
127  {
128  currentCurve = new QgsLineStringV2();
129  }
130  else if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::CircularString )
131  {
132  currentCurve = new QgsCircularStringV2();
133  }
134  else
135  {
136  return false;
137  }
138  currentCurve->fromWkb( wkbPtr );
139  currentCurveSize = currentCurve->wkbSize();
140  mCurves.append( currentCurve );
141  wkbPtr += currentCurveSize;
142  }
143  return true;
144 }
145 
147 {
148  clear();
149 
151 
152  if ( QgsWKBTypes::flatType( parts.first ) != QgsWKBTypes::parseType( geometryType() ) )
153  return false;
154  mWkbType = parts.first;
155 
156  QString defaultChildWkbType = QString( "LineString%1%2" ).arg( is3D() ? "Z" : "", isMeasure() ? "M" : "" );
157 
158  Q_FOREACH ( const QString& childWkt, QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType ) )
159  {
161 
162  if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::LineString )
163  mCurves.append( new QgsLineStringV2() );
164  else if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::CircularString )
165  mCurves.append( new QgsCircularStringV2() );
166  else
167  {
168  clear();
169  return false;
170  }
171  if ( !mCurves.back()->fromWkt( childWkt ) )
172  {
173  clear();
174  return false;
175  }
176  }
177 
178  //scan through curves and check if dimensionality of curves is different to compound curve.
179  //if so, update the type dimensionality of the compound curve to match
180  bool hasZ = false;
181  bool hasM = false;
182  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
183  {
184  hasZ = hasZ || curve->is3D();
185  hasM = hasM || curve->isMeasure();
186  if ( hasZ && hasM )
187  break;
188  }
189  if ( hasZ )
190  addZValue( 0 );
191  if ( hasM )
192  addMValue( 0 );
193 
194  return true;
195 }
196 
198 {
199  int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
200  Q_FOREACH ( const QgsCurveV2 *curve, mCurves )
201  {
202  size += curve->wkbSize();
203  }
204  return size;
205 }
206 
207 unsigned char* QgsCompoundCurveV2::asWkb( int& binarySize ) const
208 {
209  binarySize = wkbSize();
210  unsigned char* geomPtr = new unsigned char[binarySize];
211  QgsWkbPtr wkb( geomPtr, binarySize );
212  wkb << static_cast<char>( QgsApplication::endian() );
213  wkb << static_cast<quint32>( wkbType() );
214  wkb << static_cast<quint32>( mCurves.size() );
215  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
216  {
217  int curveWkbLen = 0;
218  unsigned char* curveWkb = curve->asWkb( curveWkbLen );
219  memcpy( wkb, curveWkb, curveWkbLen );
220  wkb += curveWkbLen;
221  delete[] curveWkb;
222  }
223  return geomPtr;
224 }
225 
226 QString QgsCompoundCurveV2::asWkt( int precision ) const
227 {
228  QString wkt = wktTypeStr() + " (";
229  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
230  {
231  QString childWkt = curve->asWkt( precision );
232  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
233  {
234  // Type names of linear geometries are omitted
235  childWkt = childWkt.mid( childWkt.indexOf( '(' ) );
236  }
237  wkt += childWkt + ',';
238  }
239  if ( wkt.endsWith( ',' ) )
240  {
241  wkt.chop( 1 );
242  }
243  wkt += ')';
244  return wkt;
245 }
246 
247 QDomElement QgsCompoundCurveV2::asGML2( QDomDocument& doc, int precision, const QString& ns ) const
248 {
249  // GML2 does not support curves
250  QgsLineStringV2* line = curveToLine();
251  QDomElement gml = line->asGML2( doc, precision, ns );
252  delete line;
253  return gml;
254 }
255 
256 QDomElement QgsCompoundCurveV2::asGML3( QDomDocument& doc, int precision, const QString& ns ) const
257 {
258  QDomElement compoundCurveElem = doc.createElementNS( ns, "CompositeCurve" );
259  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
260  {
261  QDomElement curveMemberElem = doc.createElementNS( ns, "curveMember" );
262  QDomElement curveElem = curve->asGML3( doc, precision, ns );
263  curveMemberElem.appendChild( curveElem );
264  compoundCurveElem.appendChild( curveMemberElem );
265  }
266 
267  return compoundCurveElem;
268 }
269 
270 QString QgsCompoundCurveV2::asJSON( int precision ) const
271 {
272  // GeoJSON does not support curves
273  QgsLineStringV2* line = curveToLine();
274  QString json = line->asJSON( precision );
275  delete line;
276  return json;
277 }
278 
280 {
281  double length = 0;
283  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
284  {
285  length += ( *curveIt )->length();
286  }
287  return length;
288 }
289 
291 {
292  if ( mCurves.size() < 1 )
293  {
294  return QgsPointV2();
295  }
296  return mCurves.at( 0 )->startPoint();
297 }
298 
300 {
301  if ( mCurves.size() < 1 )
302  {
303  return QgsPointV2();
304  }
305  return mCurves.at( mCurves.size() - 1 )->endPoint();
306 }
307 
309 {
310  pts.clear();
311  if ( mCurves.size() < 1 )
312  {
313  return;
314  }
315 
316  mCurves[0]->points( pts );
317  for ( int i = 1; i < mCurves.size(); ++i )
318  {
319  QgsPointSequenceV2 pList;
320  mCurves[i]->points( pList );
321  pList.removeFirst(); //first vertex already added in previous line
322  pts.append( pList );
323  }
324 }
325 
327 {
328  int nPoints = 0;
329  int nCurves = mCurves.size();
330  if ( nCurves < 1 )
331  {
332  return 0;
333  }
334 
335  for ( int i = 0; i < nCurves; ++i )
336  {
337  nPoints += mCurves.at( i )->numPoints() - 1; //last vertex is equal to first of next section
338  }
339  nPoints += 1; //last vertex was removed above
340  return nPoints;
341 }
342 
344 {
346  QgsLineStringV2* line = new QgsLineStringV2();
347  QgsLineStringV2* currentLine = nullptr;
348  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
349  {
350  currentLine = ( *curveIt )->curveToLine();
351  line->append( currentLine );
352  delete currentLine;
353  }
354  return line;
355 }
356 
358 {
359  if ( i >= mCurves.size() )
360  {
361  return nullptr;
362  }
363  return mCurves.at( i );
364 }
365 
367 {
368  if ( c )
369  {
370  mCurves.append( c );
371 
373  {
375  }
376  clearCache();
377  }
378 }
379 
381 {
382  if ( mCurves.size() - 1 < i )
383  {
384  return;
385  }
386 
387  delete( mCurves.at( i ) );
388  mCurves.removeAt( i );
389  clearCache();
390 }
391 
393 {
395  {
397  }
398 
399  //is last curve QgsLineStringV2
400  QgsCurveV2* lastCurve = nullptr;
401  if ( !mCurves.isEmpty() )
402  {
403  lastCurve = mCurves.at( mCurves.size() - 1 );
404  }
405 
406  QgsLineStringV2* line = nullptr;
407  if ( !lastCurve || lastCurve->geometryType() != "LineString" )
408  {
409  line = new QgsLineStringV2();
410  mCurves.append( line );
411  if ( lastCurve )
412  {
413  line->addVertex( lastCurve->endPoint() );
414  }
415  lastCurve = line;
416  }
417  else //create new QgsLineStringV2* with point in it
418  {
419  line = static_cast<QgsLineStringV2*>( lastCurve );
420  }
421  line->addVertex( pt );
422  clearCache();
423 }
424 
426 {
428  for ( ; it != mCurves.constEnd(); ++it )
429  {
430  ( *it )->draw( p );
431  }
432 }
433 
435 {
436  Q_FOREACH ( QgsCurveV2* curve, mCurves )
437  {
438  curve->transform( ct, d );
439  }
440  clearCache();
441 }
442 
444 {
445  Q_FOREACH ( QgsCurveV2* curve, mCurves )
446  {
447  curve->transform( t );
448  }
449  clearCache();
450 }
451 
453 {
454  QPainterPath pp;
456  for ( ; it != mCurves.constEnd(); ++it )
457  {
458  ( *it )->addToPainterPath( pp );
459  }
460  path.addPath( pp );
461 }
462 
464 {
465  QPainterPath pp;
467  for ( ; it != mCurves.constEnd(); ++it )
468  {
469  ( *it )->addToPainterPath( pp );
470  }
471  p.drawPath( pp );
472 }
473 
475 {
476  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
477  if ( curveIds.size() < 1 )
478  {
479  return false;
480  }
481  int curveId = curveIds.at( 0 ).first;
482  if ( curveId >= mCurves.size() )
483  {
484  return false;
485  }
486 
487  bool success = mCurves.at( curveId )->insertVertex( curveIds.at( 0 ).second, vertex );
488  if ( success )
489  {
490  clearCache(); //bbox changed
491  }
492  return success;
493 }
494 
496 {
497  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
498  QList< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
499  for ( ; idIt != curveIds.constEnd(); ++idIt )
500  {
501  mCurves.at( idIt->first )->moveVertex( idIt->second, newPos );
502  }
503 
504  bool success = !curveIds.isEmpty();
505  if ( success )
506  {
507  clearCache(); //bbox changed
508  }
509  return success;
510 }
511 
513 {
514  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
515  QList< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
516  for ( ; idIt != curveIds.constEnd(); ++idIt )
517  {
518  mCurves.at( idIt->first )->deleteVertex( idIt->second );
519  }
520 
521  bool success = !curveIds.isEmpty();
522  if ( success )
523  {
524  clearCache(); //bbox changed
525  }
526  return success;
527 }
528 
529 QList< QPair<int, QgsVertexId> > QgsCompoundCurveV2::curveVertexId( QgsVertexId id ) const
530 {
532 
533  int currentVertexIndex = 0;
534  for ( int i = 0; i < mCurves.size(); ++i )
535  {
536  int increment = mCurves.at( i )->numPoints() - 1;
537  if ( id.vertex >= currentVertexIndex && id.vertex <= currentVertexIndex + increment )
538  {
539  int curveVertexId = id.vertex - currentVertexIndex;
540  QgsVertexId vid;
541  vid.part = 0;
542  vid.ring = 0;
543  vid.vertex = curveVertexId;
544  curveIds.append( qMakePair( i, vid ) );
545  if ( curveVertexId == increment && i < ( mCurves.size() - 1 ) ) //add first vertex of next curve
546  {
547  vid.vertex = 0;
548  curveIds.append( qMakePair( i + 1, vid ) );
549  }
550  }
551  currentVertexIndex += increment;
552  }
553 
554  return curveIds;
555 }
556 
557 double QgsCompoundCurveV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
558 {
559  return QgsGeometryUtils::closestSegmentFromComponents( mCurves, QgsGeometryUtils::VERTEX, pt, segmentPt, vertexAfter, leftOf, epsilon );
560 }
561 
563 {
564  int currentVertexId = 0;
565  for ( int j = 0; j < mCurves.size(); ++j )
566  {
567  int nCurvePoints = mCurves.at( j )->numPoints();
568  if (( node - currentVertexId ) < nCurvePoints )
569  {
570  return ( mCurves.at( j )->pointAt( node - currentVertexId, point, type ) );
571  }
572  currentVertexId += ( nCurvePoints - 1 );
573  }
574  return false;
575 }
576 
577 void QgsCompoundCurveV2::sumUpArea( double& sum ) const
578 {
580  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
581  {
582  ( *curveIt )->sumUpArea( sum );
583  }
584 }
585 
587 {
588  if ( numPoints() < 1 || isClosed() )
589  {
590  return;
591  }
592  addVertex( startPoint() );
593 }
594 
596 {
598  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
599  {
600  if (( *curveIt )->hasCurvedSegments() )
601  {
602  return true;
603  }
604  }
605  return false;
606 }
607 
609 {
610  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( vertex );
611  if ( curveIds.size() == 1 )
612  {
613  QgsCurveV2* curve = mCurves[curveIds.at( 0 ).first];
614  return curve->vertexAngle( curveIds.at( 0 ).second );
615  }
616  else if ( curveIds.size() > 1 )
617  {
618  QgsCurveV2* curve1 = mCurves[curveIds.at( 0 ).first];
619  QgsCurveV2* curve2 = mCurves[curveIds.at( 1 ).first];
620  double angle1 = curve1->vertexAngle( curveIds.at( 0 ).second );
621  double angle2 = curve2->vertexAngle( curveIds.at( 1 ).second );
622  return QgsGeometryUtils::averageAngle( angle1, angle2 );
623  }
624  else
625  {
626  return 0.0;
627  }
628 }
629 
631 {
633  Q_FOREACH ( QgsCurveV2* curve, mCurves )
634  {
635  QgsCurveV2* reversedCurve = curve->reversed();
636  clone->addCurve( reversedCurve );
637  }
638  return clone;
639 }
640 
641 bool QgsCompoundCurveV2::addZValue( double zValue )
642 {
643  if ( QgsWKBTypes::hasZ( mWkbType ) )
644  return false;
645 
647 
648  Q_FOREACH ( QgsCurveV2* curve, mCurves )
649  {
650  curve->addZValue( zValue );
651  }
652  clearCache();
653  return true;
654 }
655 
656 bool QgsCompoundCurveV2::addMValue( double mValue )
657 {
658  if ( QgsWKBTypes::hasM( mWkbType ) )
659  return false;
660 
662 
663  Q_FOREACH ( QgsCurveV2* curve, mCurves )
664  {
665  curve->addMValue( mValue );
666  }
667  clearCache();
668  return true;
669 }
670 
672 {
673  if ( !QgsWKBTypes::hasZ( mWkbType ) )
674  return false;
675 
677  Q_FOREACH ( QgsCurveV2* curve, mCurves )
678  {
679  curve->dropZValue();
680  }
681  clearCache();
682  return true;
683 }
684 
686 {
687  if ( !QgsWKBTypes::hasM( mWkbType ) )
688  return false;
689 
691  Q_FOREACH ( QgsCurveV2* curve, mCurves )
692  {
693  curve->dropMValue();
694  }
695  clearCache();
696  return true;
697 }
698 
QString wktTypeStr() const
Returns the WKT type string of the geometry.
virtual QgsCompoundCurveV2 * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
void addPath(const QPainterPath &path)
void clear()
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
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 bool dropMValue()=0
Drops any measure values which exist in the geometry.
virtual QgsLineStringV2 * curveToLine() const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
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 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.
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
Circular string geometry type.
virtual QgsPointV2 endPoint() const override
Returns the end point of the curve.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate rotation angle for a vertex.
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.
TransformDirection
Enum used to indicate the direction (forward or inverse) of the 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(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.
unsigned char * asWkb(int &binarySize) const override
Returns a WKB representation of the geometry.
virtual bool operator==(const QgsCurveV2 &other) const override
static double closestSegmentFromComponents(T &container, componentType ctype, const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon)
virtual QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
void append(const QgsLineStringV2 *line)
Appends the contents of another line string to the end of this line string.
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula).
QDomElement createElementNS(const QString &nsURI, const QString &qName)
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:656
virtual QgsCurveV2 * clone() const override=0
Clones the geometry by performing a deep copy.
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.
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...
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
void append(const T &value)
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:800
virtual bool operator!=(const QgsCurveV2 &other) const override
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:770
virtual QgsCurveV2 * reversed() const =0
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
virtual void clearCache() const override
Clears any cached parameters associated with the geometry, eg bounding boxes.
Definition: qgscurvev2.h:115
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:27
Utility class for identifying a unique vertex within a geometry.
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
Line string geometry type, with support for z-dimension and m-values.
virtual bool fromWkb(QgsConstWkbPtr wkb)=0
Sets the geometry from a WKB string.
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.
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
bool isEmpty() const
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.
virtual bool fromWkb(QgsConstWkbPtr wkb) override
Sets the geometry from a WKB string.
virtual unsigned char * asWkb(int &binarySize) const =0
Returns a WKB representation of the geometry.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform)=0
Transforms the geometry using a coordinate transform.
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()
virtual QDomElement asGML3(QDomDocument &doc, int precision=17, const QString &ns="gml") const =0
Returns a GML3 representation of the geometry.
virtual bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
virtual bool dropMValue() override
Drops any measure values which exist in the geometry.
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
Compound curve geometry type.
virtual void points(QgsPointSequenceV2 &pts) const override
Returns a list of points within the curve.
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
static Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type.
Definition: qgswkbtypes.h:817
void addCurve(QgsCurveV2 *c)
Adds a curve to the geometr (takes ownership)
void addVertex(const QgsPointV2 &pt)
Adds a new vertex to the end of the line string.
virtual QgsPointV2 endPoint() const =0
Returns the end point of the curve.
const QgsCurveV2 * curveAt(int i) const
Returns the curve at the specified index.
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.
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
bool pointAt(int node, QgsPointV2 &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
int wkbSize() const override
Returns the size of the WKB representation of the geometry.
Class for doing transforms between two map coordinate systems.
virtual QString asWkt(int precision=17) const =0
Returns a WKT representation of the geometry.
int nCurves() const
Returns the number of curves in 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 flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:366
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
Definition: qgswkbtypes.cpp:32
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether &#39;thepoint&#39; is left or right of the line from &#39;p1&#39; to &#39;p2&#39;.
QgsWKBTypes::Type readHeader() const
Definition: qgswkbptr.cpp:37
const_iterator constEnd() const
const_iterator constBegin() const
Abstract base class for curved geometry type.
Definition: qgscurvev2.h:32
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()
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
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.
virtual bool moveVertex(QgsVertexId position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry.