28 #include <QPainterPath> 39 bool hasZ = p1.
is3D();
84 if ( mX.count() != otherLine->mX.count() )
87 for (
int i = 0; i < mX.count(); ++i )
105 auto result = qgis::make_unique< QgsCircularString >();
107 return result.release();
112 return QStringLiteral(
"CircularString" );
139 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
143 bbox = segmentBoundingBox(
QgsPoint( mX[i], mY[i] ),
QgsPoint( mX[i + 1], mY[i + 1] ),
QgsPoint( mX[i + 2], mY[i + 2] ) );
152 if ( nPoints > 0 && nPoints % 2 == 0 )
165 double centerX, centerY, radius;
176 QgsPointSequence compassPoints = compassPointsOnSegment( p1Angle, p2Angle, p3Angle, centerX, centerY, radius );
177 QgsPointSequence::const_iterator cpIt = compassPoints.constBegin();
178 for ( ; cpIt != compassPoints.constEnd(); ++cpIt )
180 bbox.combineExtentWith( cpIt->x(), cpIt->y() );
185 QgsPointSequence QgsCircularString::compassPointsOnSegment(
double p1Angle,
double p2Angle,
double p3Angle,
double centerX,
double centerY,
double radius )
189 QgsPoint nPoint( centerX, centerY + radius );
190 QgsPoint ePoint( centerX + radius, centerY );
191 QgsPoint sPoint( centerX, centerY - radius );
192 QgsPoint wPoint( centerX - radius, centerY );
194 if ( p3Angle >= p1Angle )
196 if ( p2Angle > p1Angle && p2Angle < p3Angle )
198 if ( p1Angle <= 90 && p3Angle >= 90 )
200 pointList.append( nPoint );
202 if ( p1Angle <= 180 && p3Angle >= 180 )
204 pointList.append( wPoint );
206 if ( p1Angle <= 270 && p3Angle >= 270 )
208 pointList.append( sPoint );
213 pointList.append( ePoint );
214 if ( p1Angle >= 90 || p3Angle <= 90 )
216 pointList.append( nPoint );
218 if ( p1Angle >= 180 || p3Angle <= 180 )
220 pointList.append( wPoint );
222 if ( p1Angle >= 270 || p3Angle <= 270 )
224 pointList.append( sPoint );
230 if ( p2Angle < p1Angle && p2Angle > p3Angle )
232 if ( p1Angle >= 270 && p3Angle <= 270 )
234 pointList.append( sPoint );
236 if ( p1Angle >= 180 && p3Angle <= 180 )
238 pointList.append( wPoint );
240 if ( p1Angle >= 90 && p3Angle <= 90 )
242 pointList.append( nPoint );
247 pointList.append( ePoint );
248 if ( p1Angle <= 270 || p3Angle >= 270 )
250 pointList.append( sPoint );
252 if ( p1Angle <= 180 || p3Angle >= 180 )
254 pointList.append( wPoint );
256 if ( p1Angle <= 90 || p3Angle >= 90 )
258 pointList.append( nPoint );
283 mX.resize( nVertices );
284 mY.resize( nVertices );
285 hasZ ? mZ.resize( nVertices ) : mZ.clear();
286 hasM ? mM.resize( nVertices ) : mM.clear();
287 for (
int i = 0; i < nVertices; ++i )
320 int binarySize =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
324 wkbArray.resize( binarySize );
327 wkb << static_cast<quint32>(
wkbType() );
346 std::unique_ptr< QgsLineString > line(
curveToLine() );
347 QDomElement gml = line->asGml2( doc, precision, ns, axisOrder );
356 QDomElement elemCurve = doc.createElementNS( ns, QStringLiteral(
"Curve" ) );
361 QDomElement elemSegments = doc.createElementNS( ns, QStringLiteral(
"segments" ) );
362 QDomElement elemArcString = doc.createElementNS( ns, QStringLiteral(
"ArcString" ) );
364 elemSegments.appendChild( elemArcString );
365 elemCurve.appendChild( elemSegments );
372 std::unique_ptr< QgsLineString > line(
curveToLine() );
373 QString json = line->asJson( precision );
387 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
418 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
432 bool res =
snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
433 result->mX, result->mY, result->mZ, result->mM );
435 return result.release();
442 if ( mX.count() <= 3 )
445 double prevX = mX.at( 0 );
446 double prevY = mY.at( 0 );
448 bool useZ = hasZ && useZValues;
449 double prevZ = useZ ? mZ.at( 0 ) : 0;
451 int remaining = mX.count();
454 while ( i + 1 < remaining )
456 double currentCurveX = mX.at( i );
457 double currentCurveY = mY.at( i );
458 double currentX = mX.at( i + 1 );
459 double currentY = mY.at( i + 1 );
460 double currentZ = useZ ? mZ.at( i + 1 ) : 0;
493 return std::min( mX.size(), mY.size() );
498 if ( i < 0 || std::min( mX.size(), mY.size() ) <= i )
503 double x = mX.at( i );
504 double y = mY.at( i );
535 if ( index >= 0 && index < mX.size() )
536 return mX.at( index );
543 if ( index >= 0 && index < mY.size() )
544 return mY.at( index );
553 int size = mX.size();
555 double *srcX = mX.data();
556 double *srcY = mY.data();
557 double *srcM = hasM ? mM.data() :
nullptr;
558 double *srcZ = hasZ ? mZ.data() :
nullptr;
560 double *destX = srcX;
561 double *destY = srcY;
562 double *destM = srcM;
563 double *destZ = srcZ;
565 int filteredPoints = 0;
566 for (
int i = 0; i < size; ++i )
570 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
571 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
573 if ( filter(
QgsPoint( x, y, z, m ) ) )
585 mX.resize( filteredPoints );
586 mY.resize( filteredPoints );
588 mZ.resize( filteredPoints );
590 mM.resize( filteredPoints );
599 for (
int i = 0; i < nPts; ++i )
601 pts.push_back(
pointN( i ) );
609 if ( points.empty() )
620 const QgsPoint &firstPt = points.at( 0 );
621 bool hasZ = firstPt.
is3D();
626 mX.resize( points.size() );
627 mY.resize( points.size() );
630 mZ.resize( points.size() );
638 mM.resize( points.size() );
645 for (
int i = 0; i < points.size(); ++i )
647 mX[i] = points[i].x();
648 mY[i] = points[i].y();
651 double z = points.at( i ).z();
652 mZ[i] = std::isnan( z ) ? 0 : z;
656 double m = points.at( i ).m();
657 mM[i] = std::isnan( m ) ? 0 : m;
673 double *zArray = mZ.data();
677 bool useDummyZ = !hasZ || !transformZ;
680 zArray =
new double[nPoints];
681 for (
int i = 0; i < nPoints; ++i )
700 for (
int i = 0; i < nPoints; ++i )
703 t.map( mX.at( i ), mY.at( i ), &x, &y );
708 mZ[i] = mZ.at( i ) * zScale + zTranslate;
712 mM[i] = mM.at( i ) * mScale + mTranslate;
725 if ( path.isEmpty() || path.currentPosition() != QPointF( mX[0], mY[0] ) )
727 path.moveTo( QPointF( mX[0], mY[0] ) );
730 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
734 for (
int j = 1; j < pt.size(); ++j )
736 path.lineTo( pt.at( j ).x(), pt.at( j ).y() );
744 if ( nPoints % 2 == 0 )
746 path.lineTo( mX[ nPoints - 1 ], mY[ nPoints - 1 ] );
751 void QgsCircularString::arcTo( QPainterPath &path, QPointF pt1, QPointF pt2, QPointF pt3 )
753 double centerX, centerY, radius;
755 radius, centerX, centerY );
760 double diameter = 2 * radius;
761 path.arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle );
772 if ( position.
vertex >= mX.size() || position.
vertex < 1 )
777 mX.insert( position.
vertex, vertex.
x() );
778 mY.insert( position.
vertex, vertex.
y() );
781 mZ.insert( position.
vertex, vertex.
z() );
785 mM.insert( position.
vertex, vertex.
m() );
788 bool vertexNrEven = ( position.
vertex % 2 == 0 );
803 if ( position.
vertex < 0 || position.
vertex >= mX.size() )
808 mX[position.
vertex] = newPos.
x();
809 mY[position.
vertex] = newPos.
y();
812 mZ[position.
vertex] = newPos.
z();
816 mM[position.
vertex] = newPos.
m();
830 if ( position.
vertex < 0 || position.
vertex > ( nVertices - 1 ) )
835 if ( position.
vertex < ( nVertices - 2 ) )
868 double minDist = std::numeric_limits<double>::max();
871 int minDistLeftOf = 0;
873 double currentDist = 0.0;
876 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
878 currentDist = closestPointOnArc( mX[i], mY[i], mX[i + 1], mY[i + 1], mX[i + 2], mY[i + 2], pt, segmentPt, vertexAfter, leftOf, epsilon );
879 if ( currentDist < minDist )
881 minDist = currentDist;
882 minDistSegmentPoint = segmentPt;
891 if ( minDist == std::numeric_limits<double>::max() )
894 segmentPt = minDistSegmentPoint;
895 vertexAfter = minDistVertexAfter;
896 vertexAfter.
part = 0;
897 vertexAfter.
ring = 0;
920 for (
int i = 0; i < maxIndex; i += 2 )
923 QgsPoint p2( mX[i + 1], mY[i + 1] );
924 QgsPoint p3( mX[i + 2], mY[i + 2] );
934 sum += 0.5 * ( mX[i] * mY[i + 2] - mY[i] * mX[i + 2] );
937 double midPointX = ( p1.
x() + p3.
x() ) / 2.0;
938 double midPointY = ( p1.
y() + p3.
y() ) / 2.0;
940 double radius, centerX, centerY;
944 double r2 = radius * radius;
955 double cov = 0.5 - d * std::sqrt( r2 - d * d ) / ( M_PI * r2 ) - M_1_PI * std::asin( d / radius );
956 double circleChordArea = 0;
957 if ( circlePointLeftOfLine == centerPointLeftOfLine )
959 circleChordArea = M_PI * r2 * ( 1 - cov );
963 circleChordArea = M_PI * r2 * cov;
966 if ( !circlePointLeftOfLine )
968 sum += circleChordArea;
972 sum -= circleChordArea;
982 double QgsCircularString::closestPointOnArc(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3,
985 double radius, centerX, centerY;
1010 segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3;
1011 vertexAfter.
vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2;
1018 segmentPt.
setX( pt.
x() );
1019 segmentPt.
setY( pt.
y() );
1025 double sqrDistancePointToCenter = ( pt.
x() - centerX ) * ( pt.
x() - centerX ) + ( pt.
y() - centerY ) * ( pt.
y() - centerY );
1026 *leftOf = clockwise ? ( sqrDistancePointToCenter > radius * radius ? -1 : 1 )
1027 : ( sqrDistancePointToCenter < radius * radius ? -1 : 1 );
1033 void QgsCircularString::insertVertexBetween(
int after,
int before,
int pointOnCircle )
1035 double xAfter = mX.at( after );
1036 double yAfter = mY.at( after );
1037 double xBefore = mX.at( before );
1038 double yBefore = mY.at( before );
1039 double xOnCircle = mX.at( pointOnCircle );
1040 double yOnCircle = mY.at( pointOnCircle );
1042 double radius, centerX, centerY;
1045 double x = ( xAfter + xBefore ) / 2.0;
1046 double y = ( yAfter + yBefore ) / 2.0;
1049 mX.insert( before, newVertex.
x() );
1050 mY.insert( before, newVertex.
y() );
1054 mZ.insert( before, ( mZ[after] + mZ[before] ) / 2.0 );
1058 mM.insert( before, ( mM[after] + mM[before] ) / 2.0 );
1071 int before = vId.
vertex - 1;
1073 int after = vId.
vertex + 1;
1075 if ( vId.
vertex % 2 != 0 )
1105 int vertex1 = vId.
vertex - 2;
1106 int vertex2 = vId.
vertex - 1;
1107 int vertex3 = vId.
vertex;
1109 QgsPoint( mX[vertex1], mY[vertex1] ),
QgsPoint( mX[vertex2], mY[vertex2] ),
QgsPoint( mX[vertex3], mY[vertex3] ) );
1110 int vertex4 = vId.
vertex + 1;
1111 int vertex5 = vId.
vertex + 2;
1113 QgsPoint( mX[vertex3], mY[vertex3] ),
QgsPoint( mX[vertex4], mY[vertex4] ),
QgsPoint( mX[vertex5], mY[vertex5] ) );
1122 if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 2 )
1125 if ( startVertex.
vertex % 2 == 1 )
1128 double x1 = mX.at( startVertex.
vertex );
1129 double y1 = mY.at( startVertex.
vertex );
1130 double x2 = mX.at( startVertex.
vertex + 1 );
1131 double y2 = mY.at( startVertex.
vertex + 1 );
1132 double x3 = mX.at( startVertex.
vertex + 2 );
1133 double y3 = mY.at( startVertex.
vertex + 2 );
1140 std::reverse( copy->mX.begin(), copy->mX.end() );
1141 std::reverse( copy->mY.begin(), copy->mY.end() );
1144 std::reverse( copy->mZ.begin(), copy->mZ.end() );
1148 std::reverse( copy->mM.begin(), copy->mM.end() );
1163 mZ.reserve( nPoints );
1164 for (
int i = 0; i < nPoints; ++i )
1181 mM.reserve( nPoints );
1182 for (
int i = 0; i < nPoints; ++i )
1215 std::swap( mX, mY );
bool isMeasure() const
Returns true if the geometry contains m values.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
A rectangle specified with double values.
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...
void setPoints(const QgsPointSequence &points)
Resets the line string to match the specified list of points.
int numPoints() const override
Returns the number of points in the curve.
static bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise)
Returns true if, in a circle, angle is between angle1 and angle2.
static double ccwAngle(double dy, double dx)
Returns the counter clockwise angle between a line with components dx, dy and the line with dx > 0 an...
QgsCircularString()
Constructs an empty circular string.
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 (...
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
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, y1) to (x2, y2) and (x2, y2) to (x3, y3).
bool pointAt(int node, QgsPoint &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
QString asJson(int precision=17) const override
Returns a GeoJSON representation of the geometry.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
static QgsPoint segmentMidPointFromCenter(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint ¢er, bool useShortestArc=true)
Calculates the midpoint on the circle passing through p1 and p2, with the specified center coordinate...
QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry.
bool hasCurvedSegments() const override
Returns true if the geometry contains curved segments.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
static double circleLength(double x1, double y1, double x2, double y2, double x3, double y3)
Length of a circular string segment defined by pt1, pt2, pt3.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
double segmentLength(QgsVertexId startVertex) const override
Returns the length of the segment of the geometry which begins at startVertex.
static endian_t endian()
Returns whether this machine uses big or little endian.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
QgsPoint pointN(int i) const
Returns the point at index i within the circular string.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
static Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type.
QgsWkbTypes::Type mWkbType
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
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.
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
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
QString wktTypeStr() const
Returns the WKT type string of the geometry.
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if circle is ordered clockwise.
bool insertVertex(QgsVertexId position, const QgsPoint &vertex) override
Inserts a vertex into the geometry.
bool equals(const QgsCurve &other) const override
Checks whether this curve exactly equals another curve.
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
QgsCircularString * createEmptyWithSameType() const override
Creates a new geometry with the same class and same WKB type as the original and transfers ownership...
Type
The WKB type describes the number of dimensions a geometry has.
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type.
double vertexAngle(QgsVertexId vertex) const override
Returns approximate angle at a vertex.
Utility class for identifying a unique vertex within a geometry.
QString geometryType() const override
Returns a unique string representing the geometry type.
double length() const override
Returns the length of the geometry.
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.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, QgsWkbTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
static QDomElement pointsToGML3(const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, bool is3D, const QgsAbstractGeometry::AxisOrder &axisOrder=QgsAbstractGeometry::AxisOrder::XY)
Returns a gml::posList DOM element.
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type.
static double circleTangentDirection(const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3)
Calculates the direction angle of a circle tangent (clockwise from north in radians) ...
QgsCircularString * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
static bool angleOnCircle(double angle, double angle1, double angle2, double angle3)
Returns true if an angle is between angle1 and angle3 on a circle described by angle1, angle2 and angle3.
Abstract base class for curved geometry type.
int dimension() const override
Returns the inherent dimension of the geometry.
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula).
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry.
Point geometry type, with support for z-dimension and m-values.
QgsPoint endPoint() const override
Returns the end point of the curve.
AxisOrder
Axis order for GML generation.
static QgsCircularString fromTwoPointsAndCenter(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint ¢er, bool useShortestArc=true)
Creates a circular string with a single arc representing the curve from p1 to p2 with the specified c...
void setX(double x)
Sets the point's x-coordinate.
bool snapToGridPrivate(double hSpacing, double vSpacing, double dSpacing, double mSpacing, const QVector< double > &srcX, const QVector< double > &srcY, const QVector< double > &srcZ, const QVector< double > &srcM, QVector< double > &outX, QVector< double > &outY, QVector< double > &outZ, QVector< double > &outM) const
Helper function for QgsCurve subclasses to snap to grids.
void setY(double y)
Sets the point's y-coordinate.
QVector< QgsPoint > QgsPointSequence
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle...
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
static double sqrDistance2D(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the squared 2D distance between two points.
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
static double sweepAngle(double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3)
Calculates angle of a circular string part defined by pt1, pt2, pt3.
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
QgsCircularString * clone() const override
Clones the geometry by performing a deep copy.
Line string geometry type, with support for z-dimension and m-values.
QgsCircularString * 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...
static int leftOfLine(double x, double y, double x1, double y1, double x2, double y2)
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> ( x2, y2).
void setPoints(const QgsPointSequence &points)
Sets the circular string's points.
QByteArray asWkb() const override
Returns a WKB representation of the geometry.
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double ¢erX, double ¢erY)
Returns radius and center of the circle through pt1, pt2, pt3.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
Circular string geometry type.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform.
void swapXy() override
Swaps the x and y coordinates from the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path.
static Type flatType(Type type)
Returns the flat type for a WKB type.
QgsWkbTypes::Type readHeader() const
readHeader
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.
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...
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
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'. Negativ values mean left a...
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
bool isEmpty() const override
Returns true if the geometry is empty.
QgsPoint startPoint() const override
Returns the starting point of the curve.
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.
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 dropMValue() override
Drops any measure values which exist in the geometry.
static void segmentizeArc(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &p3, QgsPointSequence &points, double tolerance=M_PI_2/90, QgsAbstractGeometry::SegmentationToleranceType toleranceType=QgsAbstractGeometry::MaximumAngle, bool hasZ=false, bool hasM=false)
Convert circular arc defined by p1, p2, p3 (p1/p3 being start resp.