18 #ifndef QGSLINESTRING_H
19 #define QGSLINESTRING_H
24 #include "qgis_core.h"
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 )];
81 if ( !PySequence_Check( a0 ) )
83 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"A sequence of QgsPoint, QgsPointXY or array of floats is expected" ).toUtf8().constData() );
89 const int size = PySequence_Size( a0 );
102 for (
int i = 0; i < size; ++i )
104 PyObject *value = PySequence_GetItem( a0, i );
107 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
112 if ( PySequence_Check( value ) )
114 const int elementSize = PySequence_Size( value );
115 if ( elementSize < 2 || elementSize > 4 )
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() );
125 for (
int j = 0; j < elementSize; ++j )
127 PyObject *element = PySequence_GetItem( value, j );
130 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Invalid type at index %1." ).arg( i ) .toUtf8().constData() );
136 double d = PyFloat_AsDouble( element );
137 if ( PyErr_Occurred() )
148 if ( i == 0 && j == 2 )
154 else if ( i > 0 && j == 2 && hasZ )
159 if ( i == 0 && j == 3 )
165 else if ( i > 0 && j == 3 && hasM )
170 Py_DECREF( element );
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() );
187 if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
190 QgsPointXY *p =
reinterpret_cast<QgsPointXY *
>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
196 sipReleaseType( p, sipType_QgsPointXY, state );
198 else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
201 QgsPoint *p =
reinterpret_cast<QgsPoint *
>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
207 if ( i == 0 && p->
is3D() )
213 else if ( i > 0 && hasZ )
224 else if ( i > 0 && hasM )
232 sipReleaseType( p, sipType_QgsPoint, state );
244 PyErr_SetString( PyExc_TypeError, QStringLiteral(
"Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats." ).arg( i ) .toUtf8().constData() );
250 sipCpp =
new sipQgsLineString(
QgsLineString( xl, yl, zl, ml, is25D ) );
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;
329 const int count = sipCpp->numPoints();
330 if ( a0 < -count || a0 >= count )
332 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
337 std::unique_ptr< QgsPoint > p;
339 p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
341 p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
342 sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
348 double xAt(
int index )
const override;
359 double xAt(
int index )
const override;
361 const int count = sipCpp->numPoints();
362 if ( a0 < -count || a0 >= count )
364 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
370 return PyFloat_FromDouble( sipCpp->xAt( a0 ) );
372 return PyFloat_FromDouble( sipCpp->xAt( count + a0 ) );
378 double yAt(
int index )
const override;
389 double yAt(
int index )
const override;
391 const int count = sipCpp->numPoints();
392 if ( a0 < -count || a0 >= count )
394 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
400 return PyFloat_FromDouble( sipCpp->yAt( a0 ) );
402 return PyFloat_FromDouble( sipCpp->yAt( count + a0 ) );
415 return mX.constData();
426 return mY.constData();
442 return mZ.constData();
458 return mM.constData();
511 double zAt(
int index )
const
513 if ( index >= 0 && index < mZ.size() )
514 return mZ.at( index );
516 return std::numeric_limits<double>::quiet_NaN();
530 double zAt(
int index )
const;
532 const int count = sipCpp->numPoints();
533 if ( a0 < -count || a0 >= count )
535 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
541 return PyFloat_FromDouble( sipCpp->zAt( a0 ) );
543 return PyFloat_FromDouble( sipCpp->zAt( count + a0 ) );
557 double mAt(
int index )
const
559 if ( index >= 0 && index < mM.size() )
560 return mM.at( index );
562 return std::numeric_limits<double>::quiet_NaN();
576 double mAt(
int index )
const;
578 const int count = sipCpp->numPoints();
579 if ( a0 < -count || a0 >= count )
581 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
587 return PyFloat_FromDouble( sipCpp->mAt( a0 ) );
589 return PyFloat_FromDouble( sipCpp->mAt( count + a0 ) );
603 void setXAt(
int index,
double x );
617 void setXAt(
int index,
double x );
619 const int count = sipCpp->numPoints();
620 if ( a0 < -count || a0 >= count )
622 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
628 sipCpp->setXAt( a0, a1 );
630 sipCpp->setXAt( count + a0, a1 );
644 void setYAt(
int index,
double y );
658 void setYAt(
int index,
double y );
660 const int count = sipCpp->numPoints();
661 if ( a0 < -count || a0 >= count )
663 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
669 sipCpp->setYAt( a0, a1 );
671 sipCpp->setYAt( count + a0, a1 );
687 if ( index >= 0 && index < mZ.size() )
702 void setZAt(
int index,
double z );
704 const int count = sipCpp->numPoints();
705 if ( a0 < -count || a0 >= count )
707 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
713 sipCpp->setZAt( a0, a1 );
715 sipCpp->setZAt( count + a0, a1 );
731 if ( index >= 0 && index < mM.size() )
746 void setMAt(
int index,
double m );
748 const int count = sipCpp->numPoints();
749 if ( a0 < -count || a0 >= count )
751 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
757 sipCpp->setMAt( a0, a1 );
759 sipCpp->setMAt( count + a0, a1 );
777 void setPoints(
size_t size,
const double *x,
const double *y,
const double *z =
nullptr,
const double *m =
nullptr )
SIP_SKIP;
796 void addVertex( const
QgsPoint &pt );
813 void extend(
double startDistance,
double endDistance );
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;
832 void clear() override;
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;
849 QVector<
QgsVertexId > collectDuplicateNodes(
double epsilon = 4 * std::numeric_limits<
double>::epsilon(),
bool useZValues = false ) const;
851 QPolygonF asQPolygonF() const override;
854 bool fromWkt( const QString &wkt ) override;
858 QString asWkt(
int precision = 17 ) const override;
862 QString asKml(
int precision = 17 ) const override;
868 std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > >
splitCurveAtVertex(
int index )
const final;
887 QgsLineString *curveToLine(
double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override
SIP_FACTORY;
893 void draw( QPainter &p ) const override;
896 void transform( const QTransform &t,
double zTranslate = 0.0,
double zScale = 1.0,
double mTranslate = 0.0,
double mScale = 1.0 ) override;
898 void addToPainterPath( QPainterPath &path ) const override;
899 void drawAsPolygon( QPainter &p ) const override;
903 bool deleteVertex(
QgsVertexId position ) override;
910 bool pointAt(
int node,
QgsPoint &point,
Qgis::VertexType &type ) const override;
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;
920 bool dropZValue() override;
921 bool dropMValue() override;
922 void swapXy() override;
927 void scroll(
int firstVertexIndex ) final;
951 SIP_PYOBJECT __repr__();
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() );
971 const int count = sipCpp->numPoints();
972 if ( a0 < -count || a0 >= count )
974 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
979 std::unique_ptr< QgsPoint > p;
981 p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
983 p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
984 sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
997 void __setitem__(
int index,
const QgsPoint &point );
999 const int count = sipCpp->numPoints();
1000 if ( a0 < -count || a0 >= count )
1002 PyErr_SetString( PyExc_IndexError, QByteArray::number( 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() );
1028 void __delitem__(
int index );
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 ) );
1037 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
1049 QgsBox3d calculateBoundingBox3d()
const;
1072 importVerticesFromWkb( wkb );
1077 friend class TestQgsGeometry;
1083 #endif // QGSLINESTRING_H