QGIS API Documentation  3.27.0-Master (e113457133)
qgslinestring.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgslinestring.h
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 #ifndef QGSLINESTRING_H
19 #define QGSLINESTRING_H
20 
21 
22 #include <QPolygonF>
23 
24 #include "qgis_core.h"
25 #include "qgis_sip.h"
26 #include "qgscurve.h"
27 #include "qgscompoundcurve.h"
28 
29 class QgsLineSegment2D;
30 class QgsBox3d;
31 
32 /***************************************************************************
33  * This class is considered CRITICAL and any change MUST be accompanied with
34  * full unit tests in testqgsgeometry.cpp.
35  * See details in QEP #17
36  ****************************************************************************/
37 
44 class CORE_EXPORT QgsLineString: public QgsCurve
45 {
46 
47  public:
48 
53 #ifndef SIP_RUN
54 
61  QgsLineString( const QVector<QgsPoint> &points );
62 
69  QgsLineString( const QVector<QgsPointXY> &points );
70 #else
71 
79  QgsLineString( SIP_PYOBJECT points SIP_TYPEHINT( Sequence[Union[QgsPoint, QgsPointXY, Sequence[float]]] ) ) SIP_HOLDGIL [( const QVector<double> &x, const QVector<double> &y, const QVector<double> &z = QVector<double>(), const QVector<double> &m = QVector<double>(), bool is25DType = false )];
80  % MethodCode
81  if ( !PySequence_Check( a0 ) )
82  {
83  PyErr_SetString( PyExc_TypeError, QStringLiteral( "A sequence of QgsPoint, QgsPointXY or array of floats is expected" ).toUtf8().constData() );
84  sipIsErr = 1;
85  }
86  else
87  {
88  int state;
89  const int size = PySequence_Size( a0 );
90  QVector< double > xl;
91  QVector< double > yl;
92  bool hasZ = false;
93  QVector< double > zl;
94  bool hasM = false;
95  QVector< double > ml;
96  xl.reserve( size );
97  yl.reserve( size );
98 
99  bool is25D = false;
100 
101  sipIsErr = 0;
102  for ( int i = 0; i < size; ++i )
103  {
104  PyObject *value = PySequence_GetItem( a0, i );
105  if ( !value )
106  {
107  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
108  sipIsErr = 1;
109  break;
110  }
111 
112  if ( PySequence_Check( value ) )
113  {
114  const int elementSize = PySequence_Size( value );
115  if ( elementSize < 2 || elementSize > 4 )
116  {
117  sipIsErr = 1;
118  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid sequence size at index %1. Expected an array of 2-4 float values, got %2." ).arg( i ).arg( elementSize ).toUtf8().constData() );
119  Py_DECREF( value );
120  break;
121  }
122  else
123  {
124  sipIsErr = 0;
125  for ( int j = 0; j < elementSize; ++j )
126  {
127  PyObject *element = PySequence_GetItem( value, j );
128  if ( !element )
129  {
130  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
131  sipIsErr = 1;
132  break;
133  }
134 
135  PyErr_Clear();
136  double d = PyFloat_AsDouble( element );
137  if ( PyErr_Occurred() )
138  {
139  Py_DECREF( value );
140  sipIsErr = 1;
141  break;
142  }
143  if ( j == 0 )
144  xl.append( d );
145  else if ( j == 1 )
146  yl.append( d );
147 
148  if ( i == 0 && j == 2 )
149  {
150  hasZ = true;
151  zl.reserve( size );
152  zl.append( d );
153  }
154  else if ( i > 0 && j == 2 && hasZ )
155  {
156  zl.append( d );
157  }
158 
159  if ( i == 0 && j == 3 )
160  {
161  hasM = true;
162  ml.reserve( size );
163  ml.append( d );
164  }
165  else if ( i > 0 && j == 3 && hasM )
166  {
167  ml.append( d );
168  }
169 
170  Py_DECREF( element );
171  }
172 
173  if ( hasZ && elementSize < 3 )
174  zl.append( std::numeric_limits< double >::quiet_NaN() );
175  if ( hasM && elementSize < 4 )
176  ml.append( std::numeric_limits< double >::quiet_NaN() );
177 
178  Py_DECREF( value );
179  if ( sipIsErr )
180  {
181  break;
182  }
183  }
184  }
185  else
186  {
187  if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
188  {
189  sipIsErr = 0;
190  QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
191  if ( !sipIsErr )
192  {
193  xl.append( p->x() );
194  yl.append( p->y() );
195  }
196  sipReleaseType( p, sipType_QgsPointXY, state );
197  }
198  else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
199  {
200  sipIsErr = 0;
201  QgsPoint *p = reinterpret_cast<QgsPoint *>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
202  if ( !sipIsErr )
203  {
204  xl.append( p->x() );
205  yl.append( p->y() );
206 
207  if ( i == 0 && p->is3D() )
208  {
209  hasZ = true;
210  zl.reserve( size );
211  zl.append( p->z() );
212  }
213  else if ( i > 0 && hasZ )
214  {
215  zl.append( p->z() );
216  }
217 
218  if ( i == 0 && p->isMeasure() )
219  {
220  hasM = true;
221  ml.reserve( size );
222  ml.append( p->m() );
223  }
224  else if ( i > 0 && hasM )
225  {
226  ml.append( p->m() );
227  }
228 
229  if ( i == 0 && p->wkbType() == QgsWkbTypes::Point25D )
230  is25D = true;
231  }
232  sipReleaseType( p, sipType_QgsPoint, state );
233  }
234  else
235  {
236  sipIsErr = 1;
237  }
238 
239  Py_DECREF( value );
240 
241  if ( sipIsErr )
242  {
243  // couldn't convert the sequence value to a QgsPoint or QgsPointXY
244  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats." ).arg( i ) .toUtf8().constData() );
245  break;
246  }
247  }
248  }
249  if ( sipIsErr == 0 )
250  sipCpp = new sipQgsLineString( QgsLineString( xl, yl, zl, ml, is25D ) );
251  }
252  % End
253 #endif
254 
260 
279  QgsLineString( const QVector<double> &x, const QVector<double> &y,
280  const QVector<double> &z = QVector<double>(),
281  const QVector<double> &m = QVector<double>(), bool is25DType = false ) SIP_HOLDGIL;
282 
287  QgsLineString( const QgsPoint &p1, const QgsPoint &p2 ) SIP_HOLDGIL;
288 
299  static QgsLineString *fromBezierCurve( const QgsPoint &start, const QgsPoint &controlPoint1, const QgsPoint &controlPoint2, const QgsPoint &end, int segments = 30 ) SIP_FACTORY;
300 
306  static QgsLineString *fromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
307 
308  bool equals( const QgsCurve &other ) const override;
309 
310 #ifndef SIP_RUN
311 
316  QgsPoint pointN( int i ) const;
317 #else
318 
327  SIP_PYOBJECT pointN( int i ) const SIP_TYPEHINT( QgsPoint );
328  % MethodCode
329  const int count = sipCpp->numPoints();
330  if ( a0 < -count || a0 >= count )
331  {
332  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
333  sipIsErr = 1;
334  }
335  else
336  {
337  std::unique_ptr< QgsPoint > p;
338  if ( a0 >= 0 )
339  p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
340  else // negative index, count backwards from end
341  p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
342  sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
343  }
344  % End
345 #endif
346 
347 #ifndef SIP_RUN
348  double xAt( int index ) const override;
349 #else
350 
359  double xAt( int index ) const override;
360  % MethodCode
361  const int count = sipCpp->numPoints();
362  if ( a0 < -count || a0 >= count )
363  {
364  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
365  sipIsErr = 1;
366  }
367  else
368  {
369  if ( a0 >= 0 )
370  return PyFloat_FromDouble( sipCpp->xAt( a0 ) );
371  else
372  return PyFloat_FromDouble( sipCpp->xAt( count + a0 ) );
373  }
374  % End
375 #endif
376 
377 #ifndef SIP_RUN
378  double yAt( int index ) const override;
379 #else
380 
389  double yAt( int index ) const override;
390  % MethodCode
391  const int count = sipCpp->numPoints();
392  if ( a0 < -count || a0 >= count )
393  {
394  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
395  sipIsErr = 1;
396  }
397  else
398  {
399  if ( a0 >= 0 )
400  return PyFloat_FromDouble( sipCpp->yAt( a0 ) );
401  else
402  return PyFloat_FromDouble( sipCpp->yAt( count + a0 ) );
403  }
404  % End
405 #endif
406 
413  const double *xData() const SIP_SKIP
414  {
415  return mX.constData();
416  }
417 
424  const double *yData() const SIP_SKIP
425  {
426  return mY.constData();
427  }
428 
437  const double *zData() const SIP_SKIP
438  {
439  if ( mZ.empty() )
440  return nullptr;
441  else
442  return mZ.constData();
443  }
444 
453  const double *mData() const SIP_SKIP
454  {
455  if ( mM.empty() )
456  return nullptr;
457  else
458  return mM.constData();
459  }
460 
466  QVector< double > xVector() const SIP_SKIP
467  {
468  return mX;
469  }
470 
476  QVector< double > yVector() const SIP_SKIP
477  {
478  return mY;
479  }
480 
486  QVector< double > zVector() const SIP_SKIP
487  {
488  return mZ;
489  }
490 
496  QVector< double > mVector() const SIP_SKIP
497  {
498  return mM;
499  }
500 
501 
502 #ifndef SIP_RUN
503 
511  double zAt( int index ) const
512  {
513  if ( index >= 0 && index < mZ.size() )
514  return mZ.at( index );
515  else
516  return std::numeric_limits<double>::quiet_NaN();
517  }
518 #else
519 
530  double zAt( int index ) const;
531  % MethodCode
532  const int count = sipCpp->numPoints();
533  if ( a0 < -count || a0 >= count )
534  {
535  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
536  sipIsErr = 1;
537  }
538  else
539  {
540  if ( a0 >= 0 )
541  return PyFloat_FromDouble( sipCpp->zAt( a0 ) );
542  else
543  return PyFloat_FromDouble( sipCpp->zAt( count + a0 ) );
544  }
545  % End
546 #endif
547 
548 #ifndef SIP_RUN
549 
557  double mAt( int index ) const
558  {
559  if ( index >= 0 && index < mM.size() )
560  return mM.at( index );
561  else
562  return std::numeric_limits<double>::quiet_NaN();
563  }
564 #else
565 
576  double mAt( int index ) const;
577  % MethodCode
578  const int count = sipCpp->numPoints();
579  if ( a0 < -count || a0 >= count )
580  {
581  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
582  sipIsErr = 1;
583  }
584  else
585  {
586  if ( a0 >= 0 )
587  return PyFloat_FromDouble( sipCpp->mAt( a0 ) );
588  else
589  return PyFloat_FromDouble( sipCpp->mAt( count + a0 ) );
590  }
591  % End
592 #endif
593 
594 #ifndef SIP_RUN
595 
603  void setXAt( int index, double x );
604 #else
605 
617  void setXAt( int index, double x );
618  % MethodCode
619  const int count = sipCpp->numPoints();
620  if ( a0 < -count || a0 >= count )
621  {
622  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
623  sipIsErr = 1;
624  }
625  else
626  {
627  if ( a0 >= 0 )
628  sipCpp->setXAt( a0, a1 );
629  else
630  sipCpp->setXAt( count + a0, a1 );
631  }
632  % End
633 #endif
634 
635 #ifndef SIP_RUN
636 
644  void setYAt( int index, double y );
645 #else
646 
658  void setYAt( int index, double y );
659  % MethodCode
660  const int count = sipCpp->numPoints();
661  if ( a0 < -count || a0 >= count )
662  {
663  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
664  sipIsErr = 1;
665  }
666  else
667  {
668  if ( a0 >= 0 )
669  sipCpp->setYAt( a0, a1 );
670  else
671  sipCpp->setYAt( count + a0, a1 );
672  }
673  % End
674 #endif
675 
676 #ifndef SIP_RUN
677 
685  void setZAt( int index, double z )
686  {
687  if ( index >= 0 && index < mZ.size() )
688  mZ[ index ] = z;
689  }
690 #else
691 
702  void setZAt( int index, double z );
703  % MethodCode
704  const int count = sipCpp->numPoints();
705  if ( a0 < -count || a0 >= count )
706  {
707  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
708  sipIsErr = 1;
709  }
710  else
711  {
712  if ( a0 >= 0 )
713  sipCpp->setZAt( a0, a1 );
714  else
715  sipCpp->setZAt( count + a0, a1 );
716  }
717  % End
718 #endif
719 
720 #ifndef SIP_RUN
721 
729  void setMAt( int index, double m )
730  {
731  if ( index >= 0 && index < mM.size() )
732  mM[ index ] = m;
733  }
734 #else
735 
746  void setMAt( int index, double m );
747  % MethodCode
748  const int count = sipCpp->numPoints();
749  if ( a0 < -count || a0 >= count )
750  {
751  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
752  sipIsErr = 1;
753  }
754  else
755  {
756  if ( a0 >= 0 )
757  sipCpp->setMAt( a0, a1 );
758  else
759  sipCpp->setMAt( count + a0, a1 );
760  }
761  % End
762 #endif
763 
777  void setPoints( size_t size, const double *x, const double *y, const double *z = nullptr, const double *m = nullptr ) SIP_SKIP;
778 
784  void setPoints( const QgsPointSequence &points );
785 
790  void append( const QgsLineString *line );
791 
796  void addVertex( const QgsPoint &pt );
797 
799  void close();
800 
805  QgsCompoundCurve *toCurveType() const override SIP_FACTORY;
806 
813  void extend( double startDistance, double endDistance );
814 
815 #ifndef SIP_RUN
816 
822  void visitPointsByRegularDistance( double distance, const std::function< bool( double x, double y, double z, double m,
823  double startSegmentX, double startSegmentY, double startSegmentZ, double startSegmentM,
824  double endSegmentX, double endSegmentY, double endSegmentZ, double endSegmentM
825  ) > &visitPoint ) const;
826 #endif
827 
828  //reimplemented methods
829  QString geometryType() const override SIP_HOLDGIL;
830  int dimension() const override SIP_HOLDGIL;
831  QgsLineString *clone() const override SIP_FACTORY;
832  void clear() override;
833  bool isEmpty() const override SIP_HOLDGIL;
834  int indexOf( const QgsPoint &point ) const final;
835  bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
836  QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
837  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
838  bool isClosed() const override SIP_HOLDGIL;
839  bool isClosed2D() const override SIP_HOLDGIL;
840  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL;
841 
849  QVector< QgsVertexId > collectDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) const;
850 
851  QPolygonF asQPolygonF() const override;
852 
853  bool fromWkb( QgsConstWkbPtr &wkb ) override;
854  bool fromWkt( const QString &wkt ) override;
855 
856  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
857  QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
858  QString asWkt( int precision = 17 ) const override;
859  QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
860  QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
861  json asJsonObject( int precision = 17 ) const override SIP_SKIP;
862  QString asKml( int precision = 17 ) const override;
863 
864  //curve interface
865  double length() const override SIP_HOLDGIL;
866 
867 #ifndef SIP_RUN
868  std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > > splitCurveAtVertex( int index ) const final;
869 #endif
870 
877  double length3D() const SIP_HOLDGIL;
878  QgsPoint startPoint() const override SIP_HOLDGIL;
879  QgsPoint endPoint() const override SIP_HOLDGIL;
880 
887  QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
888 
889  int numPoints() const override SIP_HOLDGIL;
890  int nCoordinates() const override SIP_HOLDGIL;
891  void points( QgsPointSequence &pt SIP_OUT ) const override;
892 
893  void draw( QPainter &p ) const override;
894 
895  void transform( const QgsCoordinateTransform &ct, Qgis::TransformDirection d = Qgis::TransformDirection::Forward, bool transformZ = false ) override SIP_THROW( QgsCsException );
896  void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
897 
898  void addToPainterPath( QPainterPath &path ) const override;
899  void drawAsPolygon( QPainter &p ) const override;
900 
901  bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
902  bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
903  bool deleteVertex( QgsVertexId position ) override;
904 
905  QgsLineString *reversed() const override SIP_FACTORY;
906  QgsPoint *interpolatePoint( double distance ) const override SIP_FACTORY;
907  QgsLineString *curveSubstring( double startDistance, double endDistance ) const override SIP_FACTORY;
908 
909  double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT, QgsVertexId &vertexAfter SIP_OUT, int *leftOf SIP_OUT = nullptr, double epsilon = 4 * std::numeric_limits<double>::epsilon() ) const override;
910  bool pointAt( int node, QgsPoint &point, Qgis::VertexType &type ) const override;
911 
912  QgsPoint centroid() const override;
913 
914  void sumUpArea( double &sum SIP_OUT ) const override;
915  double vertexAngle( QgsVertexId vertex ) const override;
916  double segmentLength( QgsVertexId startVertex ) const override;
917  bool addZValue( double zValue = 0 ) override;
918  bool addMValue( double mValue = 0 ) override;
919 
920  bool dropZValue() override;
921  bool dropMValue() override;
922  void swapXy() override;
923 
924  bool convertTo( QgsWkbTypes::Type type ) override;
925 
926  bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
927  void scroll( int firstVertexIndex ) final;
928 
929 #ifndef SIP_RUN
930  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
931  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
932 
940  inline static const QgsLineString *cast( const QgsAbstractGeometry *geom )
941  {
942  if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::LineString )
943  return static_cast<const QgsLineString *>( geom );
944  return nullptr;
945  }
946 #endif
947 
949 
950 #ifdef SIP_RUN
951  SIP_PYOBJECT __repr__();
952  % MethodCode
953  QString wkt = sipCpp->asWkt();
954  if ( wkt.length() > 1000 )
955  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
956  QString str = QStringLiteral( "<QgsLineString: %1>" ).arg( wkt );
957  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
958  % End
959 
969  SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsPoint );
970  % MethodCode
971  const int count = sipCpp->numPoints();
972  if ( a0 < -count || a0 >= count )
973  {
974  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
975  sipIsErr = 1;
976  }
977  else
978  {
979  std::unique_ptr< QgsPoint > p;
980  if ( a0 >= 0 )
981  p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
982  else
983  p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
984  sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
985  }
986  % End
987 
997  void __setitem__( int index, const QgsPoint &point );
998  % MethodCode
999  const int count = sipCpp->numPoints();
1000  if ( a0 < -count || a0 >= count )
1001  {
1002  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
1003  sipIsErr = 1;
1004  }
1005  else
1006  {
1007  if ( a0 < 0 )
1008  a0 = count + a0;
1009  sipCpp->setXAt( a0, a1->x() );
1010  sipCpp->setYAt( a0, a1->y() );
1011  if ( sipCpp->isMeasure() )
1012  sipCpp->setMAt( a0, a1->m() );
1013  if ( sipCpp->is3D() )
1014  sipCpp->setZAt( a0, a1->z() );
1015  }
1016  % End
1017 
1018 
1028  void __delitem__( int index );
1029  % MethodCode
1030  const int count = sipCpp->numPoints();
1031  if ( a0 >= 0 && a0 < count )
1032  sipCpp->deleteVertex( QgsVertexId( -1, -1, a0 ) );
1033  else if ( a0 < 0 && a0 >= -count )
1034  sipCpp->deleteVertex( QgsVertexId( -1, -1, count + a0 ) );
1035  else
1036  {
1037  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
1038  sipIsErr = 1;
1039  }
1040  % End
1041 
1042 #endif
1043 
1049  QgsBox3d calculateBoundingBox3d() const;
1050 
1051  protected:
1052 
1053  int compareToSameClass( const QgsAbstractGeometry *other ) const final;
1054  QgsRectangle calculateBoundingBox() const override;
1055 
1056  private:
1057  QVector<double> mX;
1058  QVector<double> mY;
1059  QVector<double> mZ;
1060  QVector<double> mM;
1061 
1062  void importVerticesFromWkb( const QgsConstWkbPtr &wkb );
1063 
1069  void fromWkbPoints( QgsWkbTypes::Type type, const QgsConstWkbPtr &wkb )
1070  {
1071  mWkbType = type;
1072  importVerticesFromWkb( wkb );
1073  }
1074 
1075  friend class QgsPolygon;
1076  friend class QgsTriangle;
1077  friend class TestQgsGeometry;
1078 
1079 };
1080 
1081 // clazy:excludeall=qstring-allocations
1082 
1083 #endif // QGSLINESTRING_H
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:72
An abstract base class for classes which transform geometries by transforming input points to output ...
Abstract base class for all geometries.
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual QgsRectangle calculateBoundingBox() const
Default calculator for the minimal bounding box for the geometry.
virtual void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform)
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
virtual QgsAbstractGeometry * createEmptyWithSameType() const =0
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
virtual void filterVertices(const std::function< bool(const QgsPoint &) > &filter)
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
virtual int compareToSameClass(const QgsAbstractGeometry *other) const =0
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
A 3-dimensional box composed of x, y, z coordinates.
Definition: qgsbox3d.h:39
Compound curve geometry type.
A const WKB pointer.
Definition: qgswkbptr.h:138
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
virtual bool equals(const QgsCurve &other) const =0
Checks whether this curve exactly equals another curve.
virtual double xAt(int index) const =0
Returns the x-coordinate of the specified node in the line string.
virtual std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > > splitCurveAtVertex(int index) const =0
Splits the curve at the specified vertex index, returning two curves which represent the portion of t...
virtual double yAt(int index) const =0
Returns the y-coordinate of the specified node in the line string.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
Represents a single 2D line segment, consisting of a 2D start and end vertex only.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:45
const double * yData() const
Returns a const pointer to the y vertex data.
QVector< double > xVector() const
Returns the x vertex values as a vector.
static const QgsLineString * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
QVector< double > yVector() const
Returns the y vertex values as a vector.
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values.
void setZAt(int index, double z)
Sets the z-coordinate of the specified node in the line string.
QVector< double > zVector() const
Returns the z vertex values as a vector.
double mAt(int index) const
Returns the m value of the specified node in the line string.
double zAt(int index) const
Returns the z-coordinate of the specified node in the line string.
QVector< double > mVector() const
Returns the m vertex values as a vector.
void setMAt(int index, double m)
Sets the m value of the specified node in the line string.
const double * xData() const
Returns a const pointer to the x vertex data.
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values.
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
Q_GADGET double x
Definition: qgspoint.h:52
double z
Definition: qgspoint.h:54
double m
Definition: qgspoint.h:55
double y
Definition: qgspoint.h:53
Polygon geometry type.
Definition: qgspolygon.h:34
A rectangle specified with double values.
Definition: qgsrectangle.h:42
Triangle geometry type.
Definition: qgstriangle.h:34
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
double ANALYSIS_EXPORT leftOf(const QgsPoint &thepoint, const QgsPoint *p1, const QgsPoint *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. Negative values mean left ...
Definition: MathUtils.cpp:292
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
#define str(x)
Definition: qgis.cpp:37
#define SIP_THROW(name)
Definition: qgis_sip.h:198
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:227
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:166
#define SIP_FACTORY
Definition: qgis_sip.h:76
QVector< QgsPoint > QgsPointSequence
QLineF segment(int index, QRectF rect, double radius)
double closestSegment(const QgsPolylineXY &pl, const QgsPointXY &pt, int &vertexAfter, double epsilon)
Definition: qgstracer.cpp:69
int precision
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:31