26 #include <QStringList>    28 #include <QRegularExpression>    29 #include <nlohmann/json.hpp>    33   QVector< QgsLineString * > linestrings;
    37   QVector< const QgsAbstractGeometry * > geometries;
    39   while ( ! geometries.isEmpty() )
    42     if ( 
const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( g ) )
    44       linestrings << static_cast< QgsLineString * >( curve->segmentize() );
    46     else if ( 
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g ) )
    48       for ( 
int i = 0; i < collection->numGeometries(); ++i )
    50         geometries.append( collection->geometryN( i ) );
    53     else if ( 
const QgsCurvePolygon *curvePolygon = qgsgeometry_cast< const QgsCurvePolygon * >( g ) )
    55       if ( curvePolygon->exteriorRing() )
    56         linestrings << static_cast< QgsLineString * >( curvePolygon->exteriorRing()->segmentize() );
    58       for ( 
int i = 0; i < curvePolygon->numInteriorRings(); ++i )
    60         linestrings << static_cast< QgsLineString * >( curvePolygon->interiorRing( i )->segmentize() );
    69   double minDist = std::numeric_limits<double>::max();
    70   double currentDist = 0;
    84     if ( currentDist <= minDist )
    86       minDist = currentDist;
    87       minDistPoint = vertex;
    88       id.part = vertexId.
part;
    89       id.ring = vertexId.
ring;
    90       id.vertex = vertexId.
vertex;
    91       id.type = vertexId.
type;
   106     if ( vertexAfter.
vertex > 0 )
   112       double distance = pointBefore.
distance( closestPoint );
   115         closestPoint = pointBefore;
   117         closestPoint = pointAfter;
   121           closestPoint.
addZValue( pointBefore.
z() + ( pointAfter.
z() - pointBefore.
z() ) * distance / length );
   123           closestPoint.
addMValue( pointBefore.
m() + ( pointAfter.
m() - pointBefore.
m() ) * distance / length );
   133   double currentDist = 0;
   138     if ( vertexId == 
id )
   152   double currentDist = 0;
   162     nextVertex = previousVertex;
   167   while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
   169     if ( !first && nextVertex.
part == previousVertex.
part && nextVertex.
ring == previousVertex.
ring )
   181     if ( currentDist > distance )
   187     previousPoint = point;
   197   return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
   210     double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
   226   double dist = dx * dx + dy * dy;
   241   double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
   246   double dx = p2.
x() - p1.
x();
   247   double dy = p2.
y() - p1.
y();
   248   double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
   250   intersection = 
QgsPoint( p1.
x() + v1.
x() * k, p1.
y() + v1.
y() * k );
   260   isIntersection = 
false;
   265   double wl = w.length();
   279   isIntersection = 
true;
   280   if ( acceptImproperIntersection )
   282     if ( ( p1 == q1 ) || ( p1 == q2 ) )
   284       intersectionPoint = p1;
   287     else if ( ( p2 == q1 ) || ( p2 == q2 ) )
   289       intersectionPoint = p2;
   296       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( p1.
x(), p1.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
   298       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( p2.
x(), p2.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
   300       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( q1.
x(), q1.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
   302       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( q2.
x(), q2.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance )
   309   double lambdav = 
QgsVector( intersectionPoint.
x() - p1.
x(), intersectionPoint.
y() - p1.
y() ) *  v;
   310   if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
   313   double lambdaw = 
QgsVector( intersectionPoint.
x() - q1.
x(), intersectionPoint.
y() - q1.
y() ) * w;
   314   return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
   324   const double x1 = linePoint1.
x() - center.
x();
   325   const double y1 = linePoint1.
y() - center.
y();
   326   const double x2 = linePoint2.
x() - center.
x();
   327   const double y2 = linePoint2.
y() - center.
y();
   328   const double dx = x2 - x1;
   329   const double dy = y2 - y1;
   331   const double dr2 = std::pow( dx, 2 ) + std::pow( dy, 2 );
   332   const double d = x1 * y2 - x2 * y1;
   334   const double disc = std::pow( radius, 2 ) * dr2 - std::pow( d, 2 );
   344     const int sgnDy = dy < 0 ? -1 : 1;
   346     const double sqrDisc = std::sqrt( disc );
   348     const double ax = center.
x() + ( d * dy + sgnDy * dx * sqrDisc ) / dr2;
   349     const double ay = center.
y() + ( -d * dx + std::fabs( dy ) * sqrDisc ) / dr2;
   352     const double bx = center.
x() + ( d * dy - sgnDy * dx * sqrDisc ) / dr2;
   353     const double by = center.
y() + ( -d * dx - std::fabs( dy ) * sqrDisc ) / dr2;
   360       intersection.
set( p1.
x(), p1.
y() );
   364       intersection.
set( p2.
x(), p2.
y() );
   375   const double d = center0.
distance( center1 );
   378   if ( d > ( r0 + r1 ) )
   383   else if ( d < std::fabs( r0 - r1 ) )
   400   const double a = ( ( r0 * r0 ) - ( r1 * r1 ) + ( d * d ) ) / ( 2.0 * d ) ;
   405   const double dx = center1.
x() - center0.
x();
   406   const double dy = center1.
y() - center0.
y();
   409   const double x2 = center0.
x() + ( dx * a / d );
   410   const double y2 = center0.
y() + ( dy * a / d );
   415   const double h = std::sqrt( ( r0 * r0 ) - ( a * a ) );
   420   const double rx = dy * ( h / d );
   421   const double ry = dx * ( h / d );
   424   intersection1 = 
QgsPointXY( x2 + rx, y2 - ry );
   425   intersection2 = 
QgsPointXY( x2 - rx, y2 +  ry );
   439   const double dx = center.
x() - p.
x();
   440   const double dy = center.
y() - p.
y();
   441   const double distanceSquared = dx * dx + dy * dy;
   442   const double radiusSquared = radius * radius;
   443   if ( distanceSquared < radiusSquared )
   450   const double distanceToTangent = std::sqrt( distanceSquared - radiusSquared );
   462   if ( radius1 > radius2 )
   465   const double radius2a = radius2 - radius1;
   474   QgsVector v1( -( line1P2.
y() - center1.
y() ), line1P2.
x() - center1.
x() );
   475   const double v1Length = v1.
length();
   476   v1 = v1 * ( radius1 / v1Length );
   479   line1P1 = center1 + v1;
   480   line1P2 = line1P2 + v1;
   484   QgsVector v2( line2P2.
y() - center1.
y(), -( line2P2.
x() - center1.
x() ) );
   485   const double v2Length = v2.
length();
   486   v2 = v2 * ( radius1 / v2Length );
   489   line2P1 = center1 + v2;
   490   line2P2 = line2P2 + v2;
   498   if ( radius1 > radius2 )
   502   const double d = center1.
distance( center2 );
   503   const double radius1a = radius1 + radius2;
   520   QgsVector v1( ( line1P2.
y() - center2.
y() ), -( line1P2.
x() - center2.
x() ) );
   521   const double v1Length = v1.
length();
   522   v1 = v1 * ( radius2 / v1Length );
   525   line1P1 = center2 + v1;
   526   line1P2 = line1P2 + v1;
   530   QgsVector v2( -( line2P2.
y() - center2.
y() ), line2P2.
x() - center2.
x() );
   531   const double v2Length = v2.
length();
   532   v2 = v2 * ( radius2 / v2Length );
   535   line2P1 = center2 + v2;
   536   line2P2 = line2P2 + v2;
   543   QVector<SelfIntersection> intersections;
   549   for ( 
int i = 0, j = 1; j < n; i = j++ )
   557     int end = i == 0 && isClosed ? n - 1 : n;
   558     for ( 
int k = start, l = start + 1; l < end; k = l++ )
   564       bool intersection = 
false;
   575       intersections.append( s );
   578   return intersections;
   592   double test = ( f1 * f2 - f3 * f4 );
   594   return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
   604 void QgsGeometryUtils::pointOnLineWithDistance( 
double x1, 
double y1, 
double x2, 
double y2, 
double distance, 
double &x, 
double &y, 
double *z1, 
double *z2, 
double *z, 
double *m1, 
double *m2, 
double *m )
   606   const double dx = x2 - x1;
   607   const double dy = y2 - y1;
   608   const double length = std::sqrt( dx * dx + dy * dy );
   621     const double scaleFactor = distance / 
length;
   622     x = x1 + dx * scaleFactor;
   623     y = y1 + dy * scaleFactor;
   625       *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
   627       *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
   633   double centerX, centerY, radius;
   636   const double theta = distance / radius; 
   637   const double anglePt1 = std::atan2( pt1.
y() - centerY, pt1.
x() - centerX );
   638   const double anglePt2 = std::atan2( pt2.
y() - centerY, pt2.
x() - centerX );
   639   const double anglePt3 = std::atan2( pt3.
y() - centerY, pt3.
x() - centerX );
   640   const bool isClockwise = 
circleClockwise( anglePt1, anglePt2, anglePt3 );
   641   const double angleDest = anglePt1 + ( isClockwise ? -theta : theta );
   643   const double x = centerX + radius * ( std::cos( angleDest ) );
   644   const double y = centerY + radius * ( std::sin( angleDest ) );
   646   const double z = pt1.
is3D() ?
   658   double angle = std::atan2( dy, dx ) * 180 / M_PI;
   663   else if ( angle > 360 )
   672   double dx21, dy21, dx31, dy31, h21, h31, d;
   677     centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
   678     centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
   679     radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
   684   dx21 = pt2.
x() - pt1.
x();
   685   dy21 = pt2.
y() - pt1.
y();
   686   dx31 = pt3.
x() - pt1.
x();
   687   dy31 = pt3.
y() - pt1.
y();
   689   h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
   690   h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
   693   d = 2 * ( dx21 * dy31 - dx31 * dy21 );
   703   centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
   704   centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
   705   radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
   710   if ( angle3 >= angle1 )
   712     return !( angle2 > angle1 && angle2 < angle3 );
   716     return !( angle2 > angle1 || angle2 < angle3 );
   724     if ( angle2 < angle1 )
   726       return ( angle <= angle1 && angle >= angle2 );
   730       return ( angle <= angle1 || angle >= angle2 );
   735     if ( angle2 > angle1 )
   737       return ( angle >= angle1 && angle <= angle2 );
   741       return ( angle >= angle1 || angle <= angle2 );
   754   double centerX, centerY, radius;
   756   double length = M_PI / 180.0 * radius * 
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
   770   if ( p3Angle >= p1Angle )
   772     if ( p2Angle > p1Angle && p2Angle < p3Angle )
   774       return ( p3Angle - p1Angle );
   778       return ( - ( p1Angle + ( 360 - p3Angle ) ) );
   783     if ( p2Angle < p1Angle && p2Angle > p3Angle )
   785       return ( -( p1Angle - p3Angle ) );
   789       return ( p3Angle + ( 360 - p1Angle ) );
   796   QgsPoint midPoint( ( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
   798   if ( radius < midDist )
   802   double centerMidDist = std::sqrt( radius * radius - midDist * midDist );
   803   double dist = radius - centerMidDist;
   805   double midDx = midPoint.
x() - p1.
x();
   806   double midDy = midPoint.
y() - p1.
y();
   809   QVector<QgsPoint> possibleMidPoints;
   816   double minDist = std::numeric_limits<double>::max();
   817   int minDistIndex = -1;
   818   for ( 
int i = 0; i < possibleMidPoints.size(); ++i )
   820     double currentDist = 
sqrDistance2D( mousePos, possibleMidPoints.at( i ) );
   821     if ( currentDist < minDist )
   824       minDist = currentDist;
   828   if ( minDistIndex == -1 )
   833   result = possibleMidPoints.at( minDistIndex );
   845   if ( !useShortestArc )
   846     midPointAngle += M_PI;
   847   return center.
project( center.
distance( p1 ), midPointAngle * 180 / M_PI );
   854   double mX, mY, radius;
   863     angle = 
lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY ) - M_PI_2;
   867     angle = 
lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() ) - M_PI_2;
   876   bool reversed = 
false;
   900   circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
   902   if ( circlePoint1 != circlePoint3 && ( radius < 0 || 
qgsDoubleNear( segSide, 0.0 ) ) ) 
   910   double increment = tolerance; 
   914     tolerance = std::min( tolerance, radius * 2 );
   915     double halfAngle = std::acos( -tolerance / radius + 1 );
   916     increment = 2 * halfAngle;
   920   double a1 = std::atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
   921   double a2 = std::atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
   922   double a3 = std::atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
   925   const bool symmetric = 
true;
   928     double angle = a3 - a1;
   930     if ( angle <= 0 ) angle += M_PI * 2;
   933     int segs = ceil( angle / increment );
   935     increment = angle / segs;
   949   QVector<QgsPoint> stringPoints;
   950   stringPoints.insert( 0, circlePoint1 );
   951   if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) 
   965     double tolError = increment / 100;
   966     double stopAngle = a3 - tolError;
   967     for ( 
double angle = a1 + increment; 
angle < stopAngle; 
angle += increment )
   969       x = centerX + radius * std::cos( 
angle );
   970       y = centerY + radius * std::sin( 
angle );
   981       stringPoints.insert( stringPoints.size(), 
QgsPoint( pointWkbType, x, y, z, m ) );
   984   stringPoints.insert( stringPoints.size(), circlePoint3 );
   989     std::reverse( stringPoints.begin(), stringPoints.end() );
   991   if ( ! points.empty() && stringPoints.front() == points.back() ) stringPoints.pop_front();
   992   points.append( stringPoints );
   997   double side = ( ( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
  1022       return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
  1024       return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
  1030       return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
  1032       return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
  1040   const QStringList coordList = wktCoordinateList.split( 
',', QString::SkipEmptyParts );
  1043   bool foundZ = 
false;
  1044   bool foundM = 
false;
  1045   QRegularExpression rx( QStringLiteral( 
"\\s" ) );
  1046   for ( 
const QString &pointCoordinates : coordList )
  1048     QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
  1049     if ( coordinates.size() == 3 && !foundZ && !foundM && !is3D && !
isMeasure )
  1055     else if ( coordinates.size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
  1064   for ( 
const QString &pointCoordinates : coordList )
  1066     QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
  1067     if ( coordinates.size() < dim )
  1071     double x = coordinates[idx++].toDouble();
  1072     double y = coordinates[idx++].toDouble();
  1075     if ( ( is3D || foundZ ) && coordinates.length() > idx )
  1076       z = coordinates[idx++].toDouble();
  1079     if ( ( isMeasure || foundM ) && coordinates.length() > idx )
  1080       m = coordinates[idx++].toDouble();
  1083     if ( is3D || foundZ )
  1085       if ( isMeasure || foundM )
  1092       if ( isMeasure || foundM )
  1098     points.append( 
QgsPoint( t, x, y, z, m ) );
  1106   wkb << static_cast<quint32>( points.size() );
  1107   for ( 
const QgsPoint &point : points )
  1109     wkb << point.x() << point.y();
  1123   QString wkt = QStringLiteral( 
"(" );
  1132     wkt += QLatin1String( 
", " );
  1134   if ( wkt.endsWith( QLatin1String( 
", " ) ) )
  1142   QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral( 
"coordinates" ) );
  1145   QString cs = QStringLiteral( 
"," );
  1147   QString ts = QStringLiteral( 
" " );
  1149   elemCoordinates.setAttribute( QStringLiteral( 
"cs" ), cs );
  1150   elemCoordinates.setAttribute( QStringLiteral( 
"ts" ), ts );
  1152   QString strCoordinates;
  1155     if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
  1160   if ( strCoordinates.endsWith( ts ) )
  1161     strCoordinates.chop( 1 ); 
  1163   elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
  1164   return elemCoordinates;
  1169   QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral( 
"posList" ) );
  1170   elemPosList.setAttribute( QStringLiteral( 
"srsDimension" ), is3D ? 3 : 2 );
  1172   QString strCoordinates;
  1175     if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
  1182   if ( strCoordinates.endsWith( 
' ' ) )
  1183     strCoordinates.chop( 1 ); 
  1185   elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
  1191   QString json = QStringLiteral( 
"[ " );
  1196   if ( json.endsWith( QLatin1String( 
", " ) ) )
  1207   json coordinates( json::array() );
  1224   double clippedAngle = 
angle;
  1225   if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
  1227     clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
  1229   if ( clippedAngle < 0.0 )
  1231     clippedAngle += 2 * M_PI;
  1233   return clippedAngle;
  1238   QString wktParsed = wkt;
  1240   if ( wkt.contains( QString( 
"EMPTY" ), Qt::CaseInsensitive ) )
  1242     QRegularExpression wktRegEx( QStringLiteral( 
"^\\s*(\\w+)\\s+(\\w+)\\s*$" ) );
  1243     wktRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
  1244     QRegularExpressionMatch match = wktRegEx.match( wkt );
  1245     if ( match.hasMatch() )
  1247       wktParsed = match.captured( 1 );
  1248       contents = match.captured( 2 ).toUpper();
  1253     QRegularExpression cooRegEx( QStringLiteral( 
"^[^\\(]*\\((.*)\\)[^\\)]*$" ) );
  1254     cooRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
  1255     QRegularExpressionMatch match = cooRegEx.match( wktParsed );
  1256     contents = match.hasMatch() ? match.captured( 1 ) : QString();
  1259   return qMakePair( wkbType, contents );
  1267   for ( 
int i = 0, n = wkt.length(); i < n; ++i )
  1269     if ( ( wkt[i].isSpace() || wkt[i] == 
'\n' || wkt[i] == 
'\t' ) && level == 0 )
  1272     if ( wkt[i] == 
',' && level == 0 )
  1274       if ( !block.isEmpty() )
  1276         if ( block.startsWith( 
'(' ) && !defaultType.isEmpty() )
  1277           block.prepend( defaultType + 
' ' );
  1278         blocks.append( block );
  1283     if ( wkt[i] == 
'(' )
  1285     else if ( wkt[i] == 
')' )
  1289   if ( !block.isEmpty() )
  1291     if ( block.startsWith( 
'(' ) && !defaultType.isEmpty() )
  1292       block.prepend( defaultType + 
' ' );
  1293     blocks.append( block );
  1303   double x = ( pt1.
x() + pt2.
x() ) / 2.0;
  1304   double y = ( pt1.
y() + pt2.
y() ) / 2.0;
  1305   double z = std::numeric_limits<double>::quiet_NaN();
  1306   double m = std::numeric_limits<double>::quiet_NaN();
  1311     z = ( pt1.
z() + pt2.
z() ) / 2.0;
  1317     m = ( pt1.
m() + pt2.
m() ) / 2.0;
  1320   return QgsPoint( pType, x, y, z, m );
  1325   const double _fraction = 1 - fraction;
  1327                    p1.
x() * _fraction + p2.
x() * fraction,
  1328                    p1.
y() * _fraction + p2.
y() * fraction,
  1329                    p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
  1330                    p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
  1335   const double deltaX = ( x2 - x1 ) * fraction;
  1336   const double deltaY = ( y2 - y1 ) * fraction;
  1337   return QgsPointXY( x1 + deltaX, y1 + deltaY );
  1345   const double fraction = ( value - v1 ) / ( v2 - v1 );
  1351   double delta_x = pt2.
x() - pt1.
x();
  1352   double delta_y = pt2.
y() - pt1.
y();
  1358   return delta_y / delta_x;
  1377     a = pt1.
y() - pt2.
y();
  1378     b = pt2.
x() - pt1.
x();
  1379     c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
  1389   if ( ( p == s1 ) || ( p == s2 ) )
  1407     double y = ( -c - a * p.
x() ) / b;
  1409     double d2 = 1 + m * m;
  1410     double H = p.
y() - y;
  1411     double dx = m * H / d2;
  1424   double at = std::atan2( y2 - y1, x2 - x1 );
  1425   double a = -at + M_PI_2;
  1431   double angle1 = std::atan2( y1 - y2, x1 - x2 );
  1432   double angle2 = std::atan2( y3 - y2, x3 - x2 );
  1446   double a1 = 
lineAngle( x1, y1, x2, y2 );
  1447   double a2 = 
lineAngle( x2, y2, x3, y3 );
  1455   double clockwiseDiff = 0.0;
  1458     clockwiseDiff = a2 - a1;
  1462     clockwiseDiff = a2 + ( 2 * M_PI - a1 );
  1464   double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
  1466   double resultAngle = 0;
  1467   if ( clockwiseDiff <= counterClockwiseDiff )
  1469     resultAngle = a1 + clockwiseDiff / 2.0;
  1473     resultAngle = a1 - counterClockwiseDiff / 2.0;
  1484   if ( u3.
length() == 0 ) 
return 1;
  1501   if ( std::fabs( u3.
x() ) <= epsilon &&
  1502        std::fabs( u3.
y() ) <= epsilon &&
  1503        std::fabs( u3.
z() ) <= epsilon )
  1515   if ( !( std::fabs( b1 ) > epsilon ) )
  1520   if ( !( a2 != -1 && a2 != 1 ) )
  1526   double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
  1542     bool isIntersection;
  1551     intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
  1591   if ( !firstIsDone || !secondIsDone )
  1597   intersection = ( X1 + X2 ) / 2.0;
  1603   return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
  1607     double weightB, 
double weightC, 
double &pointX, 
double &pointY )
  1610   if ( weightB + weightC > 1 )
  1612     weightB = 1 - weightB;
  1613     weightC = 1 - weightC;
  1616   const double rBx = weightB * ( bX - aX );
  1617   const double rBy = weightB * ( bY - aY );
  1618   const double rCx = weightC * ( cX - aX );
  1619   const double rCy = weightC * ( cY - aY );
  1621   pointX = rBx + rCx + aX;
  1622   pointY = rBy + rCy + aY;
  1629   for ( 
const QgsPoint &pt : points )
  1634       point.
setZ( pt.z() );
 bool isMeasure() const
Returns true if the geometry contains m values. 
 
Maximum distance between an arbitrary point on the original curve and closest point on its approximat...
 
static bool lineCircleIntersection(const QgsPointXY ¢er, double radius, const QgsPointXY &linePoint1, const QgsPointXY &linePoint2, QgsPointXY &intersection)
Compute the intersection of a line and a circle. 
 
3 Class for storage of 3D vectors similar to QVector3D, with the difference that it uses double preci...
 
static double skewLinesDistance(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22)
An algorithm to calculate the shortest distance between two skew lines. 
 
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string. 
 
void set(double x, double y)
Sets the x and y value of the point. 
 
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 interpolateArcValue(double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3)
Interpolate a value at given angle on circular arc given values (zm1, zm2, zm3) at three different an...
 
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...
 
static bool verticesAtDistance(const QgsAbstractGeometry &geometry, double distance, QgsVertexId &previousVertex, QgsVertexId &nextVertex)
Retrieves the vertices which are before and after the interpolated point at a specified distance alon...
 
static bool segmentIntersection(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint &q1, const QgsPoint &q2, QgsPoint &intersectionPoint, bool &isIntersection, double tolerance=1e-8, bool acceptImproperIntersection=false)
Compute the intersection between two segments. 
 
static QVector< SelfIntersection > selfIntersections(const QgsAbstractGeometry *geom, int part, int ring, double tolerance)
Find self intersections in a polyline. 
 
static int segmentSide(const QgsPoint &pt1, const QgsPoint &pt3, const QgsPoint &pt2)
For line defined by points pt1 and pt3, find out on which side of the line is point pt3...
 
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value. 
 
static double lineAngle(double x1, double y1, double x2, double y2)
Calculates the direction of line joining two points in radians, clockwise from the north direction...
 
bool isValid() const
Returns true if the vertex id is valid. 
 
void setZ(double z)
Sets the point's z-coordinate. 
 
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 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). 
 
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3)
Calculates the angle between the lines AB and BC, where AB and BC described by points a...
 
double distance(double x, double y) const
Returns the Cartesian 2D distance between this point and a specified x, y coordinate. 
 
static double gradient(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the gradient of a line defined by points pt1 and pt2. 
 
double length() const
Returns the length of the vector. 
 
A class to represent a 2D point. 
 
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 Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string. 
 
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. 
 
Curve polygon geometry type. 
 
static double linePerpendicularAngle(double x1, double y1, double x2, double y2)
Calculates the perpendicular angle to a line joining two points. 
 
static bool segmentMidPoint(const QgsPoint &p1, const QgsPoint &p2, QgsPoint &result, double radius, const QgsPoint &mousePos)
Calculates midpoint on circle passing through p1 and p2, closest to the given coordinate mousePos...
 
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...
 
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point. 
 
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates. 
 
double y() const
Returns Y coordinate. 
 
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension. 
 
static int circleCircleOuterTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2)
Calculates the outer tangent points for two circles, centered at center1 and center2 and with radii o...
 
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 QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT. 
 
void set(double x, double y, double z)
Sets vector coordinates. 
 
static double dotProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the dot product of two vectors. 
 
static QgsVector3D crossProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the cross product of two vectors. 
 
static QDomElement pointsToGML2(const QgsPointSequence &points, QDomDocument &doc, int precision, const QString &ns, QgsAbstractGeometry::AxisOrder axisOrder=QgsAbstractGeometry::AxisOrder::XY)
Returns a gml::coordinates DOM element. 
 
void normalize()
Normalizes the current vector in place. 
 
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate. 
 
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
 
virtual double length() const
Returns the planar, 2-dimensional length of the geometry. 
 
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if the circle defined by three angles is ordered clockwise. 
 
double z() const
Returns Z coordinate. 
 
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list. 
 
Type
The WKB type describes the number of dimensions a geometry has. 
 
static double triangleArea(double aX, double aY, double bX, double bY, double cX, double cY)
Returns the area of the triangle denoted by the points (aX, aY), (bX, bY) and (cX, cY). 
 
virtual double closestSegment(const QgsPoint &pt, QgsPoint &segmentPt, QgsVertexId &vertexAfter, int *leftOf=nullptr, double epsilon=4 *std::numeric_limits< double >::epsilon()) const =0
Searches for the closest segment of the geometry to a given point. 
 
static bool setZValueFromPoints(const QgsPointSequence &points, QgsPoint &point)
A Z dimension is added to point if one of the point in the list points is in 3D. 
 
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex. 
 
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type. 
 
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). 
 
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string. 
 
Utility class for identifying a unique vertex within a geometry. 
 
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments. 
 
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2)
Returns a middle point between points pt1 and pt2. 
 
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double. 
 
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) ...
 
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. 
 
static bool linesIntersection3D(const QgsVector3D &La1, const QgsVector3D &La2, const QgsVector3D &Lb1, const QgsVector3D &Lb2, QgsVector3D &intersection)
An algorithm to calculate an (approximate) intersection of two lines in 3D. 
 
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction)
Interpolates the position of a point a fraction of the way along the line from (x1, y1) to (x2, y2). 
 
Abstract base class for all geometries. 
 
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry. 
 
static double normalizedAngle(double angle)
Ensures that an angle is in the range 0 <= angle < 2 pi. 
 
double distance(double x, double y) const
Returns the distance between this point and a specified x, y coordinate. 
 
QgsWkbTypes::Type wkbType() const
Returns the WKB type of the geometry. 
 
QgsPoint project(double distance, double azimuth, double inclination=90.0) const
Returns a new point which correspond to this point projected by a specified distance with specified a...
 
Point geometry type, with support for z-dimension and m-values. 
 
AxisOrder
Axis order for GML generation. 
 
double length() const
Returns the length of the vector. 
 
static bool lineIntersection(const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection)
Computes the intersection between two lines. 
 
A class to represent a vector. 
 
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object. 
 
static bool skewLinesProjection(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22, QgsVector3D &X1, double epsilon=0.0001)
A method to project one skew line onto another. 
 
QVector< QgsPoint > QgsPointSequence
 
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance)
Returns a point a specified distance toward a second point. 
 
static double sqrDistance2D(const QgsPoint &pt1, const QgsPoint &pt2)
Returns the squared 2D distance between two points. 
 
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places...
 
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 QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2)
Create a perpendicular line segment from p to segment [s1, s2]. 
 
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string. 
 
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. 
 
virtual int vertexCount(int part=0, int ring=0) const =0
Returns the number of vertices of which this geometry is built. 
 
static bool tangentPointAndCircle(const QgsPointXY ¢er, double radius, const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2)
Calculates the tangent points between the circle with the specified center and radius and the point p...
 
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. 
 
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type. 
 
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value. 
 
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }. 
 
static int circleCircleInnerTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2)
Calculates the inner tangent points for two circles, centered at center1 and center2 and with radii o...
 
static int circleCircleIntersections(QgsPointXY center1, double radius1, QgsPointXY center2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2)
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
 
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon)
Returns the squared distance between a point and a line. 
 
static bool hasM(Type type)
Tests whether a WKB type contains m values. 
 
double x() const
Returns the vector's x-component. 
 
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point. 
 
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id. 
 
static void weightedPointInTriangle(double aX, double aY, double bX, double bY, double cX, double cY, double weightB, double weightC, double &pointX, double &pointY)
Returns a weighted point inside the triangle denoted by the points (aX, aY), (bX, bY) and (cX...
 
double y() const
Returns the vector's y-component. 
 
static double distanceToVertex(const QgsAbstractGeometry &geom, QgsVertexId id)
Returns the distance along a geometry from its first vertex to the specified vertex. 
 
static QgsPointXY interpolatePointOnLineByValue(double x1, double y1, double v1, double x2, double y2, double v2, double value)
Interpolates the position of a point along the line from (x1, y1) to (x2, y2). 
 
bool is3D() const
Returns true if the geometry is 3D and contains a z-value. 
 
double x() const
Returns X coordinate. 
 
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. 
 
static void coefficients(const QgsPoint &pt1, const QgsPoint &pt2, double &a, double &b, double &c)
Returns the coefficients (a, b, c for equation "ax + by + c = 0") of a line defined by points pt1 and...