QGIS API Documentation  3.21.0-Master (2d5a580dfc)
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 
31 /***************************************************************************
32  * This class is considered CRITICAL and any change MUST be accompanied with
33  * full unit tests in testqgsgeometry.cpp.
34  * See details in QEP #17
35  ****************************************************************************/
36 
43 class CORE_EXPORT QgsLineString: public QgsCurve
44 {
45 
46  public:
47 
52 #ifndef SIP_RUN
53 
60  QgsLineString( const QVector<QgsPoint> &points );
61 
68  QgsLineString( const QVector<QgsPointXY> &points );
69 #else
70 
78  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 )];
79  % MethodCode
80  if ( !PySequence_Check( a0 ) )
81  {
82  PyErr_SetString( PyExc_TypeError, QStringLiteral( "A sequence of QgsPoint, QgsPointXY or array of floats is expected" ).toUtf8().constData() );
83  sipIsErr = 1;
84  }
85  else
86  {
87  int state;
88  const int size = PySequence_Size( a0 );
89  QVector< double > xl;
90  QVector< double > yl;
91  bool hasZ = false;
92  QVector< double > zl;
93  bool hasM = false;
94  QVector< double > ml;
95  xl.reserve( size );
96  yl.reserve( size );
97 
98  bool is25D = false;
99 
100  sipIsErr = 0;
101  for ( int i = 0; i < size; ++i )
102  {
103  PyObject *value = PySequence_GetItem( a0, i );
104  if ( !value )
105  {
106  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
107  sipIsErr = 1;
108  break;
109  }
110 
111  if ( PySequence_Check( value ) )
112  {
113  const int elementSize = PySequence_Size( value );
114  if ( elementSize < 2 || elementSize > 4 )
115  {
116  sipIsErr = 1;
117  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() );
118  Py_DECREF( value );
119  break;
120  }
121  else
122  {
123  sipIsErr = 0;
124  for ( int j = 0; j < elementSize; ++j )
125  {
126  PyObject *element = PySequence_GetItem( value, j );
127  if ( !element )
128  {
129  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
130  sipIsErr = 1;
131  break;
132  }
133 
134  PyErr_Clear();
135  double d = PyFloat_AsDouble( element );
136  if ( PyErr_Occurred() )
137  {
138  Py_DECREF( value );
139  sipIsErr = 1;
140  break;
141  }
142  if ( j == 0 )
143  xl.append( d );
144  else if ( j == 1 )
145  yl.append( d );
146 
147  if ( i == 0 && j == 2 )
148  {
149  hasZ = true;
150  zl.reserve( size );
151  zl.append( d );
152  }
153  else if ( i > 0 && j == 2 && hasZ )
154  {
155  zl.append( d );
156  }
157 
158  if ( i == 0 && j == 3 )
159  {
160  hasM = true;
161  ml.reserve( size );
162  ml.append( d );
163  }
164  else if ( i > 0 && j == 3 && hasM )
165  {
166  ml.append( d );
167  }
168 
169  Py_DECREF( element );
170  }
171 
172  if ( hasZ && elementSize < 3 )
173  zl.append( std::numeric_limits< double >::quiet_NaN() );
174  if ( hasM && elementSize < 4 )
175  ml.append( std::numeric_limits< double >::quiet_NaN() );
176 
177  Py_DECREF( value );
178  if ( sipIsErr )
179  {
180  break;
181  }
182  }
183  }
184  else
185  {
186  if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
187  {
188  sipIsErr = 0;
189  QgsPointXY *p = reinterpret_cast<QgsPointXY *>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
190  if ( !sipIsErr )
191  {
192  xl.append( p->x() );
193  yl.append( p->y() );
194  }
195  sipReleaseType( p, sipType_QgsPointXY, state );
196  }
197  else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
198  {
199  sipIsErr = 0;
200  QgsPoint *p = reinterpret_cast<QgsPoint *>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
201  if ( !sipIsErr )
202  {
203  xl.append( p->x() );
204  yl.append( p->y() );
205 
206  if ( i == 0 && p->is3D() )
207  {
208  hasZ = true;
209  zl.reserve( size );
210  zl.append( p->z() );
211  }
212  else if ( i > 0 && hasZ )
213  {
214  zl.append( p->z() );
215  }
216 
217  if ( i == 0 && p->isMeasure() )
218  {
219  hasM = true;
220  ml.reserve( size );
221  ml.append( p->m() );
222  }
223  else if ( i > 0 && hasM )
224  {
225  ml.append( p->m() );
226  }
227 
228  if ( i == 0 && p->wkbType() == QgsWkbTypes::Point25D )
229  is25D = true;
230  }
231  sipReleaseType( p, sipType_QgsPoint, state );
232  }
233  else
234  {
235  sipIsErr = 1;
236  }
237 
238  Py_DECREF( value );
239 
240  if ( sipIsErr )
241  {
242  // couldn't convert the sequence value to a QgsPoint or QgsPointXY
243  PyErr_SetString( PyExc_TypeError, QStringLiteral( "Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats." ).arg( i ) .toUtf8().constData() );
244  break;
245  }
246  }
247  }
248  if ( sipIsErr == 0 )
249  sipCpp = new sipQgsLineString( QgsLineString( xl, yl, zl, ml, is25D ) );
250  }
251  % End
252 #endif
253 
259 
278  QgsLineString( const QVector<double> &x, const QVector<double> &y,
279  const QVector<double> &z = QVector<double>(),
280  const QVector<double> &m = QVector<double>(), bool is25DType = false ) SIP_HOLDGIL;
281 
286  QgsLineString( const QgsPoint &p1, const QgsPoint &p2 ) SIP_HOLDGIL;
287 
298  static QgsLineString *fromBezierCurve( const QgsPoint &start, const QgsPoint &controlPoint1, const QgsPoint &controlPoint2, const QgsPoint &end, int segments = 30 ) SIP_FACTORY;
299 
305  static QgsLineString *fromQPolygonF( const QPolygonF &polygon ) SIP_FACTORY;
306 
307  bool equals( const QgsCurve &other ) const override;
308 
309 #ifndef SIP_RUN
310 
315  QgsPoint pointN( int i ) const;
316 #else
317 
326  SIP_PYOBJECT pointN( int i ) const SIP_TYPEHINT( QgsPoint );
327  % MethodCode
328  const int count = sipCpp->numPoints();
329  if ( a0 < -count || a0 >= count )
330  {
331  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
332  sipIsErr = 1;
333  }
334  else
335  {
336  std::unique_ptr< QgsPoint > p;
337  if ( a0 >= 0 )
338  p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
339  else // negative index, count backwards from end
340  p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
341  sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
342  }
343  % End
344 #endif
345 
346 #ifndef SIP_RUN
347  double xAt( int index ) const override;
348 #else
349 
358  double xAt( int index ) const override;
359  % MethodCode
360  const int count = sipCpp->numPoints();
361  if ( a0 < -count || a0 >= count )
362  {
363  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
364  sipIsErr = 1;
365  }
366  else
367  {
368  if ( a0 >= 0 )
369  return PyFloat_FromDouble( sipCpp->xAt( a0 ) );
370  else
371  return PyFloat_FromDouble( sipCpp->xAt( count + a0 ) );
372  }
373  % End
374 #endif
375 
376 #ifndef SIP_RUN
377  double yAt( int index ) const override;
378 #else
379 
388  double yAt( int index ) const override;
389  % MethodCode
390  const int count = sipCpp->numPoints();
391  if ( a0 < -count || a0 >= count )
392  {
393  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
394  sipIsErr = 1;
395  }
396  else
397  {
398  if ( a0 >= 0 )
399  return PyFloat_FromDouble( sipCpp->yAt( a0 ) );
400  else
401  return PyFloat_FromDouble( sipCpp->yAt( count + a0 ) );
402  }
403  % End
404 #endif
405 
412  const double *xData() const SIP_SKIP
413  {
414  return mX.constData();
415  }
416 
423  const double *yData() const SIP_SKIP
424  {
425  return mY.constData();
426  }
427 
436  const double *zData() const SIP_SKIP
437  {
438  if ( mZ.empty() )
439  return nullptr;
440  else
441  return mZ.constData();
442  }
443 
452  const double *mData() const SIP_SKIP
453  {
454  if ( mM.empty() )
455  return nullptr;
456  else
457  return mM.constData();
458  }
459 
460 #ifndef SIP_RUN
461 
469  double zAt( int index ) const
470  {
471  if ( index >= 0 && index < mZ.size() )
472  return mZ.at( index );
473  else
474  return std::numeric_limits<double>::quiet_NaN();
475  }
476 #else
477 
488  double zAt( int index ) const;
489  % MethodCode
490  const int count = sipCpp->numPoints();
491  if ( a0 < -count || a0 >= count )
492  {
493  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
494  sipIsErr = 1;
495  }
496  else
497  {
498  if ( a0 >= 0 )
499  return PyFloat_FromDouble( sipCpp->zAt( a0 ) );
500  else
501  return PyFloat_FromDouble( sipCpp->zAt( count + a0 ) );
502  }
503  % End
504 #endif
505 
506 #ifndef SIP_RUN
507 
515  double mAt( int index ) const
516  {
517  if ( index >= 0 && index < mM.size() )
518  return mM.at( index );
519  else
520  return std::numeric_limits<double>::quiet_NaN();
521  }
522 #else
523 
534  double mAt( int index ) const;
535  % MethodCode
536  const int count = sipCpp->numPoints();
537  if ( a0 < -count || a0 >= count )
538  {
539  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
540  sipIsErr = 1;
541  }
542  else
543  {
544  if ( a0 >= 0 )
545  return PyFloat_FromDouble( sipCpp->mAt( a0 ) );
546  else
547  return PyFloat_FromDouble( sipCpp->mAt( count + a0 ) );
548  }
549  % End
550 #endif
551 
552 #ifndef SIP_RUN
553 
561  void setXAt( int index, double x );
562 #else
563 
575  void setXAt( int index, double x );
576  % MethodCode
577  const int count = sipCpp->numPoints();
578  if ( a0 < -count || a0 >= count )
579  {
580  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
581  sipIsErr = 1;
582  }
583  else
584  {
585  if ( a0 >= 0 )
586  sipCpp->setXAt( a0, a1 );
587  else
588  sipCpp->setXAt( count + a0, a1 );
589  }
590  % End
591 #endif
592 
593 #ifndef SIP_RUN
594 
602  void setYAt( int index, double y );
603 #else
604 
616  void setYAt( int index, double y );
617  % MethodCode
618  const int count = sipCpp->numPoints();
619  if ( a0 < -count || a0 >= count )
620  {
621  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
622  sipIsErr = 1;
623  }
624  else
625  {
626  if ( a0 >= 0 )
627  sipCpp->setYAt( a0, a1 );
628  else
629  sipCpp->setYAt( count + a0, a1 );
630  }
631  % End
632 #endif
633 
634 #ifndef SIP_RUN
635 
643  void setZAt( int index, double z )
644  {
645  if ( index >= 0 && index < mZ.size() )
646  mZ[ index ] = z;
647  }
648 #else
649 
660  void setZAt( int index, double z );
661  % MethodCode
662  const int count = sipCpp->numPoints();
663  if ( a0 < -count || a0 >= count )
664  {
665  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
666  sipIsErr = 1;
667  }
668  else
669  {
670  if ( a0 >= 0 )
671  sipCpp->setZAt( a0, a1 );
672  else
673  sipCpp->setZAt( count + a0, a1 );
674  }
675  % End
676 #endif
677 
678 #ifndef SIP_RUN
679 
687  void setMAt( int index, double m )
688  {
689  if ( index >= 0 && index < mM.size() )
690  mM[ index ] = m;
691  }
692 #else
693 
704  void setMAt( int index, double m );
705  % MethodCode
706  const int count = sipCpp->numPoints();
707  if ( a0 < -count || a0 >= count )
708  {
709  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
710  sipIsErr = 1;
711  }
712  else
713  {
714  if ( a0 >= 0 )
715  sipCpp->setMAt( a0, a1 );
716  else
717  sipCpp->setMAt( count + a0, a1 );
718  }
719  % End
720 #endif
721 
727  void setPoints( const QgsPointSequence &points );
728 
733  void append( const QgsLineString *line );
734 
739  void addVertex( const QgsPoint &pt );
740 
742  void close();
743 
748  QgsCompoundCurve *toCurveType() const override SIP_FACTORY;
749 
756  void extend( double startDistance, double endDistance );
757 
758 #ifndef SIP_RUN
759 
765  void visitPointsByRegularDistance( double distance, const std::function< bool( double x, double y, double z, double m,
766  double startSegmentX, double startSegmentY, double startSegmentZ, double startSegmentM,
767  double endSegmentX, double endSegmentY, double endSegmentZ, double endSegmentM
768  ) > &visitPoint ) const;
769 #endif
770 
771  //reimplemented methods
772  QString geometryType() const override SIP_HOLDGIL;
773  int dimension() const override SIP_HOLDGIL;
774  QgsLineString *clone() const override SIP_FACTORY;
775  void clear() override;
776  bool isEmpty() const override SIP_HOLDGIL;
777  int indexOf( const QgsPoint &point ) const final;
778  bool isValid( QString &error SIP_OUT, Qgis::GeometryValidityFlags flags = Qgis::GeometryValidityFlags() ) const override;
779  QgsLineString *snappedToGrid( double hSpacing, double vSpacing, double dSpacing = 0, double mSpacing = 0 ) const override SIP_FACTORY;
780  bool removeDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) override;
781  bool isClosed() const override SIP_HOLDGIL;
782  bool isClosed2D() const override SIP_HOLDGIL;
783  bool boundingBoxIntersects( const QgsRectangle &rectangle ) const override SIP_HOLDGIL;
784 
792  QVector< QgsVertexId > collectDuplicateNodes( double epsilon = 4 * std::numeric_limits<double>::epsilon(), bool useZValues = false ) const;
793 
794  QPolygonF asQPolygonF() const override;
795 
796  bool fromWkb( QgsConstWkbPtr &wkb ) override;
797  bool fromWkt( const QString &wkt ) override;
798 
799  int wkbSize( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
800  QByteArray asWkb( QgsAbstractGeometry::WkbFlags flags = QgsAbstractGeometry::WkbFlags() ) const override;
801  QString asWkt( int precision = 17 ) const override;
802  QDomElement asGml2( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
803  QDomElement asGml3( QDomDocument &doc, int precision = 17, const QString &ns = "gml", QgsAbstractGeometry::AxisOrder axisOrder = QgsAbstractGeometry::AxisOrder::XY ) const override;
804  json asJsonObject( int precision = 17 ) const override SIP_SKIP;
805  QString asKml( int precision = 17 ) const override;
806 
807  //curve interface
808  double length() const override SIP_HOLDGIL;
809 
810 #ifndef SIP_RUN
811  std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > > splitCurveAtVertex( int index ) const final;
812 #endif
813 
820  double length3D() const SIP_HOLDGIL;
821  QgsPoint startPoint() const override SIP_HOLDGIL;
822  QgsPoint endPoint() const override SIP_HOLDGIL;
823 
830  QgsLineString *curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override SIP_FACTORY;
831 
832  int numPoints() const override SIP_HOLDGIL;
833  int nCoordinates() const override SIP_HOLDGIL;
834  void points( QgsPointSequence &pt SIP_OUT ) const override;
835 
836  void draw( QPainter &p ) const override;
837 
838  void transform( const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform, bool transformZ = false ) override SIP_THROW( QgsCsException );
839  void transform( const QTransform &t, double zTranslate = 0.0, double zScale = 1.0, double mTranslate = 0.0, double mScale = 1.0 ) override;
840 
841  void addToPainterPath( QPainterPath &path ) const override;
842  void drawAsPolygon( QPainter &p ) const override;
843 
844  bool insertVertex( QgsVertexId position, const QgsPoint &vertex ) override;
845  bool moveVertex( QgsVertexId position, const QgsPoint &newPos ) override;
846  bool deleteVertex( QgsVertexId position ) override;
847 
848  QgsLineString *reversed() const override SIP_FACTORY;
849  QgsPoint *interpolatePoint( double distance ) const override SIP_FACTORY;
850  QgsLineString *curveSubstring( double startDistance, double endDistance ) const override SIP_FACTORY;
851 
852  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;
853  bool pointAt( int node, QgsPoint &point, QgsVertexId::VertexType &type ) const override;
854 
855  QgsPoint centroid() const override;
856 
857  void sumUpArea( double &sum SIP_OUT ) const override;
858  double vertexAngle( QgsVertexId vertex ) const override;
859  double segmentLength( QgsVertexId startVertex ) const override;
860  bool addZValue( double zValue = 0 ) override;
861  bool addMValue( double mValue = 0 ) override;
862 
863  bool dropZValue() override;
864  bool dropMValue() override;
865  void swapXy() override;
866 
867  bool convertTo( QgsWkbTypes::Type type ) override;
868 
869  bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
870  void scroll( int firstVertexIndex ) final;
871 
872 #ifndef SIP_RUN
873  void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
874  void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
875 
883  inline static const QgsLineString *cast( const QgsAbstractGeometry *geom )
884  {
885  if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::LineString )
886  return static_cast<const QgsLineString *>( geom );
887  return nullptr;
888  }
889 #endif
890 
892 
893 #ifdef SIP_RUN
894  SIP_PYOBJECT __repr__();
895  % MethodCode
896  QString wkt = sipCpp->asWkt();
897  if ( wkt.length() > 1000 )
898  wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
899  QString str = QStringLiteral( "<QgsLineString: %1>" ).arg( wkt );
900  sipRes = PyUnicode_FromString( str.toUtf8().constData() );
901  % End
902 
912  SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsPoint );
913  % MethodCode
914  const int count = sipCpp->numPoints();
915  if ( a0 < -count || a0 >= count )
916  {
917  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
918  sipIsErr = 1;
919  }
920  else
921  {
922  std::unique_ptr< QgsPoint > p;
923  if ( a0 >= 0 )
924  p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
925  else
926  p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
927  sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
928  }
929  % End
930 
940  void __setitem__( int index, const QgsPoint &point );
941  % MethodCode
942  const int count = sipCpp->numPoints();
943  if ( a0 < -count || a0 >= count )
944  {
945  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
946  sipIsErr = 1;
947  }
948  else
949  {
950  if ( a0 < 0 )
951  a0 = count + a0;
952  sipCpp->setXAt( a0, a1->x() );
953  sipCpp->setYAt( a0, a1->y() );
954  if ( sipCpp->isMeasure() )
955  sipCpp->setMAt( a0, a1->m() );
956  if ( sipCpp->is3D() )
957  sipCpp->setZAt( a0, a1->z() );
958  }
959  % End
960 
961 
971  void __delitem__( int index );
972  % MethodCode
973  const int count = sipCpp->numPoints();
974  if ( a0 >= 0 && a0 < count )
975  sipCpp->deleteVertex( QgsVertexId( -1, -1, a0 ) );
976  else if ( a0 < 0 && a0 >= -count )
977  sipCpp->deleteVertex( QgsVertexId( -1, -1, count + a0 ) );
978  else
979  {
980  PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
981  sipIsErr = 1;
982  }
983  % End
984 
985 #endif
986 
987  protected:
988 
989  int compareToSameClass( const QgsAbstractGeometry *other ) const final;
990  QgsRectangle calculateBoundingBox() const override;
991 
992  private:
993  QVector<double> mX;
994  QVector<double> mY;
995  QVector<double> mZ;
996  QVector<double> mM;
997 
998  void importVerticesFromWkb( const QgsConstWkbPtr &wkb );
999 
1005  void fromWkbPoints( QgsWkbTypes::Type type, const QgsConstWkbPtr &wkb )
1006  {
1007  mWkbType = type;
1008  importVerticesFromWkb( wkb );
1009  }
1010 
1011  friend class QgsPolygon;
1012  friend class QgsTriangle;
1013  friend class TestQgsGeometry;
1014 
1015 };
1016 
1017 // clazy:excludeall=qstring-allocations
1018 
1019 #endif // QGSLINESTRING_H
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:63
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.
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.
QgsCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type.
Definition: qgscurve.cpp:205
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:44
const double * yData() const
Returns a const pointer to the y vertex data.
static const QgsLineString * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
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.
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.
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:702
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:189
#define SIP_TYPEHINT(type)
Definition: qgis_sip.h:218
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_OUT
Definition: qgis_sip.h:58
#define SIP_HOLDGIL
Definition: qgis_sip.h:157
#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:68
int precision
Utility class for identifying a unique vertex within a geometry.