28 #include <QJsonObject>    30 #include <QPainterPath>    32 #include <nlohmann/json.hpp>    42   bool hasZ = p1.
is3D();
    87   if ( mX.count() != otherLine->mX.count() )
    90   for ( 
int i = 0; i < mX.count(); ++i )
   108   auto result = qgis::make_unique< QgsCircularString >();
   110   return result.release();
   115   return QStringLiteral( 
"CircularString" );
   142   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   146       bbox = segmentBoundingBox( 
QgsPoint( mX[i], mY[i] ), 
QgsPoint( mX[i + 1], mY[i + 1] ), 
QgsPoint( mX[i + 2], mY[i + 2] ) );
   155   if ( nPoints > 0 && nPoints % 2 == 0 )
   168   double centerX, centerY, radius;
   179   QgsPointSequence compassPoints = compassPointsOnSegment( p1Angle, p2Angle, p3Angle, centerX, centerY, radius );
   180   QgsPointSequence::const_iterator cpIt = compassPoints.constBegin();
   181   for ( ; cpIt != compassPoints.constEnd(); ++cpIt )
   183     bbox.combineExtentWith( cpIt->x(), cpIt->y() );
   188 QgsPointSequence QgsCircularString::compassPointsOnSegment( 
double p1Angle, 
double p2Angle, 
double p3Angle, 
double centerX, 
double centerY, 
double radius )
   192   QgsPoint nPoint( centerX, centerY + radius );
   193   QgsPoint ePoint( centerX + radius, centerY );
   194   QgsPoint sPoint( centerX, centerY - radius );
   195   QgsPoint wPoint( centerX - radius, centerY );
   197   if ( p3Angle >= p1Angle )
   199     if ( p2Angle > p1Angle && p2Angle < p3Angle )
   201       if ( p1Angle <= 90 && p3Angle >= 90 )
   203         pointList.append( nPoint );
   205       if ( p1Angle <= 180 && p3Angle >= 180 )
   207         pointList.append( wPoint );
   209       if ( p1Angle <= 270 && p3Angle >= 270 )
   211         pointList.append( sPoint );
   216       pointList.append( ePoint );
   217       if ( p1Angle >= 90 || p3Angle <= 90 )
   219         pointList.append( nPoint );
   221       if ( p1Angle >= 180 || p3Angle <= 180 )
   223         pointList.append( wPoint );
   225       if ( p1Angle >= 270 || p3Angle <= 270 )
   227         pointList.append( sPoint );
   233     if ( p2Angle < p1Angle && p2Angle > p3Angle )
   235       if ( p1Angle >= 270 && p3Angle <= 270 )
   237         pointList.append( sPoint );
   239       if ( p1Angle >= 180 && p3Angle <= 180 )
   241         pointList.append( wPoint );
   243       if ( p1Angle >= 90 && p3Angle <= 90 )
   245         pointList.append( nPoint );
   250       pointList.append( ePoint );
   251       if ( p1Angle <= 270 || p3Angle >= 270 )
   253         pointList.append( sPoint );
   255       if ( p1Angle <= 180 || p3Angle >= 180 )
   257         pointList.append( wPoint );
   259       if ( p1Angle <= 90 || p3Angle >= 90 )
   261         pointList.append( nPoint );
   286   mX.resize( nVertices );
   287   mY.resize( nVertices );
   288   hasZ ? mZ.resize( nVertices ) : mZ.clear();
   289   hasM ? mM.resize( nVertices ) : mM.clear();
   290   for ( 
int i = 0; i < nVertices; ++i )
   317   if ( parts.second.compare( QLatin1String( 
"EMPTY" ), Qt::CaseInsensitive ) == 0 )
   326   int binarySize = 
sizeof( char ) + 
sizeof( quint32 ) + 
sizeof( quint32 );
   330   wkbArray.resize( binarySize );
   333   wkb << static_cast<quint32>( 
wkbType() );
   345     wkt += QStringLiteral( 
"EMPTY" );
   358   std::unique_ptr< QgsLineString > line( 
curveToLine() );
   359   QDomElement gml = line->asGml2( doc, precision, ns, axisOrder );
   368   QDomElement elemCurve = doc.createElementNS( ns, QStringLiteral( 
"Curve" ) );
   373   QDomElement elemSegments = doc.createElementNS( ns, QStringLiteral( 
"segments" ) );
   374   QDomElement elemArcString = doc.createElementNS( ns, QStringLiteral( 
"ArcString" ) );
   376   elemSegments.appendChild( elemArcString );
   377   elemCurve.appendChild( elemSegments );
   385   std::unique_ptr< QgsLineString > line( 
curveToLine() );
   386   return line->asJsonObject( precision );
   399   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   430   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   444   bool res = 
snapToGridPrivate( hSpacing, vSpacing, dSpacing, mSpacing, mX, mY, mZ, mM,
   445                                 result->mX, result->mY, result->mZ, result->mM );
   447     return result.release();
   454   if ( mX.count() <= 3 )
   457   double prevX = mX.at( 0 );
   458   double prevY = mY.at( 0 );
   460   bool useZ = hasZ && useZValues;
   461   double prevZ = useZ ? mZ.at( 0 ) : 0;
   463   int remaining = mX.count();
   466   while ( i + 1 < remaining )
   468     double currentCurveX = mX.at( i );
   469     double currentCurveY = mY.at( i );
   470     double currentX = mX.at( i + 1 );
   471     double currentY = mY.at( i + 1 );
   472     double currentZ = useZ ? mZ.at( i + 1 ) : 0;
   505   return std::min( mX.size(), mY.size() );
   510   if ( i < 0 || std::min( mX.size(), mY.size() ) <= i )
   515   double x = mX.at( i );
   516   double y = mY.at( i );
   547   if ( index >= 0 && index < mX.size() )
   548     return mX.at( index );
   555   if ( index >= 0 && index < mY.size() )
   556     return mY.at( index );
   565   int size = mX.size();
   567   double *srcX = mX.data(); 
   568   double *srcY = mY.data(); 
   569   double *srcM = hasM ? mM.data() : 
nullptr; 
   570   double *srcZ = hasZ ? mZ.data() : 
nullptr; 
   572   double *destX = srcX;
   573   double *destY = srcY;
   574   double *destM = srcM;
   575   double *destZ = srcZ;
   577   int filteredPoints = 0;
   578   for ( 
int i = 0; i < size; ++i )
   582     double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
   583     double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
   585     if ( filter( 
QgsPoint( x, y, z, m ) ) )
   597   mX.resize( filteredPoints );
   598   mY.resize( filteredPoints );
   600     mZ.resize( filteredPoints );
   602     mM.resize( filteredPoints );
   611   int size = mX.size();
   613   double *srcX = mX.data();
   614   double *srcY = mY.data();
   615   double *srcM = hasM ? mM.data() : 
nullptr;
   616   double *srcZ = hasZ ? mZ.data() : 
nullptr;
   618   for ( 
int i = 0; i < size; ++i )
   622     double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
   623     double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
   639   for ( 
int i = 0; i < nPts; ++i )
   641     pts.push_back( 
pointN( i ) );
   649   if ( points.empty() )
   660   const QgsPoint &firstPt = points.at( 0 );
   661   bool hasZ = firstPt.
is3D();
   666   mX.resize( points.size() );
   667   mY.resize( points.size() );
   670     mZ.resize( points.size() );
   678     mM.resize( points.size() );
   685   for ( 
int i = 0; i < points.size(); ++i )
   687     mX[i] = points[i].x();
   688     mY[i] = points[i].y();
   691       double z = points.at( i ).z();
   692       mZ[i] = std::isnan( z ) ? 0 : z;
   696       double m = points.at( i ).m();
   697       mM[i] = std::isnan( m ) ? 0 : m;
   713   double *zArray = mZ.data();
   717   bool useDummyZ = !hasZ || !transformZ;
   720     zArray = 
new double[nPoints];
   721     for ( 
int i = 0; i < nPoints; ++i )
   740   for ( 
int i = 0; i < nPoints; ++i )
   743     t.map( mX.at( i ), mY.at( i ), &x, &y );
   748       mZ[i] = mZ.at( i ) * zScale + zTranslate;
   752       mM[i] = mM.at( i ) * mScale + mTranslate;
   765   if ( path.isEmpty() || path.currentPosition() != QPointF( mX[0], mY[0] ) )
   767     path.moveTo( QPointF( mX[0], mY[0] ) );
   770   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   774     for ( 
int j = 1; j < pt.size(); ++j )
   776       path.lineTo( pt.at( j ).x(), pt.at( j ).y() );
   784   if ( nPoints % 2 == 0 )
   786     path.lineTo( mX[ nPoints - 1 ], mY[ nPoints - 1 ] );
   791 void QgsCircularString::arcTo( QPainterPath &path, QPointF pt1, QPointF pt2, QPointF pt3 )
   793   double centerX, centerY, radius;
   795                                         radius, centerX, centerY );
   800   double diameter = 2 * radius;
   801   path.arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle );
   812   if ( position.
vertex >= mX.size() || position.
vertex < 1 )
   817   mX.insert( position.
vertex, vertex.
x() );
   818   mY.insert( position.
vertex, vertex.
y() );
   821     mZ.insert( position.
vertex, vertex.
z() );
   825     mM.insert( position.
vertex, vertex.
m() );
   828   bool vertexNrEven = ( position.
vertex % 2 == 0 );
   843   if ( position.
vertex < 0 || position.
vertex >= mX.size() )
   848   mX[position.
vertex] = newPos.
x();
   849   mY[position.
vertex] = newPos.
y();
   852     mZ[position.
vertex] = newPos.
z();
   856     mM[position.
vertex] = newPos.
m();
   870   if ( position.
vertex < 0 || position.
vertex > ( nVertices - 1 ) )
   875   if ( position.
vertex < ( nVertices - 2 ) )
   908   double minDist = std::numeric_limits<double>::max();
   911   int minDistLeftOf = 0;
   913   double currentDist = 0.0;
   916   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   918     currentDist = closestPointOnArc( mX[i], mY[i], mX[i + 1], mY[i + 1], mX[i + 2], mY[i + 2], pt, segmentPt, vertexAfter, leftOf, epsilon );
   919     if ( currentDist < minDist )
   921       minDist = currentDist;
   922       minDistSegmentPoint = segmentPt;
   931   if ( minDist == std::numeric_limits<double>::max() )
   934   segmentPt = minDistSegmentPoint;
   935   vertexAfter = minDistVertexAfter;
   936   vertexAfter.
part = 0;
   937   vertexAfter.
ring = 0;
   960   for ( 
int i = 0; i < maxIndex; i += 2 )
   963     QgsPoint p2( mX[i + 1], mY[i + 1] );
   964     QgsPoint p3( mX[i + 2], mY[i + 2] );
   974     sum += 0.5 * ( mX[i] * mY[i + 2] - mY[i] * mX[i + 2] );
   977     double midPointX = ( p1.
x() + p3.
x() ) / 2.0;
   978     double midPointY = ( p1.
y() + p3.
y() ) / 2.0;
   980     double radius, centerX, centerY;
   984     double r2 = radius * radius;
   995     double cov = 0.5 - d * std::sqrt( r2 - d * d ) / ( M_PI * r2 ) - M_1_PI * std::asin( d / radius );
   996     double circleChordArea = 0;
   997     if ( circlePointLeftOfLine == centerPointLeftOfLine )
   999       circleChordArea = M_PI * r2 * ( 1 - cov );
  1003       circleChordArea = M_PI * r2 * cov;
  1006     if ( !circlePointLeftOfLine )
  1008       sum += circleChordArea;
  1012       sum -= circleChordArea;
  1022 double QgsCircularString::closestPointOnArc( 
double x1, 
double y1, 
double x2, 
double y2, 
double x3, 
double y3,
  1025   double radius, centerX, centerY;
  1050     segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3;
  1051     vertexAfter.
vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2;
  1058     segmentPt.
setX( pt.
x() );
  1059     segmentPt.
setY( pt.
y() );
  1065     double sqrDistancePointToCenter = ( pt.
x() - centerX ) * ( pt.
x() - centerX ) + ( pt.
y() - centerY ) * ( pt.
y() - centerY );
  1066     *leftOf = clockwise ? ( sqrDistancePointToCenter > radius * radius ? -1 : 1 )
  1067               : ( sqrDistancePointToCenter < radius * radius ? -1 : 1 );
  1073 void QgsCircularString::insertVertexBetween( 
int after, 
int before, 
int pointOnCircle )
  1075   double xAfter = mX.at( after );
  1076   double yAfter = mY.at( after );
  1077   double xBefore = mX.at( before );
  1078   double yBefore = mY.at( before );
  1079   double xOnCircle = mX.at( pointOnCircle );
  1080   double yOnCircle = mY.at( pointOnCircle );
  1082   double radius, centerX, centerY;
  1085   double x = ( xAfter + xBefore ) / 2.0;
  1086   double y = ( yAfter + yBefore ) / 2.0;
  1089   mX.insert( before, newVertex.
x() );
  1090   mY.insert( before, newVertex.
y() );
  1094     mZ.insert( before, ( mZ[after] + mZ[before] ) / 2.0 );
  1098     mM.insert( before, ( mM[after] + mM[before] ) / 2.0 );
  1111   int before = vId.
vertex - 1;
  1113   int after = vId.
vertex + 1;
  1115   if ( vId.
vertex % 2 != 0 ) 
  1145       int vertex1 = vId.
vertex - 2;
  1146       int vertex2 = vId.
vertex - 1;
  1147       int vertex3 = vId.
vertex;
  1149                       QgsPoint( mX[vertex1], mY[vertex1] ), 
QgsPoint( mX[vertex2], mY[vertex2] ), 
QgsPoint( mX[vertex3], mY[vertex3] ) );
  1150       int vertex4 = vId.
vertex + 1;
  1151       int vertex5 = vId.
vertex + 2;
  1153                       QgsPoint( mX[vertex3], mY[vertex3] ), 
QgsPoint( mX[vertex4], mY[vertex4] ), 
QgsPoint( mX[vertex5], mY[vertex5] ) );
  1162   if ( startVertex.
vertex < 0 || startVertex.
vertex >= mX.count() - 2 )
  1165   if ( startVertex.
vertex % 2 == 1 )
  1168   double x1 = mX.at( startVertex.
vertex );
  1169   double y1 = mY.at( startVertex.
vertex );
  1170   double x2 = mX.at( startVertex.
vertex + 1 );
  1171   double y2 = mY.at( startVertex.
vertex + 1 );
  1172   double x3 = mX.at( startVertex.
vertex + 2 );
  1173   double y3 = mY.at( startVertex.
vertex + 2 );
  1180   std::reverse( copy->mX.begin(), copy->mX.end() );
  1181   std::reverse( copy->mY.begin(), copy->mY.end() );
  1184     std::reverse( copy->mZ.begin(), copy->mZ.end() );
  1188     std::reverse( copy->mM.begin(), copy->mM.end() );
  1198   double distanceTraversed = 0;
  1200   if ( totalPoints == 0 )
  1209   const double *x = mX.constData();
  1210   const double *y = mY.constData();
  1211   const double *z = 
is3D() ? mZ.constData() : 
nullptr;
  1212   const double *m = 
isMeasure() ? mM.constData() : 
nullptr;
  1214   double prevX = *x++;
  1215   double prevY = *y++;
  1216   double prevZ = z ? *z++ : 0.0;
  1217   double prevM = m ? *m++ : 0.0;
  1221     return new QgsPoint( pointType, prevX, prevY, prevZ, prevM );
  1224   for ( 
int i = 0; i < ( totalPoints - 2 ) ; i += 2 )
  1233     double z2 = z ? *z++ : 0.0;
  1234     double m2 = m ? *m++ : 0.0;
  1238     double z3 = z ? *z++ : 0.0;
  1239     double m3 = m ? *m++ : 0.0;
  1242     if ( distance < distanceTraversed + segmentLength || 
qgsDoubleNear( distance, distanceTraversed + segmentLength ) )
  1245       const double distanceToPoint = std::min( distance - distanceTraversed, segmentLength );
  1247                            QgsPoint( pointType, x2, y2, z2, m2 ),
  1248                            QgsPoint( pointType, x3, y3, z3, m3 ), distanceToPoint ) );
  1264   if ( startDistance < 0 && endDistance < 0 )
  1267   endDistance = std::max( startDistance, endDistance );
  1269   double distanceTraversed = 0;
  1271   if ( totalPoints == 0 )
  1274   QVector< QgsPoint > substringPoints;
  1282   const double *x = mX.constData();
  1283   const double *y = mY.constData();
  1284   const double *z = 
is3D() ? mZ.constData() : 
nullptr;
  1285   const double *m = 
isMeasure() ? mM.constData() : 
nullptr;
  1287   double prevX = *x++;
  1288   double prevY = *y++;
  1289   double prevZ = z ? *z++ : 0.0;
  1290   double prevM = m ? *m++ : 0.0;
  1291   bool foundStart = 
false;
  1293   if ( 
qgsDoubleNear( startDistance, 0.0 ) || startDistance < 0 )
  1295     substringPoints << 
QgsPoint( pointType, prevX, prevY, prevZ, prevM );
  1299   substringPoints.reserve( totalPoints );
  1301   for ( 
int i = 0; i < ( totalPoints - 2 ) ; i += 2 )
  1310     double z2 = z ? *z++ : 0.0;
  1311     double m2 = m ? *m++ : 0.0;
  1315     double z3 = z ? *z++ : 0.0;
  1316     double m3 = m ? *m++ : 0.0;
  1318     bool addedSegmentEnd = 
false;
  1320     if ( distanceTraversed < startDistance && distanceTraversed + segmentLength > startDistance )
  1323       const double distanceToStart = startDistance - distanceTraversed;
  1325                                   QgsPoint( pointType, x2, y2, z2, m2 ),
  1326                                   QgsPoint( pointType, x3, y3, z3, m3 ), distanceToStart );
  1329       const bool endPointOnSegment = distanceTraversed + segmentLength > endDistance;
  1330       if ( endPointOnSegment )
  1332         const double distanceToEnd = endDistance - distanceTraversed;
  1333         const double midPointDistance = ( distanceToEnd - distanceToStart ) * 0.5 + distanceToStart;
  1334         substringPoints << startPoint
  1336                             QgsPoint( pointType, x2, y2, z2, m2 ),
  1337                             QgsPoint( pointType, x3, y3, z3, m3 ), midPointDistance )
  1339                             QgsPoint( pointType, x2, y2, z2, m2 ),
  1340                             QgsPoint( pointType, x3, y3, z3, m3 ), distanceToEnd );
  1341         addedSegmentEnd = 
true;
  1345         const double midPointDistance = ( segmentLength - distanceToStart ) * 0.5 + distanceToStart;
  1346         substringPoints << startPoint
  1348                             QgsPoint( pointType, x2, y2, z2, m2 ),
  1349                             QgsPoint( pointType, x3, y3, z3, m3 ), midPointDistance )
  1350                         << 
QgsPoint( pointType, x3, y3, z3, m3 );
  1351         addedSegmentEnd = 
true;
  1355     if ( !addedSegmentEnd && foundStart && ( distanceTraversed + segmentLength > endDistance ) )
  1358       const double distanceToEnd = endDistance - distanceTraversed;
  1361                       QgsPoint( pointType, x2, y2, z2, m2 ),
  1362                       QgsPoint( pointType, x3, y3, z3, m3 ), distanceToEnd / 2.0 )
  1365                           QgsPoint( pointType, x2, y2, z2, m2 ),
  1366                           QgsPoint( pointType, x3, y3, z3, m3 ), distanceToEnd );
  1368     else if ( !addedSegmentEnd && foundStart )
  1370       substringPoints << 
QgsPoint( pointType, x2, y2, z2, m2 )
  1371                       << 
QgsPoint( pointType, x3, y3, z3, m3 );
  1375     if ( distanceTraversed > endDistance )
  1384   std::unique_ptr< QgsCircularString > result = qgis::make_unique< QgsCircularString >();
  1385   result->setPoints( substringPoints );
  1386   return result.release();
  1399   mZ.reserve( nPoints );
  1400   for ( 
int i = 0; i < nPoints; ++i )
  1417   mM.reserve( nPoints );
  1418   for ( 
int i = 0; i < nPoints; ++i )
  1451   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. 
 
json asJsonObject(int precision=17) const override
Returns a json object representation of the geometry. 
 
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. 
 
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...
 
static QDomElement pointsToGML3(const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, bool is3D, QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY)
Returns a gml::posList DOM element. 
 
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 the circle defined by three angles 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 int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2)
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> ( x2, y2). 
 
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type. 
 
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry. 
 
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 planar, 2-dimensional length of the geometry. 
 
QgsPoint * interpolatePoint(double distance) const override
Returns an interpolated point on the curve at the specified distance. 
 
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 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. 
 
static QgsPoint interpolatePointOnArc(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance)
Interpolates a point on an arc defined by three points, pt1, pt2 and pt3. 
 
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...
 
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 transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform) override
Transforms the vertices from the geometry in place, applying the transform function to every vertex...
 
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override SIP_THROW(QgsCsException)
Transforms the geometry using a coordinate transform. 
 
QgsCircularString * curveSubstring(double startDistance, double endDistance) const override
Returns a new curve representing a substring of this curve. 
 
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'. Negative values mean left ...
 
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.