29#include <QPainterPath>
31#include <nlohmann/json.hpp>
45 auto result = std::make_unique< QgsCompoundCurve >();
47 return result.release();
52 const QgsCompoundCurve *otherCurve = qgsgeometry_cast<const QgsCompoundCurve *>( other );
58 while ( i < mCurves.size() && j < otherCurve->mCurves.size() )
62 const int comparison = aGeom->
compareTo( bGeom );
63 if ( comparison != 0 )
70 if ( i < mCurves.size() )
74 if ( j < otherCurve->mCurves.size() )
83 return QStringLiteral(
"CompoundCurve" );
94 mCurves.reserve( curve.mCurves.size() );
97 mCurves.append(
c->clone() );
104 if ( &curve !=
this )
107 for (
const QgsCurve *
c : curve.mCurves )
109 mCurves.append(
c->clone() );
123 qDeleteAll( mCurves );
130 if ( mCurves.empty() )
135 QgsBox3D bbox = mCurves.at( 0 )->boundingBox3D();
136 for (
int i = 1; i < mCurves.size(); ++i )
138 QgsBox3D curveBox = mCurves.at( i )->boundingBox3D();
147 if ( index < 1 || index >= size - 1 )
153 if (
QgsCompoundCurve *curve2 = qgsgeometry_cast< QgsCompoundCurve *>( p2.get() ) )
156 mCurves = std::move( curve2->mCurves );
158 if (
QgsCompoundCurve *curve1 = qgsgeometry_cast< QgsCompoundCurve *>( p1.get() ) )
161 mCurves.append( curve1->mCurves );
162 curve1->mCurves.clear();
184 for (
int i = 0; i <
nCurves; ++i )
187 wkbPtr -= 1 +
sizeof( int );
200 currentCurve->
fromWkb( wkbPtr );
201 mCurves.append( currentCurve );
216 QString secondWithoutParentheses =
parts.second;
217 secondWithoutParentheses = secondWithoutParentheses.remove(
'(' ).remove(
')' ).simplified().remove(
' ' );
218 if ( (
parts.second.compare( QLatin1String(
"EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
219 secondWithoutParentheses.isEmpty() )
222 QString defaultChildWkbType = QStringLiteral(
"LineString%1%2" ).arg(
is3D() ? QStringLiteral(
"Z" ) : QString(),
isMeasure() ? QStringLiteral(
"M" ) : QString() );
225 for (
const QString &childWkt : blocks )
238 if ( !mCurves.back()->fromWkt( childWkt ) )
249 for (
const QgsCurve *curve : std::as_const( mCurves ) )
251 hasZ = hasZ || curve->is3D();
252 hasM = hasM || curve->isMeasure();
266 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
267 for (
const QgsCurve *curve : mCurves )
269 binarySize += curve->wkbSize( flags );
280 wkb << static_cast<quint32>(
wkbType() );
281 wkb << static_cast<quint32>( mCurves.size() );
282 for (
const QgsCurve *curve : mCurves )
284 wkb << curve->asWkb( flags );
293 wkt += QLatin1String(
" EMPTY" );
296 wkt += QLatin1String(
" (" );
297 for (
const QgsCurve *curve : mCurves )
299 QString childWkt = curve->asWkt(
precision );
300 if ( qgsgeometry_cast<const QgsLineString *>( curve ) )
303 childWkt = childWkt.mid( childWkt.indexOf(
'(' ) );
305 wkt += childWkt +
',';
307 if ( wkt.endsWith(
',' ) )
319 std::unique_ptr< QgsLineString > line(
curveToLine() );
320 QDomElement gml = line->asGml2( doc,
precision, ns, axisOrder );
326 QDomElement compoundCurveElem = doc.createElementNS( ns, QStringLiteral(
"CompositeCurve" ) );
329 return compoundCurveElem;
331 for (
const QgsCurve *curve : mCurves )
333 QDomElement curveMemberElem = doc.createElementNS( ns, QStringLiteral(
"curveMember" ) );
334 QDomElement curveElem = curve->asGml3( doc,
precision, ns, axisOrder );
335 curveMemberElem.appendChild( curveElem );
336 compoundCurveElem.appendChild( curveMemberElem );
339 return compoundCurveElem;
345 std::unique_ptr< QgsLineString > line(
curveToLine() );
352 for (
const QgsCurve *curve : mCurves )
354 length += curve->length();
361 if ( mCurves.empty() )
365 return mCurves.at( 0 )->startPoint();
370 if ( mCurves.empty() )
374 return mCurves.at( mCurves.size() - 1 )->endPoint();
380 if ( mCurves.empty() )
385 mCurves[0]->points( pts );
386 for (
int i = 1; i < mCurves.size(); ++i )
389 mCurves[i]->points( pList );
404 for (
int i = 0; i <
nCurves; ++i )
406 nPoints += mCurves.at( i )->numPoints() - 1;
414 if ( mCurves.isEmpty() )
419 if ( !curve->isEmpty() )
427 if ( mCurves.isEmpty() )
430 for (
int i = 0; i < mCurves.size() ; ++i )
432 if ( !mCurves[i]->
isValid( error, flags ) )
434 error = QObject::tr(
"Curve[%1]: %2" ).arg( i + 1 ).arg( error );
444 for (
const QgsCurve *curve : mCurves )
446 const int curveIndex = curve->indexOf( point );
447 if ( curveIndex >= 0 )
448 return curveStart + curveIndex;
451 curveStart += curve->numPoints() - 1;
459 std::unique_ptr< QgsLineString > currentLine;
460 for (
const QgsCurve *curve : mCurves )
462 currentLine.reset( curve->curveToLine( tolerance, toleranceType ) );
463 line->
append( currentLine.get() );
474 std::unique_ptr<QgsCurve> gridified(
static_cast< QgsCurve *
>( curve->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing, removeRedundantPoints ) ) );
477 result->mCurves.append( gridified.release() );
481 if ( result->mCurves.empty() )
484 return result.release();
489 std::unique_ptr< QgsLineString > line(
curveToLine() );
490 return line->simplifyByDistance( tolerance );
496 const QVector< QgsCurve * > curves = mCurves;
502 if ( curve->numPoints() == 0 ||
qgsDoubleNear( curve->length(), 0.0, epsilon ) )
505 delete mCurves.takeAt( i );
513 curve->moveVertex(
QgsVertexId( -1, -1, 0 ), lastEnd );
524 if ( mCurves.empty() )
538 for (
const QgsCurve *curve : mCurves )
540 if ( curve->boundingBoxIntersects( box3d ) )
553 if ( mCurves.size() == 1 )
554 return mCurves.at( 0 );
561 if ( i < 0 || i >= mCurves.size() )
565 return mCurves.at( i );
573 if ( mCurves.empty() )
595 QgsLineString *previousLineString = !mCurves.empty() ? qgsgeometry_cast< QgsLineString * >( mCurves.constLast() ) :
nullptr;
596 const QgsLineString *newLineString = qgsgeometry_cast< const QgsLineString * >(
c );
597 const bool canExtendPrevious = extendPrevious && previousLineString && newLineString;
598 if ( canExtendPrevious )
600 previousLineString->
append( newLineString );
615 if ( i < 0 || i >= mCurves.size() )
620 delete mCurves.takeAt( i );
633 if ( !mCurves.isEmpty() )
635 lastCurve = mCurves.at( mCurves.size() - 1 );
642 mCurves.append( line );
660 QVector< QgsCurve * > newCurves;
661 newCurves.reserve( mCurves.size() );
662 for (
QgsCurve *curve : std::as_const( mCurves ) )
664 if ( lastCurve && lastCurve->
wkbType() == curve->wkbType() )
666 if (
QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( lastCurve ) )
668 ls->append( qgsgeometry_cast< QgsLineString * >( curve ) );
671 else if (
QgsCircularString *cs = qgsgeometry_cast< QgsCircularString * >( lastCurve ) )
673 cs->append( qgsgeometry_cast< QgsCircularString * >( curve ) );
688 for (
const QgsCurve *curve : mCurves )
696 for (
QgsCurve *curve : std::as_const( mCurves ) )
698 curve->transform( ct, d, transformZ );
705 for (
QgsCurve *curve : std::as_const( mCurves ) )
707 curve->transform( t, zTranslate, zScale, mTranslate, mScale );
716 for (
const QgsCurve *curve : mCurves )
718 if ( curve != mCurves.at( 0 ) && pp.currentPosition() != curve->startPoint().toQPointF() )
720 pp.lineTo( curve->startPoint().toQPointF() );
722 curve->addToPainterPath( pp );
730 for (
const QgsCurve *curve : mCurves )
732 if ( curve != mCurves.at( 0 ) && pp.currentPosition() != curve->startPoint().toQPointF() )
734 pp.lineTo( curve->startPoint().toQPointF() );
736 curve->addToPainterPath( pp );
743 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
744 if ( curveIds.empty() )
748 int curveId = curveIds.at( 0 ).first;
749 if ( curveId >= mCurves.size() )
754 bool success = mCurves.at( curveId )->insertVertex( curveIds.at( 0 ).second, vertex );
764 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
765 QVector< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
766 for ( ; idIt != curveIds.constEnd(); ++idIt )
768 mCurves.at( idIt->first )->moveVertex( idIt->second, newPos );
771 bool success = !curveIds.isEmpty();
781 const QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
782 if ( curveIds.isEmpty() )
785 const int curveId = curveIds.at( 0 ).first;
786 QgsCurve *curve = mCurves.at( curveId );
787 const QgsVertexId subVertexId = curveIds.at( 0 ).second;
790 if ( curveIds.size() == 1 )
792 const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( curve );
795 if ( circularString && subVertexId.
vertex % 2 == 1 )
805 std::unique_ptr<QgsCircularString> curveC = std::make_unique<QgsCircularString>();
806 curveC->setPoints(
points.mid( subVertexId.
vertex + 1 ) );
807 mCurves.insert( curveId, curveC.release() );
811 std::unique_ptr<QgsLineString> curveB = std::make_unique<QgsLineString>();
812 curveB->setPoints( partB );
813 mCurves.insert( curveId, curveB.release() );
814 curve = mCurves.at( curveId );
816 if ( subVertexId.
vertex > 1 )
818 std::unique_ptr<QgsCircularString> curveA = std::make_unique<QgsCircularString>();
819 curveA->setPoints(
points.mid( 0, subVertexId.
vertex ) );
820 mCurves.insert( curveId, curveA.release() );
835 else if ( curveIds.size() == 2 )
837 const int nextCurveId = curveIds.at( 1 ).first;
838 QgsCurve *nextCurve = mCurves.at( nextCurveId );
839 const QgsVertexId nextSubVertexId = curveIds.at( 1 ).second;
841 Q_ASSERT( nextCurveId == curveId + 1 );
843 Q_ASSERT( nextSubVertexId.
vertex == 0 );
873 mCurves.insert( curveId, line );
885 mCurves.insert( nextCurveId, line );
898 mCurves.insert( curveId, line );
906 if ( endPointOfFirst != startPointOfSecond )
911 mCurves.insert( nextCurveId, line );
917 bool success = !curveIds.isEmpty();
923QVector< QPair<int, QgsVertexId> > QgsCompoundCurve::curveVertexId(
QgsVertexId id )
const
925 QVector< QPair<int, QgsVertexId> > curveIds;
927 int currentVertexIndex = 0;
928 for (
int i = 0; i < mCurves.size(); ++i )
930 int increment = mCurves.at( i )->numPoints() - 1;
931 if (
id.vertex >= currentVertexIndex &&
id.vertex <= currentVertexIndex + increment )
933 int curveVertexId =
id.vertex - currentVertexIndex;
937 vid.
vertex = curveVertexId;
938 curveIds.append( qMakePair( i, vid ) );
939 if ( curveVertexId == increment && i < ( mCurves.size() - 1 ) )
942 curveIds.append( qMakePair( i + 1, vid ) );
946 else if (
id.vertex >= currentVertexIndex &&
id.vertex == currentVertexIndex + increment + 1 && i == ( mCurves.size() - 1 ) )
948 int curveVertexId =
id.vertex - currentVertexIndex;
952 vid.
vertex = curveVertexId;
953 curveIds.append( qMakePair( i, vid ) );
956 currentVertexIndex += increment;
978 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
981 if ( curveIds.length() != 1 )
984 int curveId = curveIds[0].first;
992 if (
const QgsCircularString *circularString = qgsgeometry_cast<const QgsCircularString *>( curve ) )
997 if ( subVertexId.
vertex % 2 == 0 )
1001 circularString->points(
points );
1007 std::unique_ptr<QgsCircularString> curveA = std::make_unique<QgsCircularString>();
1008 curveA->setPoints( partA );
1009 std::unique_ptr<QgsLineString> curveB = std::make_unique<QgsLineString>();
1010 curveB->setPoints( partB );
1011 std::unique_ptr<QgsCircularString> curveC = std::make_unique<QgsCircularString>();
1012 curveC->setPoints( partC );
1016 mCurves.insert( curveId, curveC.release() );
1017 mCurves.insert( curveId, curveB.release() );
1018 if ( subVertexId.
vertex > 1 )
1019 mCurves.insert( curveId, curveA.release() );
1026 lineString->points(
points );
1032 std::unique_ptr<QgsLineString> curveA = std::make_unique<QgsLineString>();
1033 curveA->setPoints( partA );
1034 std::unique_ptr<QgsCircularString> curveB = std::make_unique<QgsCircularString>();
1035 curveB->setPoints( partB );
1036 std::unique_ptr<QgsLineString> curveC = std::make_unique<QgsLineString>();
1037 curveC->setPoints( partC );
1041 mCurves.insert( curveId, curveC.release() );
1042 mCurves.insert( curveId, curveB.release() );
1043 if ( subVertexId.
vertex > 1 )
1044 mCurves.insert( curveId, curveA.release() );
1062 int currentVertexId = 0;
1063 for (
int j = 0; j < mCurves.size(); ++j )
1065 int nCurvePoints = mCurves.at( j )->numPoints();
1066 if ( ( node - currentVertexId ) < nCurvePoints )
1068 return ( mCurves.at( j )->pointAt( node - currentVertexId, point, type ) );
1070 currentVertexId += ( nCurvePoints - 1 );
1077 int currentVertexId = 0;
1078 for (
int j = 0; j < mCurves.size(); ++j )
1080 int nCurvePoints = mCurves.at( j )->numPoints();
1081 if ( ( index - currentVertexId ) < nCurvePoints )
1083 return mCurves.at( j )->xAt( index - currentVertexId );
1085 currentVertexId += ( nCurvePoints - 1 );
1092 int currentVertexId = 0;
1093 for (
int j = 0; j < mCurves.size(); ++j )
1095 int nCurvePoints = mCurves.at( j )->numPoints();
1096 if ( ( index - currentVertexId ) < nCurvePoints )
1098 return mCurves.at( j )->yAt( index - currentVertexId );
1100 currentVertexId += ( nCurvePoints - 1 );
1107 int currentVertexId = 0;
1108 for (
int j = 0; j < mCurves.size(); ++j )
1110 int nCurvePoints = mCurves.at( j )->numPoints();
1111 if ( ( index - currentVertexId ) < nCurvePoints )
1113 return mCurves.at( j )->zAt( index - currentVertexId );
1115 currentVertexId += ( nCurvePoints - 1 );
1122 int currentVertexId = 0;
1123 for (
int j = 0; j < mCurves.size(); ++j )
1125 int nCurvePoints = mCurves.at( j )->numPoints();
1126 if ( ( index - currentVertexId ) < nCurvePoints )
1128 return mCurves.at( j )->mAt( index - currentVertexId );
1130 currentVertexId += ( nCurvePoints - 1 );
1138 for (
QgsCurve *curve : std::as_const( mCurves ) )
1140 if ( !curve->transform( transformer ) )
1158 for (
QgsCurve *curve : std::as_const( mCurves ) )
1160 curve->filterVertices( filter );
1167 for (
QgsCurve *curve : std::as_const( mCurves ) )
1176 if ( mCurves.empty() )
1177 return std::make_tuple( std::make_unique< QgsCompoundCurve >(), std::make_unique< QgsCompoundCurve >() );
1181 std::unique_ptr< QgsCompoundCurve > curve1 = std::make_unique< QgsCompoundCurve >();
1182 std::unique_ptr< QgsCompoundCurve > curve2;
1184 for (
const QgsCurve *curve : mCurves )
1186 const int curveSize = curve->numPoints();
1187 if ( !curve2 && index < curveStart + curveSize )
1190 auto [ p1, p2 ] = curve->splitCurveAtVertex( index - curveStart );
1191 if ( !p1->isEmpty() )
1192 curve1->addCurve( p1.release() );
1194 curve2 = std::make_unique< QgsCompoundCurve >();
1195 if ( !p2->isEmpty() )
1196 curve2->addCurve( p2.release() );
1201 curve2->addCurve( curve->clone() );
1203 curve1->addCurve( curve->clone() );
1208 curveStart += curve->numPoints() - 1;
1211 return std::make_tuple( std::move( curve1 ), curve2 ? std::move( curve2 ) : std::make_unique< QgsCompoundCurve >() );
1223 for (
const QgsCurve *curve : mCurves )
1242 for (
const QgsCurve *curve : mCurves )
1244 if ( curve->hasCurvedSegments() )
1254 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( vertex );
1255 if ( curveIds.size() == 1 )
1257 QgsCurve *curve = mCurves[curveIds.at( 0 ).first];
1258 return curve->
vertexAngle( curveIds.at( 0 ).second );
1260 else if ( curveIds.size() > 1 )
1262 QgsCurve *curve1 = mCurves[curveIds.at( 0 ).first];
1263 QgsCurve *curve2 = mCurves[curveIds.at( 1 ).first];
1264 double angle1 = curve1->
vertexAngle( curveIds.at( 0 ).second );
1265 double angle2 = curve2->
vertexAngle( curveIds.at( 1 ).second );
1276 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( startVertex );
1278 for (
auto it = curveIds.constBegin(); it != curveIds.constEnd(); ++it )
1280 length += mCurves.at( it->first )->segmentLength( it->second );
1288 for (
int i = mCurves.count() - 1; i >= 0; --i )
1290 QgsCurve *reversedCurve = mCurves.at( i )->reversed();
1301 double distanceTraversed = 0;
1302 for (
const QgsCurve *curve : mCurves )
1304 const double thisCurveLength = curve->
length();
1305 if ( distanceTraversed + thisCurveLength > distance ||
qgsDoubleNear( distanceTraversed + thisCurveLength, distance ) )
1308 const double distanceToPoint = std::min( distance - distanceTraversed, thisCurveLength );
1311 return curve->interpolatePoint( distanceToPoint );
1314 distanceTraversed += thisCurveLength;
1322 if ( startDistance < 0 && endDistance < 0 )
1325 endDistance = std::max( startDistance, endDistance );
1326 std::unique_ptr< QgsCompoundCurve > substring = std::make_unique< QgsCompoundCurve >();
1328 double distanceTraversed = 0;
1329 for (
const QgsCurve *curve : mCurves )
1331 const double thisCurveLength = curve->length();
1332 if ( distanceTraversed + thisCurveLength < startDistance )
1338 std::unique_ptr< QgsCurve > part( curve->curveSubstring( startDistance - distanceTraversed, endDistance - distanceTraversed ) );
1340 substring->addCurve( part.release() );
1343 distanceTraversed += thisCurveLength;
1344 if ( distanceTraversed > endDistance )
1348 return substring.release();
1358 for (
QgsCurve *curve : std::as_const( mCurves ) )
1360 curve->addZValue( zValue );
1373 for (
QgsCurve *curve : std::as_const( mCurves ) )
1375 curve->addMValue( mValue );
1387 for (
QgsCurve *curve : std::as_const( mCurves ) )
1389 curve->dropZValue();
1401 for (
QgsCurve *curve : std::as_const( mCurves ) )
1403 curve->dropMValue();
1411 for (
QgsCurve *curve : std::as_const( mCurves ) )
QFlags< GeometryValidityFlag > GeometryValidityFlags
Geometry validity flags.
VertexType
Types of vertex.
WkbType
The WKB type describes the number of dimensions a geometry has.
@ CompoundCurve
CompoundCurve.
@ CircularString
CircularString.
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Abstract base class for all geometries.
virtual bool fromWkb(QgsConstWkbPtr &wkb)=0
Sets the geometry from a WKB string.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
bool isMeasure() const
Returns true if the geometry contains m values.
QFlags< WkbFlag > WkbFlags
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
AxisOrder
Axis order for GML generation.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
QgsAbstractGeometry & operator=(const QgsAbstractGeometry &geom)
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
virtual double length() const
Returns the planar, 2-dimensional length 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 int compareTo(const QgsAbstractGeometry *other) const
Comparator for sorting of geometry.
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
static endian_t endian()
Returns whether this machine uses big or little endian.
A 3-dimensional box composed of x, y, z coordinates.
bool intersects(const QgsBox3D &other) const
Returns true if box intersects with another box.
void combineWith(const QgsBox3D &box)
Expands the bbox so that it covers both the original rectangle and the given rectangle.
bool isNull() const
Test if the box is null (holding no spatial information).
Circular string geometry type.
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
Compound curve geometry type.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula).
QgsLineString * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
bool removeDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) override
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerat...
QgsAbstractGeometry * simplifyByDistance(double tolerance) const override
Simplifies the geometry by applying the Douglas Peucker simplification by distance algorithm.
int compareToSameClass(const QgsAbstractGeometry *other) const final
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
QgsCompoundCurve * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
void condenseCurves()
Condenses the curves in this geometry by combining adjacent linestrings a to a single continuous line...
void close()
Appends first point if not already closed.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
int dimension() const override
Returns the inherent dimension of the geometry.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
std::tuple< std::unique_ptr< QgsCurve >, std::unique_ptr< QgsCurve > > splitCurveAtVertex(int index) const final
Splits the curve at the specified vertex index, returning two curves which represent the portion of t...
bool boundingBoxIntersects(const QgsBox3D &box3d) const override
Returns true if the bounding box of this geometry intersects with a box3d.
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
double mAt(int index) const override
Returns the m-coordinate of the specified node in the line string.
bool isEmpty() const override
Returns true if the geometry is empty.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform) override
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
int nCurves() const
Returns the number of curves in the geometry.
bool toggleCircularAtVertex(QgsVertexId position)
Converts the vertex at the given position from/to circular.
QgsBox3D calculateBoundingBox3D() const override
Calculates the minimal 3D bounding box for the geometry.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
const QgsAbstractGeometry * simplifiedTypeRef() const override
Returns a reference to the simplest lossless representation of this geometry, e.g.
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb()
void swapXy() override
Swaps the x and y coordinates from the geometry.
void removeCurve(int i)
Removes a curve from the geometry.
void addCurve(QgsCurve *c, bool extendPrevious=false)
Adds a curve to the geometry (takes ownership).
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const override
Searches for the closest segment of the geometry to a given point.
QDomElement asGml2(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML2 representation of the geometry.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
bool dropMValue() override
Drops any measure values which exist in the geometry.
QgsCompoundCurve & operator=(const QgsCompoundCurve &curve)
QgsCompoundCurve * clone() const override
Clones the geometry by performing a deep copy.
const QgsCurve * curveAt(int i) const
Returns the curve at the specified index.
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
bool isValid(QString &error, Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const override
Checks validity of the geometry, and returns true if the geometry is valid.
~QgsCompoundCurve() override
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns a WKB representation of the geometry.
void clear() override
Clears the geometry, ie reset it to a null geometry.
int indexOf(const QgsPoint &point) const final
Returns the index of the first vertex matching the given point, or -1 if a matching vertex is not fou...
void transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection d=Qgis::TransformDirection::Forward, bool transformZ=false) override
Transforms the geometry using a coordinate transform.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
QgsCompoundCurve * curveSubstring(double startDistance, double endDistance) const override
Returns a new curve representing a substring of this curve.
void scroll(int firstVertexIndex) final
Scrolls the curve vertices so that they start with the vertex at the given index.
double length() const override
Returns the planar, 2-dimensional length of the geometry.
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path.
QgsPoint * interpolatePoint(double distance) const override
Returns an interpolated point on the curve at the specified distance.
QgsCompoundCurve * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership.
bool pointAt(int node, QgsPoint &point, Qgis::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
QgsPoint startPoint() const override
Returns the starting point of the curve.
QgsCompoundCurve * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0, bool removeRedundantPoints=false) const override
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
QgsPoint endPoint() const override
Returns the end point of the curve.
int numPoints() const override
Returns the number of points in the curve.
double zAt(int index) const override
Returns the z-coordinate of the specified node in the line string.
void addVertex(const QgsPoint &pt)
Adds a vertex to the end of the geometry.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QDomElement asGml3(QDomDocument &doc, int precision=17, const QString &ns="gml", QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY) const override
Returns a GML3 representation of the geometry.
Qgis::WkbType readHeader() const
readHeader
Abstract base class for curved geometry type.
virtual int numPoints() const =0
Returns the number of points in the curve.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
bool mHasCachedSummedUpArea
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.
QgsBox3D mBoundingBox
Cached bounding box.
virtual QgsPoint startPoint() const =0
Returns the starting point of the curve.
virtual QgsPoint endPoint() const =0
Returns the end point of the curve.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const
Tells whether the operation has been canceled already.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the average angle (in radians) between the two linear segments from (x1,...
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
static QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static double closestSegmentFromComponents(T &container, ComponentType ctype, const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf, double epsilon)
Line string geometry type, with support for z-dimension and m-values.
void append(const QgsLineString *line)
Appends the contents of another line string to the end of this line string.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
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.
QgsPoint vertexAt(QgsVertexId) const override
Returns the point corresponding to a specified vertex id.
bool removeDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) override
Removes duplicate nodes from the geometry, wherever removing the nodes does not result in a degenerat...
static Qgis::WkbType dropM(Qgis::WkbType type)
Drops the m dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType dropZ(Qgis::WkbType type)
Drops the z dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsPoint > QgsPointSequence
Utility class for identifying a unique vertex within a geometry.