26 #include <QJsonObject>
28 #include <QPainterPath>
30 #include <nlohmann/json.hpp>
44 const QgsCompoundCurve *otherCurve = qgsgeometry_cast< const QgsCompoundCurve * >( &other );
51 if ( mCurves.size() != otherCurve->mCurves.size() )
54 for (
int i = 0; i < mCurves.size(); ++i )
56 if ( *mCurves.at( i ) != *otherCurve->mCurves.at( i ) )
65 auto result = std::make_unique< QgsCompoundCurve >();
67 return result.release();
72 const QgsCompoundCurve *otherCurve = qgsgeometry_cast<const QgsCompoundCurve *>( other );
78 while ( i < mCurves.size() && j < otherCurve->mCurves.size() )
82 const int comparison = aGeom->
compareTo( bGeom );
83 if ( comparison != 0 )
90 if ( i < mCurves.size() )
94 if ( j < otherCurve->mCurves.size() )
103 return QStringLiteral(
"CompoundCurve" );
114 mCurves.reserve( curve.mCurves.size() );
115 for (
const QgsCurve *
c : curve.mCurves )
117 mCurves.append(
c->clone() );
123 if ( &curve !=
this )
127 for (
const QgsCurve *
c : curve.mCurves )
129 mCurves.append(
c->clone() );
143 qDeleteAll( mCurves );
150 if ( mCurves.empty() )
156 for (
int i = 1; i < mCurves.size(); ++i )
167 if ( index < 1 || index >= size - 1 )
173 if (
QgsCompoundCurve *curve2 = qgsgeometry_cast< QgsCompoundCurve *>( p2.get() ) )
176 mCurves = std::move( curve2->mCurves );
178 if (
QgsCompoundCurve *curve1 = qgsgeometry_cast< QgsCompoundCurve *>( p1.get() ) )
181 mCurves.append( curve1->mCurves );
182 curve1->mCurves.clear();
204 for (
int i = 0; i <
nCurves; ++i )
207 wkbPtr -= 1 +
sizeof( int );
220 currentCurve->
fromWkb( wkbPtr );
221 mCurves.append( currentCurve );
236 QString secondWithoutParentheses =
parts.second;
237 secondWithoutParentheses = secondWithoutParentheses.remove(
'(' ).remove(
')' ).simplified().remove(
' ' );
238 if ( (
parts.second.compare( QLatin1String(
"EMPTY" ), Qt::CaseInsensitive ) == 0 ) ||
239 secondWithoutParentheses.isEmpty() )
242 QString defaultChildWkbType = QStringLiteral(
"LineString%1%2" ).arg(
is3D() ? QStringLiteral(
"Z" ) : QString(),
isMeasure() ? QStringLiteral(
"M" ) : QString() );
245 for (
const QString &childWkt : blocks )
258 if ( !mCurves.back()->fromWkt( childWkt ) )
269 for (
const QgsCurve *curve : std::as_const( mCurves ) )
271 hasZ = hasZ || curve->is3D();
272 hasM = hasM || curve->isMeasure();
286 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
287 for (
const QgsCurve *curve : mCurves )
289 binarySize += curve->wkbSize( flags );
300 wkb << static_cast<quint32>(
wkbType() );
301 wkb << static_cast<quint32>( mCurves.size() );
302 for (
const QgsCurve *curve : mCurves )
304 wkb << curve->asWkb( flags );
313 wkt += QLatin1String(
" EMPTY" );
316 wkt += QLatin1String(
" (" );
317 for (
const QgsCurve *curve : mCurves )
319 QString childWkt = curve->asWkt(
precision );
320 if ( qgsgeometry_cast<const QgsLineString *>( curve ) )
323 childWkt = childWkt.mid( childWkt.indexOf(
'(' ) );
325 wkt += childWkt +
',';
327 if ( wkt.endsWith(
',' ) )
339 std::unique_ptr< QgsLineString > line(
curveToLine() );
340 QDomElement gml = line->asGml2( doc,
precision, ns, axisOrder );
346 QDomElement compoundCurveElem = doc.createElementNS( ns, QStringLiteral(
"CompositeCurve" ) );
349 return compoundCurveElem;
351 for (
const QgsCurve *curve : mCurves )
353 QDomElement curveMemberElem = doc.createElementNS( ns, QStringLiteral(
"curveMember" ) );
354 QDomElement curveElem = curve->asGml3( doc,
precision, ns, axisOrder );
355 curveMemberElem.appendChild( curveElem );
356 compoundCurveElem.appendChild( curveMemberElem );
359 return compoundCurveElem;
365 std::unique_ptr< QgsLineString > line(
curveToLine() );
372 for (
const QgsCurve *curve : mCurves )
374 length += curve->length();
381 if ( mCurves.empty() )
385 return mCurves.at( 0 )->startPoint();
390 if ( mCurves.empty() )
394 return mCurves.at( mCurves.size() - 1 )->endPoint();
400 if ( mCurves.empty() )
405 mCurves[0]->points( pts );
406 for (
int i = 1; i < mCurves.size(); ++i )
409 mCurves[i]->points( pList );
424 for (
int i = 0; i <
nCurves; ++i )
426 nPoints += mCurves.at( i )->numPoints() - 1;
434 if ( mCurves.isEmpty() )
439 if ( !curve->isEmpty() )
447 if ( mCurves.isEmpty() )
450 for (
int i = 0; i < mCurves.size() ; ++i )
452 if ( !mCurves[i]->
isValid( error, flags ) )
454 error = QObject::tr(
"Curve[%1]: %2" ).arg( i + 1 ).arg( error );
464 for (
const QgsCurve *curve : mCurves )
466 const int curveIndex = curve->indexOf( point );
467 if ( curveIndex >= 0 )
468 return curveStart + curveIndex;
471 curveStart += curve->numPoints() - 1;
479 std::unique_ptr< QgsLineString > currentLine;
480 for (
const QgsCurve *curve : mCurves )
482 currentLine.reset( curve->curveToLine( tolerance, toleranceType ) );
483 line->
append( currentLine.get() );
494 std::unique_ptr<QgsCurve> gridified(
static_cast< QgsCurve *
>( curve->snappedToGrid( hSpacing, vSpacing, dSpacing, mSpacing ) ) );
497 result->mCurves.append( gridified.release() );
501 if ( result->mCurves.empty() )
504 return result.release();
510 const QVector< QgsCurve * > curves = mCurves;
516 if ( curve->numPoints() == 0 ||
qgsDoubleNear( curve->length(), 0.0, epsilon ) )
519 delete mCurves.takeAt( i );
527 curve->moveVertex(
QgsVertexId( -1, -1, 0 ), lastEnd );
538 if ( mCurves.empty() )
552 for (
const QgsCurve *curve : mCurves )
554 if ( curve->boundingBoxIntersects( rectangle ) )
567 if ( mCurves.size() == 1 )
568 return mCurves.at( 0 );
575 if ( i < 0 || i >= mCurves.size() )
579 return mCurves.at( i );
587 if ( mCurves.empty() )
609 QgsLineString *previousLineString = !mCurves.empty() ? qgsgeometry_cast< QgsLineString * >( mCurves.constLast() ) :
nullptr;
610 const QgsLineString *newLineString = qgsgeometry_cast< const QgsLineString * >(
c );
611 const bool canExtendPrevious = extendPrevious && previousLineString && newLineString;
612 if ( canExtendPrevious )
614 previousLineString->
append( newLineString );
629 if ( i < 0 || i >= mCurves.size() )
634 delete mCurves.takeAt( i );
647 if ( !mCurves.isEmpty() )
649 lastCurve = mCurves.at( mCurves.size() - 1 );
656 mCurves.append( line );
674 QVector< QgsCurve * > newCurves;
675 newCurves.reserve( mCurves.size() );
676 for (
QgsCurve *curve : std::as_const( mCurves ) )
678 if ( lastCurve && lastCurve->
wkbType() == curve->wkbType() )
680 if (
QgsLineString *ls = qgsgeometry_cast< QgsLineString * >( lastCurve ) )
682 ls->append( qgsgeometry_cast< QgsLineString * >( curve ) );
685 else if (
QgsCircularString *cs = qgsgeometry_cast< QgsCircularString * >( lastCurve ) )
687 cs->append( qgsgeometry_cast< QgsCircularString * >( curve ) );
702 for (
const QgsCurve *curve : mCurves )
710 for (
QgsCurve *curve : std::as_const( mCurves ) )
712 curve->transform( ct, d, transformZ );
719 for (
QgsCurve *curve : std::as_const( mCurves ) )
721 curve->transform( t, zTranslate, zScale, mTranslate, mScale );
729 for (
const QgsCurve *curve : mCurves )
731 curve->addToPainterPath( pp );
739 for (
const QgsCurve *curve : mCurves )
741 curve->addToPainterPath( pp );
748 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
749 if ( curveIds.empty() )
753 int curveId = curveIds.at( 0 ).first;
754 if ( curveId >= mCurves.size() )
759 bool success = mCurves.at( curveId )->insertVertex( curveIds.at( 0 ).second, vertex );
769 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
770 QVector< QPair<int, QgsVertexId> >::const_iterator idIt = curveIds.constBegin();
771 for ( ; idIt != curveIds.constEnd(); ++idIt )
773 mCurves.at( idIt->first )->moveVertex( idIt->second, newPos );
776 bool success = !curveIds.isEmpty();
786 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( position );
787 if ( curveIds.size() == 1 )
789 if ( !mCurves.at( curveIds.at( 0 ).first )->deleteVertex( curveIds.at( 0 ).second ) )
794 if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 )
799 else if ( curveIds.size() == 2 )
801 Q_ASSERT( curveIds.at( 1 ).first == curveIds.at( 0 ).first + 1 );
802 Q_ASSERT( curveIds.at( 0 ).second.vertex == mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 );
803 Q_ASSERT( curveIds.at( 1 ).second.vertex == 0 );
808 mCurves.at( curveIds.at( 1 ).first )->numPoints() > 3 )
812 mCurves.at( curveIds.at( 1 ).first ) ->pointAt( 2, intermediatePoint, type );
813 mCurves.at( curveIds.at( 0 ).first )->moveVertex(
814 QgsVertexId( 0, 0, mCurves.at( curveIds.at( 0 ).first )->numPoints() - 1 ), intermediatePoint );
816 else if ( !mCurves.at( curveIds.at( 0 ).first )->deleteVertex( curveIds.at( 0 ).second ) )
822 mCurves.at( curveIds.at( 0 ).first )->numPoints() > 0 &&
825 QgsPoint intermediatePoint = mCurves.at( curveIds.at( 0 ).first ) ->endPoint();
826 mCurves.at( curveIds.at( 1 ).first )->moveVertex(
QgsVertexId( 0, 0, 0 ), intermediatePoint );
828 else if ( !mCurves.at( curveIds.at( 1 ).first )->deleteVertex( curveIds.at( 1 ).second ) )
833 if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 &&
834 mCurves.at( curveIds.at( 1 ).first )->numPoints() != 0 )
839 else if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() != 0 &&
840 mCurves.at( curveIds.at( 1 ).first )->numPoints() == 0 )
842 mCurves.at( curveIds.at( 0 ).first )->moveVertex(
846 else if ( mCurves.at( curveIds.at( 0 ).first )->numPoints() == 0 &&
847 mCurves.at( curveIds.at( 1 ).first )->numPoints() == 0 )
854 mCurves.insert( curveIds.at( 0 ).first, line );
858 QgsPoint endPointOfFirst = mCurves.at( curveIds.at( 0 ).first ) ->endPoint();
859 QgsPoint startPointOfSecond = mCurves.at( curveIds.at( 1 ).first ) ->startPoint();
860 if ( endPointOfFirst != startPointOfSecond )
865 mCurves.insert( curveIds.at( 1 ).first, line );
870 bool success = !curveIds.isEmpty();
878 QVector< QPair<int, QgsVertexId> > QgsCompoundCurve::curveVertexId(
QgsVertexId id )
const
880 QVector< QPair<int, QgsVertexId> > curveIds;
882 int currentVertexIndex = 0;
883 for (
int i = 0; i < mCurves.size(); ++i )
885 int increment = mCurves.at( i )->numPoints() - 1;
886 if (
id.vertex >= currentVertexIndex &&
id.vertex <= currentVertexIndex + increment )
888 int curveVertexId =
id.vertex - currentVertexIndex;
892 vid.
vertex = curveVertexId;
893 curveIds.append( qMakePair( i, vid ) );
894 if ( curveVertexId == increment && i < ( mCurves.size() - 1 ) )
897 curveIds.append( qMakePair( i + 1, vid ) );
901 else if (
id.vertex >= currentVertexIndex &&
id.vertex == currentVertexIndex + increment + 1 && i == ( mCurves.size() - 1 ) )
903 int curveVertexId =
id.vertex - currentVertexIndex;
907 vid.
vertex = curveVertexId;
908 curveIds.append( qMakePair( i, vid ) );
911 currentVertexIndex += increment;
924 int currentVertexId = 0;
925 for (
int j = 0; j < mCurves.size(); ++j )
927 int nCurvePoints = mCurves.at( j )->numPoints();
928 if ( ( node - currentVertexId ) < nCurvePoints )
930 return ( mCurves.at( j )->pointAt( node - currentVertexId, point, type ) );
932 currentVertexId += ( nCurvePoints - 1 );
939 int currentVertexId = 0;
940 for (
int j = 0; j < mCurves.size(); ++j )
942 int nCurvePoints = mCurves.at( j )->numPoints();
943 if ( ( index - currentVertexId ) < nCurvePoints )
945 return mCurves.at( j )->xAt( index - currentVertexId );
947 currentVertexId += ( nCurvePoints - 1 );
954 int currentVertexId = 0;
955 for (
int j = 0; j < mCurves.size(); ++j )
957 int nCurvePoints = mCurves.at( j )->numPoints();
958 if ( ( index - currentVertexId ) < nCurvePoints )
960 return mCurves.at( j )->yAt( index - currentVertexId );
962 currentVertexId += ( nCurvePoints - 1 );
970 for (
QgsCurve *curve : std::as_const( mCurves ) )
972 if ( !curve->transform( transformer ) )
990 for (
QgsCurve *curve : std::as_const( mCurves ) )
992 curve->filterVertices( filter );
999 for (
QgsCurve *curve : std::as_const( mCurves ) )
1008 if ( mCurves.empty() )
1009 return std::make_tuple( std::make_unique< QgsCompoundCurve >(), std::make_unique< QgsCompoundCurve >() );
1013 std::unique_ptr< QgsCompoundCurve > curve1 = std::make_unique< QgsCompoundCurve >();
1014 std::unique_ptr< QgsCompoundCurve > curve2;
1016 for (
const QgsCurve *curve : mCurves )
1018 const int curveSize = curve->numPoints();
1019 if ( !curve2 && index < curveStart + curveSize )
1022 auto [ p1, p2 ] = curve->splitCurveAtVertex( index - curveStart );
1023 if ( !p1->isEmpty() )
1024 curve1->addCurve( p1.release() );
1026 curve2 = std::make_unique< QgsCompoundCurve >();
1027 if ( !p2->isEmpty() )
1028 curve2->addCurve( p2.release() );
1033 curve2->addCurve( curve->clone() );
1035 curve1->addCurve( curve->clone() );
1040 curveStart += curve->numPoints() - 1;
1043 return std::make_tuple( std::move( curve1 ), curve2 ? std::move( curve2 ) : std::make_unique< QgsCompoundCurve >() );
1048 for (
const QgsCurve *curve : mCurves )
1050 curve->sumUpArea( sum );
1065 for (
const QgsCurve *curve : mCurves )
1067 if ( curve->hasCurvedSegments() )
1077 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( vertex );
1078 if ( curveIds.size() == 1 )
1080 QgsCurve *curve = mCurves[curveIds.at( 0 ).first];
1081 return curve->
vertexAngle( curveIds.at( 0 ).second );
1083 else if ( curveIds.size() > 1 )
1085 QgsCurve *curve1 = mCurves[curveIds.at( 0 ).first];
1086 QgsCurve *curve2 = mCurves[curveIds.at( 1 ).first];
1087 double angle1 = curve1->
vertexAngle( curveIds.at( 0 ).second );
1088 double angle2 = curve2->
vertexAngle( curveIds.at( 1 ).second );
1099 QVector< QPair<int, QgsVertexId> > curveIds = curveVertexId( startVertex );
1101 for (
auto it = curveIds.constBegin(); it != curveIds.constEnd(); ++it )
1103 length += mCurves.at( it->first )->segmentLength( it->second );
1111 for (
int i = mCurves.count() - 1; i >= 0; --i )
1113 QgsCurve *reversedCurve = mCurves.at( i )->reversed();
1124 double distanceTraversed = 0;
1125 for (
const QgsCurve *curve : mCurves )
1127 const double thisCurveLength = curve->
length();
1128 if ( distanceTraversed + thisCurveLength > distance ||
qgsDoubleNear( distanceTraversed + thisCurveLength, distance ) )
1131 const double distanceToPoint = std::min( distance - distanceTraversed, thisCurveLength );
1134 return curve->interpolatePoint( distanceToPoint );
1137 distanceTraversed += thisCurveLength;
1145 if ( startDistance < 0 && endDistance < 0 )
1148 endDistance = std::max( startDistance, endDistance );
1149 std::unique_ptr< QgsCompoundCurve > substring = std::make_unique< QgsCompoundCurve >();
1151 double distanceTraversed = 0;
1152 for (
const QgsCurve *curve : mCurves )
1154 const double thisCurveLength = curve->length();
1155 if ( distanceTraversed + thisCurveLength < startDistance )
1161 std::unique_ptr< QgsCurve > part( curve->curveSubstring( startDistance - distanceTraversed, endDistance - distanceTraversed ) );
1163 substring->addCurve( part.release() );
1166 distanceTraversed += thisCurveLength;
1167 if ( distanceTraversed > endDistance )
1171 return substring.release();
1181 for (
QgsCurve *curve : std::as_const( mCurves ) )
1183 curve->addZValue( zValue );
1196 for (
QgsCurve *curve : std::as_const( mCurves ) )
1198 curve->addMValue( mValue );
1210 for (
QgsCurve *curve : std::as_const( mCurves ) )
1212 curve->dropZValue();
1224 for (
QgsCurve *curve : std::as_const( mCurves ) )
1226 curve->dropMValue();
1234 for (
QgsCurve *curve : std::as_const( mCurves ) )
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 is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual bool boundingBoxIntersects(const QgsRectangle &rectangle) const SIP_HOLDGIL
Returns true if the bounding box of this geometry intersects with a rectangle.
AxisOrder
Axis order for GML generation.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
QgsAbstractGeometry & operator=(const QgsAbstractGeometry &geom)
virtual double length() const
Returns the planar, 2-dimensional length of the geometry.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
virtual int compareTo(const QgsAbstractGeometry *other) const
Comparator for sorting of geometry.
QgsWkbTypes::Type mWkbType
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
static endian_t endian()
Returns whether this machine uses big or little endian.
Circular string geometry type.
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...
const QgsAbstractGeometry * simplifiedTypeRef() const override SIP_HOLDGIL
Returns a reference to the simplest lossless representation of this geometry, e.g.
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.
bool isValid(QString &error, int flags=0) const override
Checks validity of the geometry, and returns true if the geometry is valid.
QgsPoint endPoint() const override SIP_HOLDGIL
Returns the end point of the curve.
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...
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry.
const QgsCurve * curveAt(int i) const SIP_HOLDGIL
Returns the curve at the specified index.
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.
bool pointAt(int node, QgsPoint &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
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 dimension() const override SIP_HOLDGIL
Returns the inherent dimension of the geometry.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb()
QString geometryType() const override SIP_HOLDGIL
Returns a unique string representing the geometry type.
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 boundingBoxIntersects(const QgsRectangle &rectangle) const override SIP_HOLDGIL
Returns true if the bounding box of this geometry intersects with a rectangle.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
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.
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
double length() const override SIP_HOLDGIL
Returns the planar, 2-dimensional length of the geometry.
~QgsCompoundCurve() override
double xAt(int index) const override SIP_HOLDGIL
Returns the x-coordinate of the specified node in the line string.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
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...
bool equals(const QgsCurve &other) const override
Checks whether this curve exactly equals another curve.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
double yAt(int index) const override SIP_HOLDGIL
Returns the y-coordinate of the specified node in the line string.
QgsCompoundCurve * curveSubstring(double startDistance, double endDistance) const override
Returns a new curve representing a substring of this curve.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
QgsPoint startPoint() const override SIP_HOLDGIL
Returns the starting point of the curve.
void scroll(int firstVertexIndex) final
Scrolls the curve vertices so that they start with the vertex at the given index.
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 isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
QgsCompoundCurve * snappedToGrid(double hSpacing, double vSpacing, double dSpacing=0, double mSpacing=0) const override
Makes a new geometry with all the points or vertices snapped to the closest point of the grid.
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.
int nCurves() const SIP_HOLDGIL
Returns the number of curves in the geometry.
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.
QgsWkbTypes::Type readHeader() const
readHeader
Abstract base class for curved geometry type.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
bool isValid(QString &error, int flags=0) const override
Checks validity of the geometry, and returns true if the geometry is valid.
QgsRectangle mBoundingBox
Cached bounding box.
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 SIP_HOLDGIL
Tells whether the operation has been canceled already.
static QPair< QgsWkbTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
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 double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates the average angle (in radians) between the two linear segments from (x1,...
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...
A rectangle specified with double values.
bool intersects(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle intersects with other rectangle.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Type
The WKB type describes the number of dimensions a geometry has.
static Type dropZ(Type type) SIP_HOLDGIL
Drops the z dimension (if present) for a WKB type and returns the new type.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
static Type dropM(Type type) SIP_HOLDGIL
Drops the m dimension (if present) for a WKB type and returns the new type.
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 ...
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.
VertexType
Type of vertex.