QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
30class 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
44class 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
922 void sumUpArea( double &sum SIP_OUT ) const override;
923
924 double vertexAngle( QgsVertexId vertex ) const override;
925 double segmentLength( QgsVertexId startVertex ) const override;
926 bool addZValue( double zValue = 0 ) override;
927 bool addMValue( double mValue = 0 ) override;
928
929 bool dropZValue() override;
930 bool dropMValue() override;
931 void swapXy() override;
932
933 bool convertTo( QgsWkbTypes::Type type ) override;
934
935 bool transform( QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback = nullptr ) override;
936 void scroll( int firstVertexIndex ) final;
937
938#ifndef SIP_RUN
939 void filterVertices( const std::function< bool( const QgsPoint & ) > &filter ) override;
940 void transformVertices( const std::function< QgsPoint( const QgsPoint & ) > &transform ) override;
941
949 inline static const QgsLineString *cast( const QgsAbstractGeometry *geom )
950 {
951 if ( geom && QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::LineString )
952 return static_cast<const QgsLineString *>( geom );
953 return nullptr;
954 }
955#endif
956
958
959#ifdef SIP_RUN
960 SIP_PYOBJECT __repr__();
961 % MethodCode
962 QString wkt = sipCpp->asWkt();
963 if ( wkt.length() > 1000 )
964 wkt = wkt.left( 1000 ) + QStringLiteral( "..." );
965 QString str = QStringLiteral( "<QgsLineString: %1>" ).arg( wkt );
966 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
967 % End
968
978 SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsPoint );
979 % MethodCode
980 const int count = sipCpp->numPoints();
981 if ( a0 < -count || a0 >= count )
982 {
983 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
984 sipIsErr = 1;
985 }
986 else
987 {
988 std::unique_ptr< QgsPoint > p;
989 if ( a0 >= 0 )
990 p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
991 else
992 p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
993 sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
994 }
995 % End
996
1006 void __setitem__( int index, const QgsPoint &point );
1007 % MethodCode
1008 const int count = sipCpp->numPoints();
1009 if ( a0 < -count || a0 >= count )
1010 {
1011 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
1012 sipIsErr = 1;
1013 }
1014 else
1015 {
1016 if ( a0 < 0 )
1017 a0 = count + a0;
1018 sipCpp->setXAt( a0, a1->x() );
1019 sipCpp->setYAt( a0, a1->y() );
1020 if ( sipCpp->isMeasure() )
1021 sipCpp->setMAt( a0, a1->m() );
1022 if ( sipCpp->is3D() )
1023 sipCpp->setZAt( a0, a1->z() );
1024 }
1025 % End
1026
1027
1037 void __delitem__( int index );
1038 % MethodCode
1039 const int count = sipCpp->numPoints();
1040 if ( a0 >= 0 && a0 < count )
1041 sipCpp->deleteVertex( QgsVertexId( -1, -1, a0 ) );
1042 else if ( a0 < 0 && a0 >= -count )
1043 sipCpp->deleteVertex( QgsVertexId( -1, -1, count + a0 ) );
1044 else
1045 {
1046 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
1047 sipIsErr = 1;
1048 }
1049 % End
1050
1051#endif
1052
1058 QgsBox3d calculateBoundingBox3d() const;
1059
1060 protected:
1061
1062 int compareToSameClass( const QgsAbstractGeometry *other ) const final;
1063 QgsRectangle calculateBoundingBox() const override;
1064
1065 private:
1066 QVector<double> mX;
1067 QVector<double> mY;
1068 QVector<double> mZ;
1069 QVector<double> mM;
1070
1071 void importVerticesFromWkb( const QgsConstWkbPtr &wkb );
1072
1078 void fromWkbPoints( QgsWkbTypes::Type type, const QgsConstWkbPtr &wkb )
1079 {
1080 mWkbType = type;
1081 importVerticesFromWkb( wkb );
1082 }
1083
1084 friend class QgsPolygon;
1085 friend class QgsTriangle;
1086 friend class TestQgsGeometry;
1087
1088};
1089
1090// clazy:excludeall=qstring-allocations
1091
1092#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.
const double * xData() const
Returns a const pointer to the x vertex data.
QVector< double > xVector() const
Returns the x vertex values as a vector.
const double * zData() const
Returns a const pointer to the z vertex data, or nullptr if the linestring does not have z values.
QVector< double > yVector() const
Returns the y vertex values as a vector.
static const QgsLineString * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
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.
const double * mData() const
Returns a const pointer to the m vertex data, or nullptr if the linestring does not have m values.
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.
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_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
#define SIP_THROW(name,...)
Definition: qgis_sip.h:198
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