18#ifndef QGSLINESTRING_H
19#define QGSLINESTRING_H
32using namespace Qt::StringLiterals;
84 if ( !PySequence_Check( a0 ) )
86 PyErr_SetString( PyExc_TypeError, u
"A sequence of QgsPoint, QgsPointXY or array of floats is expected"_s.toUtf8().constData() );
92 const int size = PySequence_Size( a0 );
105 for (
int i = 0; i < size; ++i )
107 PyObject *value = PySequence_GetItem( a0, i );
110 PyErr_SetString( PyExc_TypeError, u
"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
115 if ( PySequence_Check( value ) )
117 const int elementSize = PySequence_Size( value );
118 if ( elementSize < 2 || elementSize > 4 )
121 PyErr_SetString( PyExc_TypeError, u
"Invalid sequence size at index %1. Expected an array of 2-4 float values, got %2."_s.arg( i ).arg( elementSize ).toUtf8().constData() );
128 for (
int j = 0; j < elementSize; ++j )
130 PyObject *element = PySequence_GetItem( value, j );
133 PyErr_SetString( PyExc_TypeError, u
"Invalid type at index %1."_s.arg( i ) .toUtf8().constData() );
139 double d = PyFloat_AsDouble( element );
140 if ( PyErr_Occurred() )
142 Py_DECREF( element );
151 if ( i == 0 && j == 2 )
157 else if ( i > 0 && j == 2 && hasZ )
162 if ( i == 0 && j == 3 )
168 else if ( i > 0 && j == 3 && hasM )
173 Py_DECREF( element );
176 if ( hasZ && elementSize < 3 )
177 zl.append( std::numeric_limits< double >::quiet_NaN() );
178 if ( hasM && elementSize < 4 )
179 ml.append( std::numeric_limits< double >::quiet_NaN() );
190 if ( sipCanConvertToType( value, sipType_QgsPointXY, SIP_NOT_NONE ) )
193 QgsPointXY *p =
reinterpret_cast<QgsPointXY *
>( sipConvertToType( value, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
199 sipReleaseType( p, sipType_QgsPointXY, state );
201 else if ( sipCanConvertToType( value, sipType_QgsPoint, SIP_NOT_NONE ) )
204 QgsPoint *p =
reinterpret_cast<QgsPoint *
>( sipConvertToType( value, sipType_QgsPoint, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
210 if ( i == 0 && p->
is3D() )
216 else if ( i > 0 && hasZ )
227 else if ( i > 0 && hasM )
235 sipReleaseType( p, sipType_QgsPoint, state );
247 PyErr_SetString( PyExc_TypeError, u
"Invalid type at index %1. Expected QgsPoint, QgsPointXY or array of floats."_s.arg( i ) .toUtf8().constData() );
253 sipCpp =
new sipQgsLineString(
QgsLineString( xl, yl, zl, ml, is25D ) );
282 QgsLineString(
const QVector<double> &x,
const QVector<double> &y,
283 const QVector<double> &z = QVector<double>(),
284 const QVector<double> &m = QVector<double>(),
bool is25DType =
false )
SIP_HOLDGIL;
309 static std::unique_ptr< QgsLineString >
fromQPolygonF(
const QPolygonF &polygon );
328 void setPoints(
size_t size,
const double *x,
const double *y,
const double *z =
nullptr,
const double *m =
nullptr )
SIP_SKIP;
350 void extend(
double startDistance,
double endDistance );
360 double startSegmentX,
double startSegmentY,
double startSegmentZ,
double startSegmentM,
361 double endSegmentX,
double endSegmentY,
double endSegmentZ,
double endSegmentM
362 ) > &visitPoint )
const;
369 void clear()
override;
373 bool removeDuplicateNodes(
double epsilon = 4 * std::numeric_limits<double>::epsilon(),
bool useZValues =
false )
override;
386 QVector< QgsVertexId >
collectDuplicateNodes(
double epsilon = 4 * std::numeric_limits<double>::epsilon(),
bool useZValues =
false )
const;
395 QString
asKml(
int precision = 17 )
const override;
401 std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > >
splitCurveAtVertex(
int index )
const final;
430 void draw( QPainter &p )
const override;
437 bool deleteVertices(
const QSet<QgsVertexId> &positions )
override;
514 SIP_PYOBJECT __repr__();
516 QString wkt = sipCpp->asWkt();
517 if ( wkt.length() > 1000 )
518 wkt = wkt.left( 1000 ) + u
"..."_s;
519 QString str = u
"<QgsLineString: %1>"_s.arg( wkt );
520 sipRes = PyUnicode_FromString( str.toUtf8().constData() );
534 const int count = sipCpp->numPoints();
535 if ( a0 < -count || a0 >= count )
537 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
542 std::unique_ptr< QgsPoint > p;
544 p = std::make_unique< QgsPoint >( sipCpp->pointN( a0 ) );
546 p = std::make_unique< QgsPoint >( sipCpp->pointN( count + a0 ) );
547 sipRes = sipConvertFromType( p.release(), sipType_QgsPoint, Py_None );
560 void __setitem__(
int index,
const QgsPoint &point );
562 const int count = sipCpp->numPoints();
563 if ( a0 < -count || a0 >= count )
565 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
572 sipCpp->setXAt( a0, a1->x() );
573 sipCpp->setYAt( a0, a1->y() );
574 if ( sipCpp->isMeasure() )
575 sipCpp->setMAt( a0, a1->m() );
576 if ( sipCpp->is3D() )
577 sipCpp->setZAt( a0, a1->z() );
591 void __delitem__(
int index );
593 const int count = sipCpp->numPoints();
594 if ( a0 >= 0 && a0 < count )
595 sipCpp->deleteVertex( QgsVertexId( -1, -1, a0 ) );
596 else if ( a0 < 0 && a0 >= -count )
597 sipCpp->deleteVertex( QgsVertexId( -1, -1, count + a0 ) );
600 PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
614 Q_DECL_DEPRECATED QgsBox3D calculateBoundingBox3d() const
SIP_DEPRECATED;
621 QgsBox3D calculateBoundingBox3D() const override;
629 std::unique_ptr< QgsLineString > measuredLine(
double start,
double end ) const;
644 std::unique_ptr< QgsLineString > interpolateM(
bool use3DDistance = true ) const;
670 bool lineLocatePointByM(
double m,
double &x
SIP_OUT,
double &y
SIP_OUT,
double &z
SIP_OUT,
double &distanceFromStart
SIP_OUT,
bool use3DDistance = true ) const;
678 void fromWkbPoints( Qgis::WkbType type, const QgsConstWkbPtr &wkb )
684 bool lineLocatePointByMPrivate(
double m,
double &x,
double &y,
double &z,
double &distanceFromStart,
bool use3DDistance,
bool haveInterpolatedM )
const;
QFlags< GeometryValidityFlag > GeometryValidityFlags
Geometry validity flags.
VertexType
Types of vertex.
WkbType
The WKB type describes the number of dimensions a geometry has.
virtual QgsAbstractGeometry * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0, bool removeRedundantPoints=false) const =0
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
@ MaximumAngle
Maximum angle between generating radii (lines from arc center to output vertices).
virtual bool convertTo(Qgis::WkbType type)
Converts the geometry to a specified type.
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
virtual void draw(QPainter &p) const =0
Draws the geometry using the specified QPainter.
bool isMeasure() const
Returns true if the geometry contains m values.
virtual QgsAbstractGeometry * simplifyByDistance(double tolerance) const =0
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
@ XY
X comes before Y (or lon before lat).
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 bool deleteVertices(const QSet< QgsVertexId > &positions)=0
Deletes vertices within the geometry.
virtual QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const =0
Returns a GML2 representation of the geometry.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
virtual bool insertVertex(QgsVertexId position, const QgsPoint &vertex)=0
Inserts a vertex into the geometry.
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
virtual json asJsonObject(int precision=17) const
Returns a json object representation of the geometry.
virtual QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const =0
Returns a GML3 representation of the geometry.
virtual bool boundingBoxIntersects(const QgsRectangle &rectangle) const
Returns true if the bounding box of this geometry intersects with a rectangle.
virtual bool deleteVertex(QgsVertexId position)=0
Deletes a vertex within the geometry.
virtual QgsPoint centroid() const
Returns the centroid of the geometry.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
virtual bool removeDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false)=0
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerat...
QgsAbstractGeometry()=default
virtual double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const =0
Searches for the closest segment of the geometry to a given point.
A 3-dimensional box composed of x, y, z coordinates.
Compound curve geometry type.
virtual bool pointAt(int node, QgsPoint &point, Qgis::VertexType &type) const =0
Returns the point and vertex type of a point within the curve.
virtual QgsCurve * curveSubstring(double startDistance, double endDistance) const =0
Returns a new curve representing a substring of this curve.
virtual bool isClosed() const
Returns true if the curve is closed.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
virtual bool isClosed2D() const
Returns true if the curve is closed.
virtual QPolygonF asQPolygonF() const
Returns a QPolygonF representing the points.
virtual void addToPainterPath(QPainterPath &path) const =0
Adds a curve to a painter path.
virtual int indexOf(const QgsPoint &point) const =0
Returns the index of the first vertex matching the given point, or -1 if a matching vertex is not fou...
QgsCurve * toCurveType() const override
Returns the geometry converted to the more generic curve type.
virtual void sumUpArea(double &sum) const =0
Sums up the area of the curve by iterating over the vertices (shoelace formula).
QString asKml(int precision=17) const override
Returns a KML representation of the geometry.
virtual QgsPoint * interpolatePoint(double distance) const =0
Returns an interpolated point on the curve at the specified distance.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
virtual double distanceBetweenVertices(QgsVertexId fromVertex, QgsVertexId toVertex) const =0
Returns the distance along the curve between two vertices.
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 void drawAsPolygon(QPainter &p) const =0
Draws the curve as a polygon on the specified QPainter.
virtual QgsLineString * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve.
virtual void sumUpArea3D(double &sum) const =0
Sums up the 3d area of the curve by iterating over the vertices (shoelace formula).
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.
static std::unique_ptr< QgsLineString > fromBezierCurve(const QgsPoint &start, const QgsPoint &controlPoint1, const QgsPoint &controlPoint2, const QgsPoint &end, int segments=30)
Returns a new linestring created by segmentizing the bezier curve between start and end,...
QVector< QgsLineString * > splitToDisjointXYParts() const
Divides the linestring into parts that don't share any points or lines.
double length3D() const
Returns the length in 3D world of the line string.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
QgsLineString()
Constructor for an empty linestring geometry.
static const QgsLineString * cast(const QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
friend class TestQgsGeometry
void close()
Closes the line string by appending the first point to the end of the line, if it is not already clos...
void extend(double startDistance, double endDistance)
Extends the line geometry by extrapolating out the start or end of the line by a specified distance.
static QgsLineString * cast(QgsAbstractGeometry *geom)
Cast the geom to a QgsLineString.
QVector< QgsVertexId > collectDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) const
Returns a list of any duplicate nodes contained in the geometry, within the specified tolerance.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
Point geometry type, with support for z-dimension and m-values.
A rectangle specified with double values.
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
void clear() override
Clears the geometry, ie reset it to a null geometry.
void setPoints(const QgsPointSequence &points)
Resets the simple curve to match the specified list of points.
void importVerticesFromWkb(const QgsConstWkbPtr &wkb)
Imports vertices from wkb geometry representation.
QgsSimpleCurve * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
#define SIP_TYPEHINT(type)
void visitPointsByRegularDistance(const QgsLineString *line, const QgsLineString *linePainterUnits, bool emitFirstPoint, const double distance, const double averageAngleLengthPainterUnits, const VisitPointFunction &visitPoint)
QLineF segment(int index, QRectF rect, double radius)
Utility class for identifying a unique vertex within a geometry.