QGIS API Documentation  2.18.3-Las Palmas (77b8c3d)
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 elemCurve = doc.createElementNS( ns, "Curve" );
260 
261  QDomElement elemSegments = doc.createElementNS( ns, "segments" );
262 
263  Q_FOREACH ( const QgsCurveV2* curve, mCurves )
264  {
265  if ( dynamic_cast<const QgsLineStringV2*>( curve ) )
266  {
267  QgsPointSequenceV2 pts;
268  curve->points( pts );
269 
270  QDomElement elemLineStringSegment = doc.createElementNS( ns, "LineStringSegment" );
271  elemLineStringSegment.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, is3D() ) );
272  elemSegments.appendChild( elemLineStringSegment );
273  }
274  else if ( dynamic_cast<const QgsCircularStringV2*>( curve ) )
275  {
276  QgsPointSequenceV2 pts;
277  curve->points( pts );
278 
279  QDomElement elemArcString = doc.createElementNS( ns, "ArcString" );
280  elemArcString.appendChild( QgsGeometryUtils::pointsToGML3( pts, doc, precision, ns, is3D() ) );
281  elemSegments.appendChild( elemArcString );
282  }
283  }
284  elemCurve.appendChild( elemSegments );
285  return elemCurve;
286 }
287 
288 QString QgsCompoundCurveV2::asJSON( int precision ) const
289 {
290  // GeoJSON does not support curves
291  QgsLineStringV2* line = curveToLine();
292  QString json = line->asJSON( precision );
293  delete line;
294  return json;
295 }
296 
298 {
299  double length = 0;
301  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
302  {
303  length += ( *curveIt )->length();
304  }
305  return length;
306 }
307 
309 {
310  if ( mCurves.size() < 1 )
311  {
312  return QgsPointV2();
313  }
314  return mCurves.at( 0 )->startPoint();
315 }
316 
318 {
319  if ( mCurves.size() < 1 )
320  {
321  return QgsPointV2();
322  }
323  return mCurves.at( mCurves.size() - 1 )->endPoint();
324 }
325 
327 {
328  pts.clear();
329  if ( mCurves.size() < 1 )
330  {
331  return;
332  }
333 
334  mCurves[0]->points( pts );
335  for ( int i = 1; i < mCurves.size(); ++i )
336  {
337  QgsPointSequenceV2 pList;
338  mCurves[i]->points( pList );
339  pList.removeFirst(); //first vertex already added in previous line
340  pts.append( pList );
341  }
342 }
343 
345 {
346  int nPoints = 0;
347  int nCurves = mCurves.size();
348  if ( nCurves < 1 )
349  {
350  return 0;
351  }
352 
353  for ( int i = 0; i < nCurves; ++i )
354  {
355  nPoints += mCurves.at( i )->numPoints() - 1; //last vertex is equal to first of next section
356  }
357  nPoints += 1; //last vertex was removed above
358  return nPoints;
359 }
360 
362 {
364  QgsLineStringV2* line = new QgsLineStringV2();
365  QgsLineStringV2* currentLine = nullptr;
366  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
367  {
368  currentLine = ( *curveIt )->curveToLine( tolerance, toleranceType );
369  line->append( currentLine );
370  delete currentLine;
371  }
372  return line;
373 }
374 
376 {
377  if ( i >= mCurves.size() )
378  {
379  return nullptr;
380  }
381  return mCurves.at( i );
382 }
383 
385 {
386  if ( c )
387  {
388  mCurves.append( c );
389 
391  {
393  }
394 
396  {
397  c->addZValue();
398  }
400  {
401  c->addMValue();
402  }
403  clearCache();
404  }
405 }
406 
408 {
409  if ( mCurves.size() - 1 < i )
410  {
411  return;
412  }
413 
414  delete( mCurves.at( i ) );
415  mCurves.removeAt( i );
416  clearCache();
417 }
418 
420 {
422  {
424  }
425 
426  //is last curve QgsLineStringV2
427  QgsCurveV2* lastCurve = nullptr;
428  if ( !mCurves.isEmpty() )
429  {
430  lastCurve = mCurves.at( mCurves.size() - 1 );
431  }
432 
433  QgsLineStringV2* line = nullptr;
434  if ( !lastCurve || QgsWKBTypes::flatType( lastCurve->wkbType() ) != QgsWKBTypes::LineString )
435  {
436  line = new QgsLineStringV2();
437  mCurves.append( line );
438  if ( lastCurve )
439  {
440  line->addVertex( lastCurve->endPoint() );
441  }
442  lastCurve = line;
443  }
444  else //create new QgsLineStringV2* with point in it
445  {
446  line = static_cast<QgsLineStringV2*>( lastCurve );
447  }
448  line->addVertex( pt );
449  clearCache();
450 }
451 
453 {
455  for ( ; it != mCurves.constEnd(); ++it )
456  {
457  ( *it )->draw( p );
458  }
459 }
460 
462 {
463  Q_FOREACH ( QgsCurveV2* curve, mCurves )
464  {
465  curve->transform( ct, d, transformZ );
466  }
467  clearCache();
468 }
469 
471 {
472  Q_FOREACH ( QgsCurveV2* curve, mCurves )
473  {
474  curve->transform( t );
475  }
476  clearCache();
477 }
478 
480 {
481  QPainterPath pp;
483  for ( ; it != mCurves.constEnd(); ++it )
484  {
485  ( *it )->addToPainterPath( pp );
486  }
487  path.addPath( pp );
488 }
489 
491 {
492  QPainterPath pp;
494  for ( ; it != mCurves.constEnd(); ++it )
495  {
496  ( *it )->addToPainterPath( pp );
497  }
498  p.drawPath( pp );
499 }
500 
502 {
503  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
504  if ( curveIds.size() < 1 )
505  {
506  return false;
507  }
508  int curveId = curveIds.at( 0 ).first;
509  if ( curveId >= mCurves.size() )
510  {
511  return false;
512  }
513 
514  bool success = mCurves.at( curveId )->insertVertex( curveIds.at( 0 ).second, vertex );
515  if ( success )
516  {
517  clearCache(); //bbox changed
518  }
519  return success;
520 }
521 
523 {
524  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
525  QList< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
526  for ( ; idIt != curveIds.constEnd(); ++idIt )
527  {
528  mCurves.at( idIt->first )->moveVertex( idIt->second, newPos );
529  }
530 
531  bool success = !curveIds.isEmpty();
532  if ( success )
533  {
534  clearCache(); //bbox changed
535  }
536  return success;
537 }
538 
540 {
541  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
542  if ( curveIds.size() == 1 )
543  {
544  if ( !mCurves.at( curveIds.at( 0 ).first )->deleteVertex( curveIds.at( 0 ).second ) )
545  {
546  clearCache(); //bbox may have changed
547  return false;
548  }
549  if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 )
550  {
551  removeCurve( curveIds.at( 0 ).first );
552  }
553  }
554  else if ( curveIds.size() == 2 )
555  {
556  Q_ASSERT( curveIds.at( 1 ).first == curveIds.at( 0 ).first + 1 );
557  Q_ASSERT( curveIds.at( 0 ).second.vertex == mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 );
558  Q_ASSERT( curveIds.at( 1 ).second.vertex == 0 );
559  QgsPointV2 startPoint = mCurves.at( curveIds.at( 0 ).first ) ->startPoint();
560  QgsPointV2 endPoint = mCurves.at( curveIds.at( 1 ).first ) ->endPoint();
561  if ( QgsWKBTypes::flatType( mCurves.at( curveIds.at( 0 ).first )->wkbType() ) == QgsWKBTypes::LineString &&
562  QgsWKBTypes::flatType( mCurves.at( curveIds.at( 1 ).first )->wkbType() ) == QgsWKBTypes::CircularString &&
563  mCurves.at( curveIds.at( 1 ).first )->numPoints() > 3 )
564  {
565  QgsPointV2 intermediatePoint;
567  mCurves.at( curveIds.at( 1 ).first ) ->pointAt( 2, intermediatePoint, type );
568  mCurves.at( curveIds.at( 0 ).first )->moveVertex(
569  QgsVertexId( 0, 0, mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 ), intermediatePoint );
570  }
571  else if ( !mCurves.at( curveIds.at( 0 ).first )->deleteVertex( curveIds.at( 0 ).second ) )
572  {
573  clearCache(); //bbox may have changed
574  return false;
575  }
576  if ( QgsWKBTypes::flatType( mCurves.at( curveIds.at( 0 ).first )->wkbType() ) == QgsWKBTypes::CircularString &&
577  mCurves.at( curveIds.at( 0 ).first )->numPoints() > 0 &&
578  QgsWKBTypes::flatType( mCurves.at( curveIds.at( 1 ).first )->wkbType() ) == QgsWKBTypes::LineString )
579  {
580  QgsPointV2 intermediatePoint = mCurves.at( curveIds.at( 0 ).first ) ->endPoint();
581  mCurves.at( curveIds.at( 1 ).first )->moveVertex( QgsVertexId( 0, 0, 0 ), intermediatePoint );
582  }
583  else if ( !mCurves.at( curveIds.at( 1 ).first )->deleteVertex( curveIds.at( 1 ).second ) )
584  {
585  clearCache(); //bbox may have changed
586  return false;
587  }
588  if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 &&
589  mCurves.at( curveIds.at( 1 ).first )->numPoints() != 0 )
590  {
591  removeCurve( curveIds.at( 0 ).first );
592  mCurves.at( curveIds.at( 1 ).first )->moveVertex( QgsVertexId( 0, 0, 0 ), startPoint );
593  }
594  else if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() != 0 &&
595  mCurves.at( curveIds.at( 1 ).first )->numPoints() == 0 )
596  {
597  removeCurve( curveIds.at( 1 ).first );
598  mCurves.at( curveIds.at( 0 ).first )->moveVertex(
599  QgsVertexId( 0, 0, mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 ), endPoint );
600  }
601  else if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 &&
602  mCurves.at( curveIds.at( 1 ).first )->numPoints() == 0 )
603  {
604  removeCurve( curveIds.at( 1 ).first );
605  removeCurve( curveIds.at( 0 ).first );
606  QgsLineStringV2* line = new QgsLineStringV2();
607  line->insertVertex( QgsVertexId( 0, 0, 0 ), startPoint );
608  line->insertVertex( QgsVertexId( 0, 0, 1 ), endPoint );
609  mCurves.insert( curveIds.at( 0 ).first, line );
610  }
611  else
612  {
613  QgsPointV2 endPointOfFirst = mCurves.at( curveIds.at( 0 ).first ) ->endPoint();
614  QgsPointV2 startPointOfSecond = mCurves.at( curveIds.at( 1 ).first ) ->startPoint();
615  if ( endPointOfFirst != startPointOfSecond )
616  {
617  QgsLineStringV2* line = new QgsLineStringV2();
618  line->insertVertex( QgsVertexId( 0, 0, 0 ), endPointOfFirst );
619  line->insertVertex( QgsVertexId( 0, 0, 1 ), startPointOfSecond );
620  mCurves.insert( curveIds.at( 1 ).first, line );
621  }
622  }
623  }
624 
625  bool success = !curveIds.isEmpty();
626  if ( success )
627  {
628  clearCache(); //bbox changed
629  }
630  return success;
631 }
632 
633 QList< QPair<int, QgsVertexId> > QgsCompoundCurveV2::curveVertexId( QgsVertexId id ) const
634 {
636 
637  int currentVertexIndex = 0;
638  for ( int i = 0; i < mCurves.size(); ++i )
639  {
640  int increment = mCurves.at( i )->numPoints() - 1;
641  if ( id.vertex >= currentVertexIndex && id.vertex <= currentVertexIndex + increment )
642  {
643  int curveVertexId = id.vertex - currentVertexIndex;
644  QgsVertexId vid;
645  vid.part = 0;
646  vid.ring = 0;
647  vid.vertex = curveVertexId;
648  curveIds.append( qMakePair( i, vid ) );
649  if ( curveVertexId == increment && i < ( mCurves.size() - 1 ) ) //add first vertex of next curve
650  {
651  vid.vertex = 0;
652  curveIds.append( qMakePair( i + 1, vid ) );
653  }
654  break;
655  }
656  currentVertexIndex += increment;
657  }
658 
659  return curveIds;
660 }
661 
662 double QgsCompoundCurveV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
663 {
664  return QgsGeometryUtils::closestSegmentFromComponents( mCurves, QgsGeometryUtils::VERTEX, pt, segmentPt, vertexAfter, leftOf, epsilon );
665 }
666 
668 {
669  int currentVertexId = 0;
670  for ( int j = 0; j < mCurves.size(); ++j )
671  {
672  int nCurvePoints = mCurves.at( j )->numPoints();
673  if (( node - currentVertexId ) < nCurvePoints )
674  {
675  return ( mCurves.at( j )->pointAt( node - currentVertexId, point, type ) );
676  }
677  currentVertexId += ( nCurvePoints - 1 );
678  }
679  return false;
680 }
681 
682 void QgsCompoundCurveV2::sumUpArea( double& sum ) const
683 {
685  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
686  {
687  ( *curveIt )->sumUpArea( sum );
688  }
689 }
690 
692 {
693  if ( numPoints() < 1 || isClosed() )
694  {
695  return;
696  }
697  addVertex( startPoint() );
698 }
699 
701 {
703  for ( ; curveIt != mCurves.constEnd(); ++curveIt )
704  {
705  if (( *curveIt )->hasCurvedSegments() )
706  {
707  return true;
708  }
709  }
710  return false;
711 }
712 
714 {
715  QList< QPair<int, QgsVertexId> > curveIds = curveVertexId( vertex );
716  if ( curveIds.size() == 1 )
717  {
718  QgsCurveV2* curve = mCurves[curveIds.at( 0 ).first];
719  return curve->vertexAngle( curveIds.at( 0 ).second );
720  }
721  else if ( curveIds.size() > 1 )
722  {
723  QgsCurveV2* curve1 = mCurves[curveIds.at( 0 ).first];
724  QgsCurveV2* curve2 = mCurves[curveIds.at( 1 ).first];
725  double angle1 = curve1->vertexAngle( curveIds.at( 0 ).second );
726  double angle2 = curve2->vertexAngle( curveIds.at( 1 ).second );
727  return QgsGeometryUtils::averageAngle( angle1, angle2 );
728  }
729  else
730  {
731  return 0.0;
732  }
733 }
734 
736 {
738  Q_FOREACH ( QgsCurveV2* curve, mCurves )
739  {
740  QgsCurveV2* reversedCurve = curve->reversed();
741  clone->addCurve( reversedCurve );
742  }
743  return clone;
744 }
745 
746 bool QgsCompoundCurveV2::addZValue( double zValue )
747 {
748  if ( QgsWKBTypes::hasZ( mWkbType ) )
749  return false;
750 
752 
753  Q_FOREACH ( QgsCurveV2* curve, mCurves )
754  {
755  curve->addZValue( zValue );
756  }
757  clearCache();
758  return true;
759 }
760 
761 bool QgsCompoundCurveV2::addMValue( double mValue )
762 {
763  if ( QgsWKBTypes::hasM( mWkbType ) )
764  return false;
765 
767 
768  Q_FOREACH ( QgsCurveV2* curve, mCurves )
769  {
770  curve->addMValue( mValue );
771  }
772  clearCache();
773  return true;
774 }
775 
777 {
778  if ( !QgsWKBTypes::hasZ( mWkbType ) )
779  return false;
780 
782  Q_FOREACH ( QgsCurveV2* curve, mCurves )
783  {
784  curve->dropZValue();
785  }
786  clearCache();
787  return true;
788 }
789 
791 {
792  if ( !QgsWKBTypes::hasM( mWkbType ) )
793  return false;
794 
796  Q_FOREACH ( QgsCurveV2* curve, mCurves )
797  {
798  curve->dropMValue();
799  }
800  clearCache();
801  return true;
802 }
803 
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
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 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
Calculates the area of the curve.
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.
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.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
QgsWKBTypes::Type readHeader() const
Definition: qgswkbptr.cpp:38
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
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:121
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, 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.
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
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()
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.
static QDomElement pointsToGML3(const QgsPointSequenceV2 &points, QDomDocument &doc, int precision, const QString &ns, bool is3D)
Returns a gml::posList DOM element.
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.
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)
virtual bool isClosed() const
Returns true if the curve is closed.
Definition: qgscurvev2.cpp:29
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.
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;.
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 points(QgsPointSequenceV2 &pt) const =0
Returns a list of points within the curve.
int nCurves() const
Returns the number of curves in the geometry.
virtual void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false)=0
Transforms the geometry using a coordinate transform.
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.