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;
 
   87     if ( currentDist <= minDist )
 
   89       minDist = currentDist;
 
   90       minDistPoint = vertex;
 
   91       id.part = vertexId.
part;
 
   92       id.ring = vertexId.
ring;
 
   93       id.vertex = vertexId.
vertex;
 
   94       id.type = vertexId.
type;
 
  109     if ( vertexAfter.
vertex > 0 )
 
  114       double length = pointBefore.
distance( pointAfter );
 
  136   double currentDist = 0;
 
  141     if ( vertexId == 
id )
 
  155   double currentDist = 0;
 
  165     nextVertex = previousVertex;
 
  170   while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
 
  172     if ( !first && nextVertex.
part == previousVertex.
part && nextVertex.
ring == previousVertex.
ring )
 
  180       previousVertex = nextVertex;
 
  184     if ( currentDist > distance )
 
  189     previousVertex = nextVertex;
 
  190     previousPoint = point;
 
  200   return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
 
  213     double t = ( ( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
 
  229   double dist = dx * dx + dy * dy;
 
  244   double d = v1.
y() * v2.
x() - v1.
x() * v2.
y();
 
  249   double dx = p2.
x() - p1.
x();
 
  250   double dy = p2.
y() - p1.
y();
 
  251   double k = ( dy * v2.
x() - dx * v2.
y() ) / d;
 
  253   intersection = 
QgsPoint( p1.
x() + v1.
x() * k, p1.
y() + v1.
y() * k );
 
  263   isIntersection = 
false;
 
  282   isIntersection = 
true;
 
  283   if ( acceptImproperIntersection )
 
  285     if ( ( p1 == q1 ) || ( p1 == q2 ) )
 
  287       intersectionPoint = p1;
 
  290     else if ( ( p2 == q1 ) || ( p2 == q2 ) )
 
  292       intersectionPoint = p2;
 
  299       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( p1.
x(), p1.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
 
  301       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( p2.
x(), p2.
y(), q1.
x(), q1.
y(), q2.
x(), q2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
 
  303       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( q1.
x(), q1.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance ) ||
 
  305       qgsDoubleNear( 
QgsGeometryUtils::sqrDistToLine( q2.
x(), q2.
y(), p1.
x(), p1.
y(), p2.
x(), p2.
y(), x, y, tolerance ), 0.0, tolerance )
 
  312   double lambdav = 
QgsVector( intersectionPoint.
x() - p1.
x(), intersectionPoint.
y() - p1.
y() ) *  v;
 
  313   if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
 
  316   double lambdaw = 
QgsVector( intersectionPoint.
x() - q1.
x(), intersectionPoint.
y() - q1.
y() ) * w;
 
  317   return !( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance );
 
  327   const double x1 = linePoint1.
x() - center.
x();
 
  328   const double y1 = linePoint1.
y() - center.
y();
 
  329   const double x2 = linePoint2.
x() - center.
x();
 
  330   const double y2 = linePoint2.
y() - center.
y();
 
  331   const double dx = x2 - x1;
 
  332   const double dy = y2 - y1;
 
  334   const double dr2 = std::pow( dx, 2 ) + std::pow( dy, 2 );
 
  335   const double d = x1 * y2 - x2 * y1;
 
  337   const double disc = std::pow( radius, 2 ) * dr2 - std::pow( d, 2 );
 
  347     const int sgnDy = dy < 0 ? -1 : 1;
 
  349     const double sqrDisc = std::sqrt( disc );
 
  351     const double ax = center.
x() + ( d * dy + sgnDy * dx * sqrDisc ) / dr2;
 
  352     const double ay = center.
y() + ( -d * dx + std::fabs( dy ) * sqrDisc ) / dr2;
 
  355     const double bx = center.
x() + ( d * dy - sgnDy * dx * sqrDisc ) / dr2;
 
  356     const double by = center.
y() + ( -d * dx - std::fabs( dy ) * sqrDisc ) / dr2;
 
  363       intersection.
set( p1.
x(), p1.
y() );
 
  367       intersection.
set( p2.
x(), p2.
y() );
 
  378   const double d = center1.
distance( center2 );
 
  381   if ( d > ( r1 + r2 ) )
 
  386   else if ( d < std::fabs( r1 - r2 ) )
 
  403   const double a = ( ( r1 * r1 ) - ( r2 * r2 ) + ( d * d ) ) / ( 2.0 * d ) ;
 
  408   const double dx = center2.
x() - center1.
x();
 
  409   const double dy = center2.
y() - center1.
y();
 
  412   const double x2 = center1.
x() + ( dx * a / d );
 
  413   const double y2 = center1.
y() + ( dy * a / d );
 
  418   const double h = std::sqrt( ( r1 * r1 ) - ( a * a ) );
 
  423   const double rx = dy * ( h / d );
 
  424   const double ry = dx * ( h / d );
 
  427   intersection1 = 
QgsPointXY( x2 + rx, y2 - ry );
 
  428   intersection2 = 
QgsPointXY( x2 - rx, y2 +  ry );
 
  442   const double dx = center.
x() - p.
x();
 
  443   const double dy = center.
y() - p.
y();
 
  444   const double distanceSquared = dx * dx + dy * dy;
 
  445   const double radiusSquared = radius * radius;
 
  446   if ( distanceSquared < radiusSquared )
 
  453   const double distanceToTangent = std::sqrt( distanceSquared - radiusSquared );
 
  465   if ( radius1 > radius2 )
 
  468   const double radius2a = radius2 - radius1;
 
  477   QgsVector v1( -( line1P2.
y() - center1.
y() ), line1P2.
x() - center1.
x() );
 
  478   const double v1Length = v1.
length();
 
  479   v1 = v1 * ( radius1 / v1Length );
 
  482   line1P1 = center1 + v1;
 
  483   line1P2 = line1P2 + v1;
 
  487   QgsVector v2( line2P2.
y() - center1.
y(), -( line2P2.
x() - center1.
x() ) );
 
  488   const double v2Length = v2.
length();
 
  489   v2 = v2 * ( radius1 / v2Length );
 
  492   line2P1 = center1 + v2;
 
  493   line2P2 = line2P2 + v2;
 
  501   if ( radius1 > radius2 )
 
  505   const double d = center1.
distance( center2 );
 
  506   const double radius1a = radius1 + radius2;
 
  523   QgsVector v1( ( line1P2.
y() - center2.
y() ), -( line1P2.
x() - center2.
x() ) );
 
  524   const double v1Length = v1.
length();
 
  525   v1 = v1 * ( radius2 / v1Length );
 
  528   line1P1 = center2 + v1;
 
  529   line1P2 = line1P2 + v1;
 
  533   QgsVector v2( -( line2P2.
y() - center2.
y() ), line2P2.
x() - center2.
x() );
 
  534   const double v2Length = v2.
length();
 
  535   v2 = v2 * ( radius2 / v2Length );
 
  538   line2P1 = center2 + v2;
 
  539   line2P2 = line2P2 + v2;
 
  546   QVector<SelfIntersection> intersections;
 
  552   for ( 
int i = 0, j = 1; j < n; i = j++ )
 
  560     int end = i == 0 && isClosed ? n - 1 : n;
 
  561     for ( 
int k = start, l = start + 1; l < end; k = l++ )
 
  567       bool intersection = 
false;
 
  578       intersections.append( s );
 
  581   return intersections;
 
  595   double test = ( f1 * f2 - f3 * f4 );
 
  597   return qgsDoubleNear( test, 0.0 ) ? 0 : ( test < 0 ? -1 : 1 );
 
  607 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 )
 
  609   const double dx = x2 - x1;
 
  610   const double dy = y2 - y1;
 
  611   const double length = std::sqrt( dx * dx + dy * dy );
 
  624     const double scaleFactor = distance / length;
 
  625     x = x1 + dx * scaleFactor;
 
  626     y = y1 + dy * scaleFactor;
 
  628       *z = *z1 + ( *z2 - *z1 ) * scaleFactor;
 
  630       *m = *m1 + ( *m2 - *m1 ) * scaleFactor;
 
  637   const double mX = x1 + ( x2 - x1 ) * proportion;
 
  638   const double mY = y1 + ( y2 - y1 ) * proportion;
 
  639   const double pX = x1 - x2;
 
  640   const double pY = y1 - y2;
 
  641   double normalX = -pY;
 
  643   const double normalLength = sqrt( ( normalX * normalX ) + ( normalY * normalY ) );  
 
  644   normalX /= normalLength;
 
  645   normalY /= normalLength;  
 
  647   *x = mX + offset * normalX;
 
  648   *y = mY + offset * normalY;  
 
  653   double centerX, centerY, radius;
 
  656   const double theta = distance / radius; 
 
  657   const double anglePt1 = std::atan2( pt1.
y() - centerY, pt1.
x() - centerX );
 
  658   const double anglePt2 = std::atan2( pt2.
y() - centerY, pt2.
x() - centerX );
 
  659   const double anglePt3 = std::atan2( pt3.
y() - centerY, pt3.
x() - centerX );
 
  661   const double angleDest = anglePt1 + ( 
isClockwise ? -theta : theta );
 
  663   const double x = centerX + radius * ( std::cos( angleDest ) );
 
  664   const double y = centerY + radius * ( std::sin( angleDest ) );
 
  666   const double z = pt1.
is3D() ?
 
  678   double angle = std::atan2( dy, dx ) * 180 / M_PI;
 
  683   else if ( 
angle > 360 )
 
  692   double dx21, dy21, dx31, dy31, h21, h31, d;
 
  697     centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
 
  698     centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
 
  699     radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
 
  704   dx21 = pt2.
x() - pt1.
x();
 
  705   dy21 = pt2.
y() - pt1.
y();
 
  706   dx31 = pt3.
x() - pt1.
x();
 
  707   dy31 = pt3.
y() - pt1.
y();
 
  709   h21 = std::pow( dx21, 2.0 ) + std::pow( dy21, 2.0 );
 
  710   h31 = std::pow( dx31, 2.0 ) + std::pow( dy31, 2.0 );
 
  713   d = 2 * ( dx21 * dy31 - dx31 * dy21 );
 
  723   centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
 
  724   centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
 
  725   radius = std::sqrt( std::pow( centerX - pt1.
x(), 2.0 ) + std::pow( centerY - pt1.
y(), 2.0 ) );
 
  730   if ( angle3 >= angle1 )
 
  732     return !( angle2 > angle1 && angle2 < angle3 );
 
  736     return !( angle2 > angle1 || angle2 < angle3 );
 
  744     if ( angle2 < angle1 )
 
  746       return ( angle <= angle1 && angle >= angle2 );
 
  750       return ( angle <= angle1 || angle >= angle2 );
 
  755     if ( angle2 > angle1 )
 
  757       return ( 
angle >= angle1 && 
angle <= angle2 );
 
  761       return ( 
angle >= angle1 || 
angle <= angle2 );
 
  774   double centerX, centerY, radius;
 
  776   double length = M_PI / 180.0 * radius * 
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
 
  790   if ( p3Angle >= p1Angle )
 
  792     if ( p2Angle > p1Angle && p2Angle < p3Angle )
 
  794       return ( p3Angle - p1Angle );
 
  798       return ( - ( p1Angle + ( 360 - p3Angle ) ) );
 
  803     if ( p2Angle < p1Angle && p2Angle > p3Angle )
 
  805       return ( -( p1Angle - p3Angle ) );
 
  809       return ( p3Angle + ( 360 - p1Angle ) );
 
  816   QgsPoint midPoint( ( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
 
  818   if ( radius < midDist )
 
  822   double centerMidDist = std::sqrt( radius * radius - midDist * midDist );
 
  823   double dist = radius - centerMidDist;
 
  825   double midDx = midPoint.
x() - p1.
x();
 
  826   double midDy = midPoint.
y() - p1.
y();
 
  829   QVector<QgsPoint> possibleMidPoints;
 
  836   double minDist = std::numeric_limits<double>::max();
 
  837   int minDistIndex = -1;
 
  838   for ( 
int i = 0; i < possibleMidPoints.size(); ++i )
 
  840     double currentDist = 
sqrDistance2D( mousePos, possibleMidPoints.at( i ) );
 
  841     if ( currentDist < minDist )
 
  844       minDist = currentDist;
 
  848   if ( minDistIndex == -1 )
 
  853   result = possibleMidPoints.at( minDistIndex );
 
  865   if ( !useShortestArc )
 
  866     midPointAngle += M_PI;
 
  867   return center.
project( center.
distance( p1 ), midPointAngle * 180 / M_PI );
 
  874   double mX, mY, radius;
 
  907   double bDistance = std::sqrt( ( b.
x() - centerX ) * ( b.
x() - centerX ) +
 
  908                                 ( b.
y() - centerY ) * ( b.
y() - centerY ) );
 
  910   double diff = std::fabs( radius - bDistance );
 
  914     double abX = b.
x() - a.
x();
 
  915     double abY = b.
y() - a.
y();
 
  917     double cbX = b.
x() - 
c.x();
 
  918     double cbY = b.
y() - 
c.y();
 
  920     double dot = ( abX * cbX + abY * cbY ); 
 
  921     double cross = ( abX * cbY - abY * cbX ); 
 
  923     double alpha = std::atan2( cross, dot );
 
  929   if ( diff < distanceTolerance )
 
  931     double angle1 = arcAngle( a1, a2, a3 );
 
  932     double angle2 = arcAngle( a2, a3, b );
 
  937     diff = std::fabs( angle1 - angle2 );
 
  938     if ( diff > pointSpacingAngleTolerance )
 
  948     if ( bSide != a2Side )
 
  956   bool reversed = 
false;
 
  980   circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY );
 
  982   if ( circlePoint1 != circlePoint3 && ( radius < 0 || 
qgsDoubleNear( segSide, 0.0 ) ) ) 
 
  990   double increment = tolerance; 
 
  994     tolerance = std::min( tolerance, radius * 2 );
 
  995     double halfAngle = std::acos( -tolerance / radius + 1 );
 
  996     increment = 2 * halfAngle;
 
 1000   double a1 = std::atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
 
 1001   double a2 = std::atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
 
 1002   double a3 = std::atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
 
 1005   const bool symmetric = 
true;
 
 1008     double angle = a3 - a1;
 
 1013     int segs = ceil( 
angle / increment );
 
 1015     increment = 
angle / segs;
 
 1029   QVector<QgsPoint> stringPoints;
 
 1030   stringPoints.insert( 0, circlePoint1 );
 
 1031   if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) 
 
 1045     double tolError = increment / 100;
 
 1046     double stopAngle = a3 - tolError;
 
 1047     for ( 
double angle = a1 + increment; 
angle < stopAngle; 
angle += increment )
 
 1049       x = centerX + radius * std::cos( 
angle );
 
 1050       y = centerY + radius * std::sin( 
angle );
 
 1061       stringPoints.insert( stringPoints.size(), 
QgsPoint( pointWkbType, x, y, z, m ) );
 
 1064   stringPoints.insert( stringPoints.size(), circlePoint3 );
 
 1069     std::reverse( stringPoints.begin(), stringPoints.end() );
 
 1071   if ( ! points.empty() && stringPoints.front() == points.back() ) stringPoints.pop_front();
 
 1072   points.append( stringPoints );
 
 1077   double side = ( ( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
 
 1102       return zm1 + ( zm2 - zm1 ) * ( 
angle - a1 ) / ( a2 - a1 );
 
 1104       return zm2 + ( zm3 - zm2 ) * ( 
angle - a2 ) / ( a3 - a2 );
 
 1110       return zm1 + ( zm2 - zm1 ) * ( a1 - 
angle ) / ( a1 - a2 );
 
 1112       return zm2 + ( zm3 - zm2 ) * ( a2 - 
angle ) / ( a2 - a3 );
 
 1118   int dim = 2 + is3D + isMeasure;
 
 1121 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
 1122   const QStringList coordList = wktCoordinateList.split( 
',', QString::SkipEmptyParts );
 
 1124   const QStringList coordList = wktCoordinateList.split( 
',', Qt::SkipEmptyParts );
 
 1128   bool foundZ = 
false;
 
 1129   bool foundM = 
false;
 
 1130   QRegularExpression rx( QStringLiteral( 
"\\s" ) );
 
 1131   QRegularExpression rxIsNumber( QStringLiteral( 
"^[+-]?(\\d\\.?\\d*[Ee][+\\-]?\\d+|(\\d+\\.\\d*|\\d*\\.\\d+)|\\d+)$" ) );
 
 1132   for ( 
const QString &pointCoordinates : coordList )
 
 1134 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
 1135     QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
 
 1137     QStringList coordinates = pointCoordinates.split( rx, Qt::SkipEmptyParts );
 
 1141     if ( coordinates.filter( rxIsNumber ).size() != coordinates.size() )
 
 1144     if ( coordinates.size() == 3 && !foundZ && !foundM && !is3D && !isMeasure )
 
 1150     else if ( coordinates.size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
 
 1159   for ( 
const QString &pointCoordinates : coordList )
 
 1161 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
 1162     QStringList coordinates = pointCoordinates.split( rx, QString::SkipEmptyParts );
 
 1164     QStringList coordinates = pointCoordinates.split( rx, Qt::SkipEmptyParts );
 
 1166     if ( coordinates.size() < dim )
 
 1170     double x = coordinates[idx++].toDouble();
 
 1171     double y = coordinates[idx++].toDouble();
 
 1174     if ( ( is3D || foundZ ) && coordinates.length() > idx )
 
 1175       z = coordinates[idx++].toDouble();
 
 1178     if ( ( isMeasure || foundM ) && coordinates.length() > idx )
 
 1179       m = coordinates[idx++].toDouble();
 
 1182     if ( is3D || foundZ )
 
 1184       if ( isMeasure || foundM )
 
 1191       if ( isMeasure || foundM )
 
 1197     points.append( 
QgsPoint( t, x, y, z, m ) );
 
 1205   wkb << static_cast<quint32>( points.size() );
 
 1206   for ( 
const QgsPoint &point : points )
 
 1208     wkb << point.x() << point.y();
 
 1222   QString wkt = QStringLiteral( 
"(" );
 
 1231     wkt += QLatin1String( 
", " );
 
 1233   if ( wkt.endsWith( QLatin1String( 
", " ) ) )
 
 1241   QDomElement elemCoordinates = doc.createElementNS( ns, QStringLiteral( 
"coordinates" ) );
 
 1244   QString cs = QStringLiteral( 
"," );
 
 1246   QString ts = QStringLiteral( 
" " );
 
 1248   elemCoordinates.setAttribute( QStringLiteral( 
"cs" ), cs );
 
 1249   elemCoordinates.setAttribute( QStringLiteral( 
"ts" ), ts );
 
 1251   QString strCoordinates;
 
 1254     if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
 
 1259   if ( strCoordinates.endsWith( ts ) )
 
 1260     strCoordinates.chop( 1 ); 
 
 1262   elemCoordinates.appendChild( doc.createTextNode( strCoordinates ) );
 
 1263   return elemCoordinates;
 
 1268   QDomElement elemPosList = doc.createElementNS( ns, QStringLiteral( 
"posList" ) );
 
 1269   elemPosList.setAttribute( QStringLiteral( 
"srsDimension" ), is3D ? 3 : 2 );
 
 1271   QString strCoordinates;
 
 1274     if ( axisOrder == QgsAbstractGeometry::AxisOrder::XY )
 
 1281   if ( strCoordinates.endsWith( 
' ' ) )
 
 1282     strCoordinates.chop( 1 ); 
 
 1284   elemPosList.appendChild( doc.createTextNode( strCoordinates ) );
 
 1290   QString json = QStringLiteral( 
"[ " );
 
 1295   if ( json.endsWith( QLatin1String( 
", " ) ) )
 
 1306   json coordinates( json::array() );
 
 1323   double clippedAngle = 
angle;
 
 1324   if ( clippedAngle >= M_PI * 2 || clippedAngle <= -2 * M_PI )
 
 1326     clippedAngle = std::fmod( clippedAngle, 2 * M_PI );
 
 1328   if ( clippedAngle < 0.0 )
 
 1330     clippedAngle += 2 * M_PI;
 
 1332   return clippedAngle;
 
 1337   QString wktParsed = wkt;
 
 1339   if ( wkt.contains( QString( 
"EMPTY" ), Qt::CaseInsensitive ) )
 
 1341     QRegularExpression wktRegEx( QStringLiteral( 
"^\\s*(\\w+)\\s+(\\w+)\\s*$" ) );
 
 1342     wktRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
 
 1343     QRegularExpressionMatch match = wktRegEx.match( wkt );
 
 1344     if ( match.hasMatch() )
 
 1346       wktParsed = match.captured( 1 );
 
 1347       contents = match.captured( 2 ).toUpper();
 
 1352     const int openedParenthesisCount = wktParsed.count( 
'(' );
 
 1353     const int closedParenthesisCount = wktParsed.count( 
')' );
 
 1355     for ( 
int i = 0 ;  i < openedParenthesisCount - closedParenthesisCount; ++i )
 
 1356       wktParsed.push_back( 
')' );
 
 1358     wktParsed.truncate( wktParsed.size() - ( closedParenthesisCount - openedParenthesisCount ) );
 
 1360     QRegularExpression cooRegEx( QStringLiteral( 
"^[^\\(]*\\((.*)\\)[^\\)]*$" ) );
 
 1361     cooRegEx.setPatternOptions( QRegularExpression::DotMatchesEverythingOption );
 
 1362     QRegularExpressionMatch match = cooRegEx.match( wktParsed );
 
 1363     contents = match.hasMatch() ? match.captured( 1 ) : QString();
 
 1366   return qMakePair( wkbType, contents );
 
 1374   for ( 
int i = 0, n = wkt.length(); i < n; ++i )
 
 1376     if ( ( wkt[i].isSpace() || wkt[i] == 
'\n' || wkt[i] == 
'\t' ) && level == 0 )
 
 1379     if ( wkt[i] == 
',' && level == 0 )
 
 1381       if ( !block.isEmpty() )
 
 1383         if ( block.startsWith( 
'(' ) && !defaultType.isEmpty() )
 
 1384           block.prepend( defaultType + 
' ' );
 
 1385         blocks.append( block );
 
 1390     if ( wkt[i] == 
'(' )
 
 1392     else if ( wkt[i] == 
')' )
 
 1396   if ( !block.isEmpty() )
 
 1398     if ( block.startsWith( 
'(' ) && !defaultType.isEmpty() )
 
 1399       block.prepend( defaultType + 
' ' );
 
 1400     blocks.append( block );
 
 1408   if ( x <= left && y <= bottom )
 
 1410     const double dx = left - x;
 
 1411     const double dy = bottom - y;
 
 1419   else if ( x >= right && y >= top )
 
 1421     const double dx = x - right;
 
 1422     const double dy = y - top;
 
 1430   else if ( x >= right && y <= bottom )
 
 1432     const double dx = x - right;
 
 1433     const double dy = bottom - y;
 
 1441   else if ( x <= left && y >= top )
 
 1443     const double dx = left - x;
 
 1444     const double dy = y - top;
 
 1452   else if ( x <= left )
 
 1454   else if ( x >= right )
 
 1456   else if ( y <= bottom )
 
 1458   else if ( y >= top )
 
 1462   const double smallestX = std::min( right - x, x - left );
 
 1463   const double smallestY = std::min( top - y, y - bottom );
 
 1464   if ( smallestX < smallestY )
 
 1467     if ( right - x < x - left )
 
 1475     if ( top - y < y - bottom )
 
 1487   double x = ( pt1.
x() + pt2.
x() ) / 2.0;
 
 1488   double y = ( pt1.
y() + pt2.
y() ) / 2.0;
 
 1489   double z = std::numeric_limits<double>::quiet_NaN();
 
 1490   double m = std::numeric_limits<double>::quiet_NaN();
 
 1495     z = ( pt1.
z() + pt2.
z() ) / 2.0;
 
 1501     m = ( pt1.
m() + pt2.
m() ) / 2.0;
 
 1504   return QgsPoint( pType, x, y, z, m );
 
 1509   const double _fraction = 1 - fraction;
 
 1511                    p1.
x() * _fraction + p2.
x() * fraction,
 
 1512                    p1.
y() * _fraction + p2.
y() * fraction,
 
 1513                    p1.
is3D() ? p1.
z() * _fraction + p2.
z() * fraction : std::numeric_limits<double>::quiet_NaN(),
 
 1514                    p1.
isMeasure() ? p1.
m() * _fraction + p2.
m() * fraction : std::numeric_limits<double>::quiet_NaN() );
 
 1519   const double deltaX = ( x2 - x1 ) * fraction;
 
 1520   const double deltaY = ( y2 - y1 ) * fraction;
 
 1521   return QgsPointXY( x1 + deltaX, y1 + deltaY );
 
 1529   const double fraction = ( value - v1 ) / ( v2 - v1 );
 
 1535   double delta_x = pt2.
x() - pt1.
x();
 
 1536   double delta_y = pt2.
y() - pt1.
y();
 
 1542   return delta_y / delta_x;
 
 1561     a = pt1.
y() - pt2.
y();
 
 1562     b = pt2.
x() - pt1.
x();
 
 1563     c = pt1.
x() * pt2.
y() - pt1.
y() * pt2.
x();
 
 1573   if ( ( p == s1 ) || ( p == s2 ) )
 
 1591     double y = ( -
c - a * p.
x() ) / b;
 
 1593     double d2 = 1 + m * m;
 
 1594     double H = p.
y() - y;
 
 1595     double dx = m * H / d2;
 
 1608   double at = std::atan2( y2 - y1, x2 - x1 );
 
 1609   double a = -at + M_PI_2;
 
 1615   double angle1 = std::atan2( y1 - y2, x1 - x2 );
 
 1616   double angle2 = std::atan2( y3 - y2, x3 - x2 );
 
 1630   double a1 = 
lineAngle( x1, y1, x2, y2 );
 
 1631   double a2 = 
lineAngle( x2, y2, x3, y3 );
 
 1639   double clockwiseDiff = 0.0;
 
 1642     clockwiseDiff = a2 - a1;
 
 1646     clockwiseDiff = a2 + ( 2 * M_PI - a1 );
 
 1648   double counterClockwiseDiff = 2 * M_PI - clockwiseDiff;
 
 1650   double resultAngle = 0;
 
 1651   if ( clockwiseDiff <= counterClockwiseDiff )
 
 1653     resultAngle = a1 + clockwiseDiff / 2.0;
 
 1657     resultAngle = a1 - counterClockwiseDiff / 2.0;
 
 1668   if ( u3.
length() == 0 ) 
return 1;
 
 1685   if ( std::fabs( u3.
x() ) <= epsilon &&
 
 1686        std::fabs( u3.
y() ) <= epsilon &&
 
 1687        std::fabs( u3.
z() ) <= epsilon )
 
 1699   if ( !( std::fabs( b1 ) > epsilon ) )
 
 1704   if ( !( a2 != -1 && a2 != 1 ) )
 
 1710   double r1 = ( c2 - b2 * c1 / b1 ) / ( a2 - b2 * a1 / b1 );
 
 1726     bool isIntersection;
 
 1735     intersection.
set( ptInter.
x(), ptInter.
y(), La1.
z() );
 
 1775   if ( !firstIsDone || !secondIsDone )
 
 1781   intersection = ( X1 + X2 ) / 2.0;
 
 1787   return 0.5 * std::abs( ( aX - cX ) * ( bY - aY ) - ( aX - bX ) * ( cY - aY ) );
 
 1791     double weightB, 
double weightC, 
double &pointX, 
double &pointY )
 
 1794   if ( weightB + weightC > 1 )
 
 1796     weightB = 1 - weightB;
 
 1797     weightC = 1 - weightC;
 
 1800   const double rBx = weightB * ( bX - aX );
 
 1801   const double rBy = weightB * ( bY - aY );
 
 1802   const double rCx = weightC * ( cX - aX );
 
 1803   const double rCy = weightC * ( cY - aY );
 
 1805   pointX = rBx + rCx + aX;
 
 1806   pointY = rBy + rCy + aY;
 
 1813   for ( 
const QgsPoint &pt : points )
 
 1815     if ( pt.isMeasure() )
 
 1818       point.
setM( pt.m() );
 
 1831   for ( 
const QgsPoint &pt : points )
 
 1836       point.
setZ( pt.z() );
 
 1855   bool intersection = 
false;
 
 1861   return intersection;
 
 1873   bool intersection = 
false;
 
 1879   return intersection;
 
Abstract base class for all geometries.
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
@ MaximumDifference
Maximum distance between an arbitrary point on the original curve and closest point on its approximat...
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual int vertexCount(int part=0, int ring=0) const =0
Returns the number of vertices of which this geometry is built.
AxisOrder
Axis order for GML generation.
virtual QgsPoint vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.
virtual bool isEmpty() const
Returns true if the geometry is empty.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
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.
Curve polygon geometry type.
Abstract base class for curved geometry type.
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 circleTangentDirection(const QgsPoint &tangentPoint, const QgsPoint &cp1, const QgsPoint &cp2, const QgsPoint &cp3) SIP_HOLDGIL
Calculates the direction angle of a circle tangent (clockwise from north in radians)
static QString pointsToJSON(const QgsPointSequence &points, int precision)
Returns a geoJSON coordinates string.
static QgsPoint midpoint(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns a middle point between points pt1 and pt2.
static bool bisector(double aX, double aY, double bX, double bY, double cX, double cY, double &pointX, double &pointY) SIP_HOLDGIL
Returns the point (pointX, pointY) forming the bisector from point (aX, aY) to the segment (bX,...
static double sqrDistance2D(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns the squared 2D distance between two points.
static bool skewLinesProjection(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22, QgsVector3D &X1, double epsilon=0.0001) SIP_HOLDGIL
A method to project one skew line onto another.
static double ccwAngle(double dy, double dx) SIP_HOLDGIL
Returns the counter clockwise angle between a line with components dx, dy and the line with dx > 0 an...
static double triangleArea(double aX, double aY, double bX, double bY, double cX, double cY) SIP_HOLDGIL
Returns the area of the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static bool segmentMidPoint(const QgsPoint &p1, const QgsPoint &p2, QgsPoint &result, double radius, const QgsPoint &mousePos) SIP_HOLDGIL
Calculates midpoint on circle passing through p1 and p2, closest to the given coordinate mousePos.
static json pointsToJson(const QgsPointSequence &points, int precision)
Returns coordinates as json object.
static int circleCircleInnerTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) SIP_HOLDGIL
Calculates the inner tangent points for two circles, centered at center1 and center2 and with radii o...
static QVector< QgsLineString * > extractLineStrings(const QgsAbstractGeometry *geom)
Returns list of linestrings extracted from the passed geometry.
static bool lineIntersection(const QgsPoint &p1, QgsVector v1, const QgsPoint &p2, QgsVector v2, QgsPoint &intersection) SIP_HOLDGIL
Computes the intersection between two lines.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
static double normalizedAngle(double angle) SIP_HOLDGIL
Ensures that an angle is in the range 0 <= angle < 2 pi.
static QgsPointXY interpolatePointOnLineByValue(double x1, double y1, double v1, double x2, double y2, double v2, double value) SIP_HOLDGIL
Interpolates the position of a point along the line from (x1, y1) to (x2, y2).
static QVector< SelfIntersection > selfIntersections(const QgsAbstractGeometry *geom, int part, int ring, double tolerance)
Find self intersections in a polyline.
static bool transferFirstZValueToPoint(const QgsPointSequence &points, QgsPoint &point)
A Z dimension is added to point if one of the point in the list points is in 3D.
static QgsPoint closestPoint(const QgsAbstractGeometry &geometry, const QgsPoint &point)
Returns the nearest point on a segment of a geometry for the specified point.
static int segmentSide(const QgsPoint &pt1, const QgsPoint &pt3, const QgsPoint &pt2) SIP_HOLDGIL
For line defined by points pt1 and pt3, find out on which side of the line is point pt3.
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 QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType=QString())
Parses a WKT string and returns of list of blocks contained in the WKT.
static QgsPoint segmentMidPointFromCenter(const QgsPoint &p1, const QgsPoint &p2, const QgsPoint ¢er, bool useShortestArc=true) SIP_HOLDGIL
Calculates the midpoint on the circle passing through p1 and p2, with the specified center coordinate...
static bool lineCircleIntersection(const QgsPointXY ¢er, double radius, const QgsPointXY &linePoint1, const QgsPointXY &linePoint2, QgsPointXY &intersection) SIP_HOLDGIL
Compute the intersection of a line and a circle.
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) SIP_HOLDGIL
Compute the intersection between two segments.
static void circleCenterRadius(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double &radius, double ¢erX, double ¢erY) SIP_HOLDGIL
Returns radius and center of the circle through pt1, pt2, pt3.
static double distanceToVertex(const QgsAbstractGeometry &geom, QgsVertexId id)
Returns the distance along a geometry from its first vertex to the specified vertex.
static double skewLinesDistance(const QgsVector3D &P1, const QgsVector3D &P12, const QgsVector3D &P2, const QgsVector3D &P22) SIP_HOLDGIL
An algorithm to calculate the shortest distance between two skew lines.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates the average angle (in radians) between the two linear segments from (x1,...
static bool angleOnCircle(double angle, double angle1, double angle2, double angle3) SIP_HOLDGIL
Returns true if an angle is between angle1 and angle3 on a circle described by angle1,...
static double lineAngle(double x1, double y1, double x2, double y2) SIP_HOLDGIL
Calculates the direction of line joining two points in radians, clockwise from the north direction.
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon) SIP_HOLDGIL
Returns the squared distance between a point and a line.
static void perpendicularOffsetPointAlongSegment(double x1, double y1, double x2, double y2, double proportion, double offset, double *x, double *y)
Calculates a point a certain proportion of the way along the segment from (x1, y1) to (x2,...
static bool circleClockwise(double angle1, double angle2, double angle3) SIP_HOLDGIL
Returns true if the circle defined by three angles is ordered clockwise.
static bool angleBisector(double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double &pointX, double &pointY, double &angle) SIP_HOLDGIL
Returns the point (pointX, pointY) forming the bisector from segment (aX aY) (bX bY) and segment (bX,...
static int circleCircleOuterTangents(const QgsPointXY ¢er1, double radius1, const QgsPointXY ¢er2, double radius2, QgsPointXY &line1P1, QgsPointXY &line1P2, QgsPointXY &line2P1, QgsPointXY &line2P2) SIP_HOLDGIL
Calculates the outer tangent points for two circles, centered at center1 and center2 and with radii o...
static bool transferFirstMValueToPoint(const QgsPointSequence &points, QgsPoint &point)
A M dimension is added to point if one of the points in the list points contains an M value.
static double gradient(const QgsPoint &pt1, const QgsPoint &pt2) SIP_HOLDGIL
Returns the gradient of a line defined by points pt1 and pt2.
static int circleCircleIntersections(QgsPointXY center1, double radius1, QgsPointXY center2, double radius2, QgsPointXY &intersection1, QgsPointXY &intersection2) SIP_HOLDGIL
Calculates the intersections points between the circle with center center1 and radius radius1 and the...
static double sweepAngle(double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates angle of a circular string part defined by pt1, pt2, pt3.
static double angleBetweenThreePoints(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Calculates the angle between the lines AB and BC, where AB and BC described by points a,...
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
static double interpolateArcValue(double angle, double a1, double a2, double a3, double zm1, double zm2, double zm3) SIP_HOLDGIL
Interpolate a value at given angle on circular arc given values (zm1, zm2, zm3) at three different an...
static double circleLength(double x1, double y1, double x2, double y2, double x3, double y3) SIP_HOLDGIL
Length of a circular string segment defined by pt1, pt2, pt3.
static QgsLineString perpendicularSegment(const QgsPoint &p, const QgsPoint &s1, const QgsPoint &s2) SIP_HOLDGIL
Create a perpendicular line segment from p to segment [s1, s2].
static void coefficients(const QgsPoint &pt1, const QgsPoint &pt2, double &a, double &b, double &c) SIP_HOLDGIL
Returns the coefficients (a, b, c for equation "ax + by + c = 0") of a line defined by points pt1 and...
static double linePerpendicularAngle(double x1, double y1, double x2, double y2) SIP_HOLDGIL
Calculates the perpendicular angle to a line joining two points.
static bool tangentPointAndCircle(const QgsPointXY ¢er, double radius, const QgsPointXY &p, QgsPointXY &pt1, QgsPointXY &pt2) SIP_HOLDGIL
Calculates the tangent points between the circle with the specified center and radius and the point p...
static QgsPoint pointOnLineWithDistance(const QgsPoint &startPoint, const QgsPoint &directionPoint, double distance) SIP_HOLDGIL
Returns a point a specified distance toward a second point.
static int closestSideOfRectangle(double right, double bottom, double left, double top, double x, double y)
Returns a number representing the closest side of a rectangle defined by /a right,...
static bool pointContinuesArc(const QgsPoint &a1, const QgsPoint &a2, const QgsPoint &a3, const QgsPoint &b, double distanceTolerance, double pointSpacingAngleTolerance) SIP_HOLDGIL
Returns true if point b is on the arc formed by points a1, a2, and a3, but not within that arc portio...
static void weightedPointInTriangle(double aX, double aY, double bX, double bY, double cX, double cY, double weightB, double weightC, double &pointX, double &pointY) SIP_HOLDGIL
Returns a weighted point inside the triangle denoted by the points (aX, aY), (bX, bY) and (cX,...
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
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 bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise) SIP_HOLDGIL
Returns true if, in a circle, angle is between angle1 and angle2.
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.
static bool transferFirstZOrMValueToPoint(Iterator verticesBegin, Iterator verticesEnd, QgsPoint &point)
A Z or M dimension is added to point if one of the points in the list points contains Z or M value.
static QgsPoint interpolatePointOnArc(const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, double distance) SIP_HOLDGIL
Interpolates a point on an arc defined by three points, pt1, pt2 and pt3.
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.
static bool linesIntersection3D(const QgsVector3D &La1, const QgsVector3D &La2, const QgsVector3D &Lb1, const QgsVector3D &Lb2, QgsVector3D &intersection) SIP_HOLDGIL
An algorithm to calculate an (approximate) intersection of two lines in 3D.
static int leftOfLine(const double x, const double y, const double x1, const double y1, const double x2, const double y2) SIP_HOLDGIL
Returns a value < 0 if the point (x, y) is left of the line from (x1, y1) -> (x2, y2).
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
static QgsPointXY interpolatePointOnLine(double x1, double y1, double x2, double y2, double fraction) SIP_HOLDGIL
Interpolates the position of a point a fraction of the way along the line from (x1,...
Line string geometry type, with support for z-dimension and m-values.
void addVertex(const QgsPoint &pt)
Adds a new vertex to the end of the line string.
A class to represent a 2D point.
void set(double x, double y) SIP_HOLDGIL
Sets the x and y value of the point.
double sqrDist(double x, double y) const SIP_HOLDGIL
Returns the squared distance between this point a specified x, y coordinate.
double distance(double x, double y) const SIP_HOLDGIL
Returns the distance between this point and a specified x, y coordinate.
Point geometry type, with support for z-dimension and m-values.
double distance(double x, double y) const SIP_HOLDGIL
Returns the Cartesian 2D distance between this point and a specified x, y coordinate.
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
QgsPoint project(double distance, double azimuth, double inclination=90.0) const SIP_HOLDGIL
Returns a new point which corresponds to this point projected by a specified distance with specified ...
bool convertTo(QgsWkbTypes::Type type) override
Converts the geometry to a specified type.
void setZ(double z) SIP_HOLDGIL
Sets the point's z-coordinate.
double azimuth(const QgsPoint &other) const SIP_HOLDGIL
Calculates Cartesian azimuth between this point and other one (clockwise in degree,...
void setM(double m) SIP_HOLDGIL
Sets the point's m-value.
double y() const
Returns Y coordinate.
double z() const
Returns Z coordinate.
static double dotProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the dot product of two vectors.
double x() const
Returns X coordinate.
void normalize()
Normalizes the current vector in place.
static QgsVector3D crossProduct(const QgsVector3D &v1, const QgsVector3D &v2)
Returns the cross product of two vectors.
void set(double x, double y, double z)
Sets vector coordinates.
double length() const
Returns the length of the vector.
A class to represent a vector.
double y() const SIP_HOLDGIL
Returns the vector's y-component.
double x() const SIP_HOLDGIL
Returns the vector's x-component.
double length() const SIP_HOLDGIL
Returns the length of the vector.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Type
The WKB type describes the number of dimensions a geometry has.
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
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)
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 qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
double qgsRound(double number, int places)
Returns a double number, rounded (as close as possible) to the specified number of places.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
const double DEFAULT_SEGMENT_EPSILON
Default snapping tolerance for segments.
QVector< QgsPoint > QgsPointSequence
bool isClockwise(std::array< Direction, 4 > dirs)
Checks whether the 4 directions in dirs make up a clockwise rectangle.
Utility class for identifying a unique vertex within a geometry.
VertexType type
Vertex type.
bool isValid() const SIP_HOLDGIL
Returns true if the vertex id is valid.