QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 {
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 {
55  Q_FOREACH ( const QgsCurveV2* c, curve.mCurves )
56  {
57  mCurves.append( static_cast<QgsCurveV2*>( c->clone() ) );
58  }
59 }
60 
62 {
63  if ( &curve != this )
64  {
65  clearCache();
66  QgsCurveV2::operator=( curve );
67  Q_FOREACH ( const QgsCurveV2* c, curve.mCurves )
68  {
69  mCurves.append( static_cast<QgsCurveV2*>( c->clone() ) );
70  }
71  }
72  return *this;
73 }
74 
76 {
77  return new QgsCompoundCurveV2( *this );
78 }
79 
81 {
83  qDeleteAll( mCurves );
84  mCurves.clear();
85  clearCache();
86 }
87 
89 {
90  if ( mCurves.size() < 1 )
91  {
92  return QgsRectangle();
93  }
94 
95  QgsRectangle bbox = mCurves.at( 0 )->boundingBox();
96  for ( int i = 1; i < mCurves.size(); ++i )
97  {
98  QgsRectangle curveBox = mCurves.at( i )->boundingBox();
99  bbox.combineExtentWith( curveBox );
100  }
101  return bbox;
102 }
103 
105 {
106  clear();
107  if ( !wkbPtr )
108  {
109  return false;
110  }
111 
112  QgsWKBTypes::Type type = wkbPtr.readHeader();
114  {
115  return false;
116  }
117  mWkbType = type;
118 
119  int nCurves;
120  wkbPtr >> nCurves;
121  QgsCurveV2* currentCurve = nullptr;
122  int currentCurveSize = 0;
123  for ( int i = 0; i < nCurves; ++i )
124  {
125  QgsWKBTypes::Type curveType = wkbPtr.readHeader();
126  wkbPtr -= 1 + sizeof( int );
127  if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::LineString )
128  {
129  currentCurve = new QgsLineStringV2();
130  }
131  else if ( QgsWKBTypes::flatType( curveType ) == QgsWKBTypes::CircularString )
132  {
133  currentCurve = new QgsCircularStringV2();
134  }
135  else
136  {
137  return false;
138  }
139  currentCurve->fromWkb( wkbPtr );
140  currentCurveSize = currentCurve->wkbSize();
141  mCurves.append( currentCurve );
142  wkbPtr += currentCurveSize;
143  }
144  return true;
145 }
146 
148 {
149  clear();
150 
152 
153  if ( QgsWKBTypes::flatType( parts.first ) != QgsWKBTypes::CompoundCurve )
154  return false;
155  mWkbType = parts.first;
156 
157  QString defaultChildWkbType = QString( "LineString%1%2" ).arg( is3D() ? "Z" : "", isMeasure() ? "M" : "" );
158 
159  Q_FOREACH ( const QString& childWkt, QgsGeometryUtils::wktGetChildBlocks( parts.second, defaultChildWkbType ) )
160  {
162 
163  if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::LineString )
164  mCurves.append( new QgsLineStringV2() );
165  else if ( QgsWKBTypes::flatType( childParts.first ) == QgsWKBTypes::CircularString )
166  mCurves.append( new QgsCircularStringV2() );
167  else
168  {
169  clear();
170  return false;
171  }
172  if ( !mCurves.back()->fromWkt( childWkt ) )
173  {
174  clear();
175  return false;
176  }
177  }
178 
179  //scan through curves and check if dimensionality of curves is different to compound curve.
180  //if so, update the type dimensionality of the compound curve to match
181  bool hasZ = false;
182  bool hasM = false;
183  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
184  {
185  hasZ = hasZ || curve->is3D();
186  hasM = hasM || curve->isMeasure();
187  if ( hasZ && hasM )
188  break;
189  }
190  if ( hasZ )
191  addZValue( 0 );
192  if ( hasM )
193  addMValue( 0 );
194 
195  return true;
196 }
197 
199 {
200  int size = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
201  Q_FOREACH ( const QgsCurveV2 *curve, mCurves )
202  {
203  size += curve->wkbSize();
204  }
205  return size;
206 }
207 
208 unsigned char* QgsCompoundCurveV2::asWkb( int& binarySize ) const
209 {
210  binarySize = wkbSize();
211  unsigned char* geomPtr = new unsigned char[binarySize];
212  QgsWkbPtr wkb( geomPtr, binarySize );
213  wkb << static_cast<char>( QgsApplication::endian() );
214  wkb << static_cast<quint32>( wkbType() );
215  wkb << static_cast<quint32>( mCurves.size() );
216  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
217  {
218  int curveWkbLen = 0;
219  unsigned char* curveWkb = curve->asWkb( curveWkbLen );
220  memcpy( wkb, curveWkb, curveWkbLen );
221  wkb += curveWkbLen;
222  delete[] curveWkb;
223  }
224  return geomPtr;
225 }
226 
227 QString QgsCompoundCurveV2::asWkt( int precision ) const
228 {
229  QString wkt = wktTypeStr() + " (";
230  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
231  {
232  QString childWkt = curve->asWkt( precision );
233  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
234  {
235  // Type names of linear geometries are omitted
236  childWkt = childWkt.mid( childWkt.indexOf( '(' ) );
237  }
238  wkt += childWkt + ',';
239  }
240  if ( wkt.endsWith( ',' ) )
241  {
242  wkt.chop( 1 );
243  }
244  wkt += ')';
245  return wkt;
246 }
247 
248 QDomElement QgsCompoundCurveV2::asGML2( QDomDocument& doc, int precision, const QString& ns ) const
249 {
250  // GML2 does not support curves
251  QgsLineStringV2* line = curveToLine();
252  QDomElement gml = line->asGML2( doc, precision, ns );
253  delete line;
254  return gml;
255 }
256 
257 QDomElement QgsCompoundCurveV2::asGML3( QDomDocument& doc, int precision, const QString& ns ) const
258 {
259  QDomElement compoundCurveElem = doc.createElementNS( ns, "CompositeCurve" );
260  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
261  {
262  QDomElement curveMemberElem = doc.createElementNS( ns, "curveMember" );
263  QDomElement curveElem = curve->asGML3( doc, precision, ns );
264  curveMemberElem.appendChild( curveElem );
265  compoundCurveElem.appendChild( curveMemberElem );
266  }
267 
268  return compoundCurveElem;
269 }
270 
271 QString QgsCompoundCurveV2::asJSON( int precision ) const
272 {
273  // GeoJSON does not support curves
274  QgsLineStringV2* line = curveToLine();
275  QString json = line->asJSON( precision );
276  delete line;
277  return json;
278 }
279 
281 {
282  double length = 0;
284  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
285  {
286  length += ( *curveIt )->length();
287  }
288  return length;
289 }
290 
292 {
293  if ( mCurves.size() < 1 )
294  {
295  return QgsPointV2();
296  }
297  return mCurves.at( 0 )->startPoint();
298 }
299 
301 {
302  if ( mCurves.size() < 1 )
303  {
304  return QgsPointV2();
305  }
306  return mCurves.at( mCurves.size() - 1 )->endPoint();
307 }
308 
310 {
311  pts.clear();
312  if ( mCurves.size() < 1 )
313  {
314  return;
315  }
316 
317  mCurves[0]->points( pts );
318  for ( int i = 1; i < mCurves.size(); ++i )
319  {
320  QgsPointSequenceV2 pList;
321  mCurves[i]->points( pList );
322  pList.removeFirst(); //first vertex already added in previous line
323  pts.append( pList );
324  }
325 }
326 
328 {
329  int nPoints = 0;
330  int nCurves = mCurves.size();
331  if ( nCurves < 1 )
332  {
333  return 0;
334  }
335 
336  for ( int i = 0; i < nCurves; ++i )
337  {
338  nPoints += mCurves.at( i )->numPoints() - 1; //last vertex is equal to first of next section
339  }
340  nPoints += 1; //last vertex was removed above
341  return nPoints;
342 }
343 
345 {
347  QgsLineStringV2* line = new QgsLineStringV2();
348  QgsLineStringV2* currentLine = nullptr;
349  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
350  {
351  currentLine = ( *curveIt )->curveToLine( tolerance, toleranceType );
352  line->append( currentLine );
353  delete currentLine;
354  }
355  return line;
356 }
357 
359 {
360  if ( i >= mCurves.size() )
361  {
362  return nullptr;
363  }
364  return mCurves.at( i );
365 }
366 
368 {
369  if ( c )
370  {
371  mCurves.append( c );
372 
374  {
376  }
377 
379  {
380  c->addZValue();
381  }
383  {
384  c->addMValue();
385  }
386  clearCache();
387  }
388 }
389 
391 {
392  if ( mCurves.size() - 1 < i )
393  {
394  return;
395  }
396 
397  delete( mCurves.at( i ) );
398  mCurves.removeAt( i );
399  clearCache();
400 }
401 
403 {
405  {
407  }
408 
409  //is last curve QgsLineStringV2
410  QgsCurveV2* lastCurve = nullptr;
411  if ( !mCurves.isEmpty() )
412  {
413  lastCurve = mCurves.at( mCurves.size() - 1 );
414  }
415 
416  QgsLineStringV2* line = nullptr;
417  if ( !lastCurve || QgsWKBTypes::flatType( lastCurve->wkbType() ) != QgsWKBTypes::LineString )
418  {
419  line = new QgsLineStringV2();
420  mCurves.append( line );
421  if ( lastCurve )
422  {
423  line->addVertex( lastCurve->endPoint() );
424  }
425  lastCurve = line;
426  }
427  else //create new QgsLineStringV2* with point in it
428  {
429  line = static_cast<QgsLineStringV2*>( lastCurve );
430  }
431  line->addVertex( pt );
432  clearCache();
433 }
434 
436 {
438  for ( ; it != mCurves.constEnd(); ++it )
439  {
440  ( *it )->draw( p );
441  }
442 }
443 
445 {
446  Q_FOREACH ( QgsCurveV2* curve, mCurves )
447  {
448  curve->transform( ct, d, transformZ );
449  }
450  clearCache();
451 }
452 
454 {
455  Q_FOREACH ( QgsCurveV2* curve, mCurves )
456  {
457  curve->transform( t );
458  }
459  clearCache();
460 }
461 
463 {
464  QPainterPath pp;
466  for ( ; it != mCurves.constEnd(); ++it )
467  {
468  ( *it )->addToPainterPath( pp );
469  }
470  path.addPath( pp );
471 }
472 
474 {
475  QPainterPath pp;
477  for ( ; it != mCurves.constEnd(); ++it )
478  {
479  ( *it )->addToPainterPath( pp );
480  }
481  p.drawPath( pp );
482 }
483 
485 {
486  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
487  if ( curveIds.size() < 1 )
488  {
489  return false;
490  }
491  int curveId = curveIds.at( 0 ).first;
492  if ( curveId >= mCurves.size() )
493  {
494  return false;
495  }
496 
497  bool success = mCurves.at( curveId )->insertVertex( curveIds.at( 0 ).second, vertex );
498  if ( success )
499  {
500  clearCache(); //bbox changed
501  }
502  return success;
503 }
504 
506 {
507  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
508  QList< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
509  for ( ; idIt != curveIds.constEnd(); ++idIt )
510  {
511  mCurves.at( idIt->first )->moveVertex( idIt->second, newPos );
512  }
513 
514  bool success = !curveIds.isEmpty();
515  if ( success )
516  {
517  clearCache(); //bbox changed
518  }
519  return success;
520 }
521 
523 {
524  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
525  if ( curveIds.size() == 1 )
526  {
527  if ( !mCurves.at( curveIds.at( 0 ).first )->deleteVertex( curveIds.at( 0 ).second ) )
528  {
529  clearCache(); //bbox may have changed
530  return false;
531  }
532  if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 )
533  {
534  removeCurve( curveIds.at( 0 ).first );
535  }
536  }
537  else if ( curveIds.size() == 2 )
538  {
539  Q_ASSERT( curveIds.at( 1 ).first == curveIds.at( 0 ).first + 1 );
540  Q_ASSERT( curveIds.at( 0 ).second.vertex == mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 );
541  Q_ASSERT( curveIds.at( 1 ).second.vertex == 0 );
542  QgsPointV2 startPoint = mCurves.at( curveIds.at( 0 ).first ) ->startPoint();
543  QgsPointV2 endPoint = mCurves.at( curveIds.at( 1 ).first ) ->endPoint();
544  if ( QgsWKBTypes::flatType( mCurves.at( curveIds.at( 0 ).first )->wkbType() ) == QgsWKBTypes::LineString &&
545  QgsWKBTypes::flatType( mCurves.at( curveIds.at( 1 ).first )->wkbType() ) == QgsWKBTypes::CircularString &&
546  mCurves.at( curveIds.at( 1 ).first )->numPoints() > 3 )
547  {
548  QgsPointV2 intermediatePoint;
550  mCurves.at( curveIds.at( 1 ).first ) ->pointAt( 2, intermediatePoint, type );
551  mCurves.at( curveIds.at( 0 ).first )->moveVertex(
552  QgsVertexId( 0, 0, mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 ), intermediatePoint );
553  }
554  else if ( !mCurves.at( curveIds.at( 0 ).first )->deleteVertex( curveIds.at( 0 ).second ) )
555  {
556  clearCache(); //bbox may have changed
557  return false;
558  }
559  if ( QgsWKBTypes::flatType( mCurves.at( curveIds.at( 0 ).first )->wkbType() ) == QgsWKBTypes::CircularString &&
560  mCurves.at( curveIds.at( 0 ).first )->numPoints() > 0 &&
561  QgsWKBTypes::flatType( mCurves.at( curveIds.at( 1 ).first )->wkbType() ) == QgsWKBTypes::LineString )
562  {
563  QgsPointV2 intermediatePoint = mCurves.at( curveIds.at( 0 ).first ) ->endPoint();
564  mCurves.at( curveIds.at( 1 ).first )->moveVertex( QgsVertexId( 0, 0, 0 ), intermediatePoint );
565  }
566  else if ( !mCurves.at( curveIds.at( 1 ).first )->deleteVertex( curveIds.at( 1 ).second ) )
567  {
568  clearCache(); //bbox may have changed
569  return false;
570  }
571  if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 &&
572  mCurves.at( curveIds.at( 1 ).first )->numPoints() != 0 )
573  {
574  removeCurve( curveIds.at( 0 ).first );
575  mCurves.at( curveIds.at( 1 ).first )->moveVertex( QgsVertexId( 0, 0, 0 ), startPoint );
576  }
577  else if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() != 0 &&
578  mCurves.at( curveIds.at( 1 ).first )->numPoints() == 0 )
579  {
580  removeCurve( curveIds.at( 1 ).first );
581  mCurves.at( curveIds.at( 0 ).first )->moveVertex(
582  QgsVertexId( 0, 0, mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 ), endPoint );
583  }
584  else if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 &&
585  mCurves.at( curveIds.at( 1 ).first )->numPoints() == 0 )
586  {
587  removeCurve( curveIds.at( 1 ).first );
588  removeCurve( curveIds.at( 0 ).first );
589  QgsLineStringV2* line = new QgsLineStringV2();
590  line->insertVertex( QgsVertexId( 0, 0, 0 ), startPoint );
591  line->insertVertex( QgsVertexId( 0, 0, 1 ), endPoint );
592  mCurves.insert( curveIds.at( 0 ).first, line );
593  }
594  else
595  {
596  QgsPointV2 endPointOfFirst = mCurves.at( curveIds.at( 0 ).first ) ->endPoint();
597  QgsPointV2 startPointOfSecond = mCurves.at( curveIds.at( 1 ).first ) ->startPoint();
598  if ( endPointOfFirst != startPointOfSecond )
599  {
600  QgsLineStringV2* line = new QgsLineStringV2();
601  line->insertVertex( QgsVertexId( 0, 0, 0 ), endPointOfFirst );
602  line->insertVertex( QgsVertexId( 0, 0, 1 ), startPointOfSecond );
603  mCurves.insert( curveIds.at( 1 ).first, line );
604  }
605  }
606  }
607 
608  bool success = !curveIds.isEmpty();
609  if ( success )
610  {
611  clearCache(); //bbox changed
612  }
613  return success;
614 }
615 
616 QList< QPair<int, QgsVertexId> > QgsCompoundCurveV2::curveVertexId( QgsVertexId id ) const
617 {
619 
620  int currentVertexIndex = 0;
621  for ( int i = 0; i < mCurves.size(); ++i )
622  {
623  int increment = mCurves.at( i )->numPoints() - 1;
624  if ( id.vertex >= currentVertexIndex && id.vertex <= currentVertexIndex + increment )
625  {
626  int curveVertexId = id.vertex - currentVertexIndex;
627  QgsVertexId vid;
628  vid.part = 0;
629  vid.ring = 0;
630  vid.vertex = curveVertexId;
631  curveIds.append( qMakePair( i, vid ) );
632  if ( curveVertexId == increment && i < ( mCurves.size() - 1 ) ) //add first vertex of next curve
633  {
634  vid.vertex = 0;
635  curveIds.append( qMakePair( i + 1, vid ) );
636  }
637  break;
638  }
639  currentVertexIndex += increment;
640  }
641 
642  return curveIds;
643 }
644 
645 double QgsCompoundCurveV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
646 {
647  return QgsGeometryUtils::closestSegmentFromComponents( mCurves, QgsGeometryUtils::VERTEX, pt, segmentPt, vertexAfter, leftOf, epsilon );
648 }
649 
651 {
652  int currentVertexId = 0;
653  for ( int j = 0; j < mCurves.size(); ++j )
654  {
655  int nCurvePoints = mCurves.at( j )->numPoints();
656  if (( node - currentVertexId ) < nCurvePoints )
657  {
658  return ( mCurves.at( j )->pointAt( node - currentVertexId, point, type ) );
659  }
660  currentVertexId += ( nCurvePoints - 1 );
661  }
662  return false;
663 }
664 
665 void QgsCompoundCurveV2::sumUpArea( double& sum ) const
666 {
668  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
669  {
670  ( *curveIt )->sumUpArea( sum );
671  }
672 }
673 
675 {
676  if ( numPoints() < 1 || isClosed() )
677  {
678  return;
679  }
680  addVertex( startPoint() );
681 }
682 
684 {
686  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
687  {
688  if (( *curveIt )->hasCurvedSegments() )
689  {
690  return true;
691  }
692  }
693  return false;
694 }
695 
697 {
698  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( vertex );
699  if ( curveIds.size() == 1 )
700  {
701  QgsCurveV2* curve = mCurves[curveIds.at( 0 ).first];
702  return curve->vertexAngle( curveIds.at( 0 ).second );
703  }
704  else if ( curveIds.size() > 1 )
705  {
706  QgsCurveV2* curve1 = mCurves[curveIds.at( 0 ).first];
707  QgsCurveV2* curve2 = mCurves[curveIds.at( 1 ).first];
708  double angle1 = curve1->vertexAngle( curveIds.at( 0 ).second );
709  double angle2 = curve2->vertexAngle( curveIds.at( 1 ).second );
710  return QgsGeometryUtils::averageAngle( angle1, angle2 );
711  }
712  else
713  {
714  return 0.0;
715  }
716 }
717 
719 {
721  Q_FOREACH ( QgsCurveV2* curve, mCurves )
722  {
723  QgsCurveV2* reversedCurve = curve->reversed();
724  clone->addCurve( reversedCurve );
725  }
726  return clone;
727 }
728 
729 bool QgsCompoundCurveV2::addZValue( double zValue )
730 {
731  if ( QgsWKBTypes::hasZ( mWkbType ) )
732  return false;
733 
735 
736  Q_FOREACH ( QgsCurveV2* curve, mCurves )
737  {
738  curve->addZValue( zValue );
739  }
740  clearCache();
741  return true;
742 }
743 
744 bool QgsCompoundCurveV2::addMValue( double mValue )
745 {
746  if ( QgsWKBTypes::hasM( mWkbType ) )
747  return false;
748 
750 
751  Q_FOREACH ( QgsCurveV2* curve, mCurves )
752  {
753  curve->addMValue( mValue );
754  }
755  clearCache();
756  return true;
757 }
758 
760 {
761  if ( !QgsWKBTypes::hasZ( mWkbType ) )
762  return false;
763 
765  Q_FOREACH ( QgsCurveV2* curve, mCurves )
766  {
767  curve->dropZValue();
768  }
769  clearCache();
770  return true;
771 }
772 
774 {
775  if ( !QgsWKBTypes::hasM( mWkbType ) )
776  return false;
777 
779  Q_FOREACH ( QgsCurveV2* curve, mCurves )
780  {
781  curve->dropMValue();
782  }
783  clearCache();
784  return true;
785 }
786 
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()
virtual bool insertVertex(QgsVertexId position, const QgsPointV2 &vertex) override
Inserts a vertex into the geometry.
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.
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:757
static bool hasM(Type type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:714
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.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
virtual QgsPointV2 startPoint() const override
Returns the starting point of the curve.
void removeFirst()
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:667
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.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
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:811
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:781
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:120
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:29
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.
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
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.
void combineExtentWith(const QgsRectangle &rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
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:828
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 QgsLineStringV2 * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
virtual QgsLineStringV2 * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
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.
void insert(int i, const T &value)
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
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:38
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()
virtual void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false)=0
Transforms the geometry using a coordinate transform.
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.