39   : mGeometry( geometry.constGet() )
 
   66   double dx = p2.
x() - p1.
x();
 
   67   double dy = p2.
y() - p1.
y();
 
   68   if ( ( dx == 0.0 ) && ( dy == 0.0 ) )
 
   70   if ( fabs( dx ) >= fabs( dy ) )
 
   72     double dev = fabs( dy ) / fabs( dx );
 
   79     double dev = fabs( dx ) / fabs( dy );
 
   97   std::array<Direction, 5> dirs;
 
  104   while ( current != end )
 
  114     else if ( dir != dirs[idx - 1] )
 
  124   ret.first = ( idx == 5 ) ? ( dirs[0] == dirs[4] ) : ( idx == 4 );
 
  125   std::copy( dirs.begin(), dirs.begin() + 4, ret.second.begin() );
 
  131   int idx = std::find( oriented.begin(), oriented.end(), dirs[0] ) - oriented.begin();
 
  132   for ( 
int i = 1; i < 4; ++i )
 
  134     if ( dirs[i] != oriented[( idx + i ) % 4] )
 
  165   const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( mGeometry );
 
  170   if ( vertexCount < 4 )
 
  172   else if ( simpleRectanglesOnly && ( vertexCount != 5 || !polygon->
exteriorRing()->
isClosed() ) )
 
  176   std::array<Direction, 4> dirs;
 
  177   std::tie( found4Dirs, dirs ) = 
getEdgeDirections( polygon, std::tan( maximumDeviation * M_PI / 180 ) );
 
  191   QVector<QgsLineString *> linesToProcess;
 
  193   const QgsMultiCurve *multiCurve = qgsgeometry_cast< const QgsMultiCurve * >( mGeometry );
 
  196     linesToProcess.reserve( multiCurve->
partCount() );
 
  197     for ( 
int i = 0; i < multiCurve->
partCount(); ++i )
 
  199       linesToProcess << static_cast<QgsLineString *>( multiCurve->
geometryN( i )->
clone() );
 
  203   const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( mGeometry );
 
  206     linesToProcess << static_cast<QgsLineString *>( curve->
segmentize() );
 
  209   std::unique_ptr<QgsMultiPolygon> multipolygon( linesToProcess.size() > 1 ? 
new QgsMultiPolygon() : 
nullptr );
 
  212   if ( !linesToProcess.empty() )
 
  214     std::unique_ptr< QgsLineString > secondline;
 
  215     for ( 
QgsLineString *line : std::as_const( linesToProcess ) )
 
  217       QTransform transform = QTransform::fromTranslate( x, y );
 
  219       secondline.reset( line->reversed() );
 
  220       secondline->transform( transform );
 
  222       line->append( secondline.get() );
 
  223       line->addVertex( line->pointN( 0 ) );
 
  229         multipolygon->addGeometry( polygon );
 
  251     Cell( 
double x, 
double y, 
double h, 
const QgsPolygon *polygon )
 
  255       , d( polygon->pointDistanceToBoundary( x, y ) )
 
  256       , max( d + h * M_SQRT2 )
 
  271 struct GreaterThanByMax
 
  273   bool operator()( 
const Cell *lhs, 
const Cell *rhs )
 
  275     return rhs->max > lhs->max;
 
  279 Cell *getCentroidCell( 
const QgsPolygon *polygon )
 
  287   for ( 
int i = 0, j = len - 1; i < len; j = i++ )
 
  289     double aX = exterior->
xAt( i );
 
  290     double aY = exterior->
yAt( i );
 
  291     double bX = exterior->
xAt( j );
 
  292     double bY = exterior->
yAt( j );
 
  293     double f = aX * bY - bX * aY;
 
  294     x += ( aX + bX ) * f;
 
  295     y += ( aY + bY ) * f;
 
  299     return new Cell( exterior->
xAt( 0 ), exterior->
yAt( 0 ), 0, polygon );
 
  301     return new Cell( x / area, y / area, 0.0, polygon );
 
  306   std::unique_ptr< QgsPolygon > segmentizedPoly;
 
  307   const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( surface );
 
  311     polygon = segmentizedPoly.get();
 
  318   double cellSize = std::min( bounds.
width(), bounds.
height() );
 
  323   double h = cellSize / 2.0;
 
  324   std::priority_queue< Cell *, std::vector<Cell *>, GreaterThanByMax > cellQueue;
 
  331       cellQueue.push( 
new Cell( x + h, y + h, h, polygon ) );
 
  336   std::unique_ptr< Cell > bestCell( getCentroidCell( polygon ) );
 
  339   std::unique_ptr< Cell > bboxCell( 
new Cell( bounds.
xMinimum() + bounds.
width() / 2.0,
 
  342   if ( bboxCell->d > bestCell->d )
 
  344     bestCell = std::move( bboxCell );
 
  347   while ( !cellQueue.empty() )
 
  350     std::unique_ptr< Cell > cell( cellQueue.top() );
 
  352     Cell *currentCell = cell.get();
 
  355     if ( currentCell->d > bestCell->d )
 
  357       bestCell = std::move( cell );
 
  361     if ( currentCell->max - bestCell->d <= 
precision )
 
  365     h = currentCell->h / 2.0;
 
  366     cellQueue.push( 
new Cell( currentCell->x - h, currentCell->y - h, h, polygon ) );
 
  367     cellQueue.push( 
new Cell( currentCell->x + h, currentCell->y - h, h, polygon ) );
 
  368     cellQueue.push( 
new Cell( currentCell->x - h, currentCell->y + h, h, polygon ) );
 
  369     cellQueue.push( 
new Cell( currentCell->x + h, currentCell->y + h, h, polygon ) );
 
  372   distanceFromBoundary = bestCell->d;
 
  374   return QgsPoint( bestCell->x, bestCell->y );
 
  382   if ( distanceFromBoundary )
 
  383     *distanceFromBoundary = std::numeric_limits<double>::max();
 
  385   if ( !mGeometry || mGeometry->
isEmpty() )
 
  391   if ( 
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
 
  393     int numGeom = gc->numGeometries();
 
  396     for ( 
int i = 0; i < numGeom; ++i )
 
  398       const QgsSurface *surface = qgsgeometry_cast< const QgsSurface * >( gc->geometryN( i ) );
 
  402       double dist = std::numeric_limits<double>::max();
 
  404       if ( dist > maxDist )
 
  414     if ( distanceFromBoundary )
 
  415       *distanceFromBoundary = maxDist;
 
  420     const QgsSurface *surface = qgsgeometry_cast< const QgsSurface * >( mGeometry );
 
  424     double dist = std::numeric_limits<double>::max();
 
  429     if ( distanceFromBoundary )
 
  430       *distanceFromBoundary = dist;
 
  441   return lowerThreshold > std::fabs( dotProduct ) || std::fabs( dotProduct ) > upperThreshold;
 
  467   for ( 
int i = 0; i < numPoints; ++i )
 
  469     if ( !isClosed && i == numPoints - 1 )
 
  471     else if ( !isClosed && i == 0 )
 
  480         a = ring->
pointN( numPoints - 1 );
 
  483       if ( i == numPoints - 1 )
 
  492       sum += 2.0 * std::min( std::fabs( dotProduct - 1.0 ), std::min( std::fabs( dotProduct ), std::fabs( dotProduct + 1 ) ) );
 
  502                       double lowerThreshold, 
double upperThreshold )
 
  511   double scale = 2.0 * std::min( p.
length(), q.
length() );
 
  515   double dotProduct = p * q;
 
  524   if ( dotProduct < -M_SQRT1_2 )
 
  529   return new_v.
normalized() * ( 0.1 * dotProduct * scale );
 
  534   double minScore = std::numeric_limits<double>::max();
 
  539   std::unique_ptr< QgsLineString > best( ring->
clone() );
 
  541   QVector< QgsVector >  motions;
 
  542   motions.reserve( numPoints );
 
  544   for ( 
int it = 0; it < iterations; ++it )
 
  552     for ( 
int i = 0; i < numPoints; ++i )
 
  554       if ( isClosed && i == numPoints - 1 )
 
  555         motions << motions.at( 0 ); 
 
  556       else if ( !isClosed && ( i == 0 || i == numPoints - 1 ) )
 
  566           a = ring->
pointN( numPoints - 1 );
 
  569         if ( i == numPoints - 1 )
 
  574         motions << 
calcMotion( a, b, 
c, lowerThreshold, upperThreshold );
 
  581     for ( 
int i = 0; i < numPoints; ++i )
 
  583       ring->
setXAt( i, ring->
xAt( i ) + motions.at( i ).x() );
 
  584       ring->
setYAt( i, ring->
yAt( i ) + motions.at( i ).y() );
 
  587     double newScore = 
squareness( ring, lowerThreshold, upperThreshold );
 
  588     if ( newScore < minScore )
 
  590       best.reset( ring->
clone() );
 
  594     if ( minScore < tolerance )
 
  600   return best.release();
 
  606   std::unique_ptr< QgsAbstractGeometry > segmentizedCopy;
 
  610     geom = segmentizedCopy.get();
 
  616                             maxIterations, tolerance, lowerThreshold, upperThreshold );
 
  625                              maxIterations, tolerance, lowerThreshold, upperThreshold ) );
 
  629                                maxIterations, tolerance, lowerThreshold, upperThreshold ) );
 
  645   double lowerThreshold = std::cos( ( 90 - angleThreshold ) * M_PI / 180.00 );
 
  646   double upperThreshold = std::cos( angleThreshold * M_PI / 180.0 );
 
  648   if ( 
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
 
  650     int numGeom = gc->numGeometries();
 
  651     QVector< QgsAbstractGeometry * > geometryList;
 
  652     geometryList.reserve( numGeom );
 
  653     for ( 
int i = 0; i < numGeom; ++i )
 
  655       geometryList << 
orthogonalizeGeom( gc->geometryN( i ), maxIterations, tolerance, lowerThreshold, upperThreshold );
 
  674   QVector< double > outX;
 
  675   QVector< double > outY;
 
  676   QVector< double > outZ;
 
  677   QVector< double > outM;
 
  678   double multiplier = 1.0 / double( extraNodesPerSegment + 1 );
 
  681   outX.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
 
  682   outY.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
 
  683   bool withZ = ring->
is3D();
 
  685     outZ.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
 
  688     outM.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
 
  701   int extraNodesThisSegment = extraNodesPerSegment;
 
  702   for ( 
int i = 0; i < nPoints - 1; ++i )
 
  705     x2 = ring->
xAt( i + 1 );
 
  707     y2 = ring->
yAt( i + 1 );
 
  711       z2 = ring->
zAt( i + 1 );
 
  716       m2 = ring->
mAt( i + 1 );
 
  726     if ( extraNodesPerSegment < 0 )
 
  729       extraNodesThisSegment = std::floor( std::sqrt( ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) ) / distance );
 
  730       if ( extraNodesThisSegment >= 1 )
 
  731         multiplier = 1.0 / ( extraNodesThisSegment + 1 );
 
  734     for ( 
int j = 0; j < extraNodesThisSegment; ++j )
 
  736       double delta = multiplier * ( j + 1 );
 
  737       xOut = x1 + delta * ( x2 - x1 );
 
  738       yOut = y1 + delta * ( y2 - y1 );
 
  740         zOut = z1 + delta * ( z2 - z1 );
 
  742         mOut = m1 + delta * ( m2 - m1 );
 
  752   outX << ring->
xAt( nPoints - 1 );
 
  753   outY << ring->
yAt( nPoints - 1 );
 
  755     outZ << ring->
zAt( nPoints - 1 );
 
  757     outM << ring->
mAt( nPoints - 1 );
 
  765   std::unique_ptr< QgsAbstractGeometry > segmentizedCopy;
 
  769     geom = segmentizedCopy.get();
 
  783                                         extraNodesPerSegment, distance ) );
 
  787                                           extraNodesPerSegment, distance ) );
 
  807   if ( 
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
 
  809     int numGeom = gc->numGeometries();
 
  810     QVector< QgsAbstractGeometry * > geometryList;
 
  811     geometryList.reserve( numGeom );
 
  812     for ( 
int i = 0; i < numGeom; ++i )
 
  814       geometryList << 
densifyGeometry( gc->geometryN( i ), extraNodesPerSegment );
 
  843   if ( 
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
 
  845     int numGeom = gc->numGeometries();
 
  846     QVector< QgsAbstractGeometry * > geometryList;
 
  847     geometryList.reserve( numGeom );
 
  848     for ( 
int i = 0; i < numGeom; ++i )
 
  875               "line_segment_dist_comparer",
 
  876               "AB must not be collinear with the origin." );
 
  878               "line_segment_dist_comparer",
 
  879               "CD must not be collinear with the origin." );
 
  893     if ( ab.
end() == cd.
end() || oad != oab )
 
  903     if ( cdb == 0 && cda == 0 )
 
  905       return mOrigin.sqrDist( ab.
start() ) < mOrigin.sqrDist( cd.
start() );
 
  907     else if ( cda == cdb || cda == 0 || cdb == 0 )
 
  910       return cdo == cda || cdo == cdb;
 
  926   const bool aIsLeft = a.
x() < mVertex.x();
 
  927   const bool bIsLeft = b.
x() < mVertex.x();
 
  928   if ( aIsLeft != bIsLeft )
 
  933     if ( a.
y() >= mVertex.y() || b.
y() >= mVertex.y() )
 
  935       return b.
y() < a.
y();
 
  939       return a.
y() < b.
y();
 
  971     const int abo = 
segment.pointLeftOfLine( origin );
 
  978       const double distA = ao * direction;
 
  979       const double distB = ( origin - 
segment.end() ) * direction;
 
  981       if ( distA > 0 && distB > 0 )
 
  987         if ( ( distA > 0 ) != ( distB > 0 ) )
 
  988           intersectPoint = origin;
 
  989         else if ( distA > distB ) 
 
  990           intersectPoint = 
segment.start(); 
 
  992           intersectPoint = 
segment.end();
 
 1000     if ( u < 0.0 || 1.0 < u )
 
 1007       intersectPoint = origin + direction * t;
 
 1016   if ( radius1 > radius2 )
 
 1023   QVector<QgsPointXY> points;
 
 1045   std::vector< std::unique_ptr<QgsLineString > > linesToProcess;
 
 1047   const QgsMultiCurve *multiCurve = qgsgeometry_cast< const QgsMultiCurve * >( mGeometry );
 
 1050     for ( 
int i = 0; i < multiCurve->
partCount(); ++i )
 
 1059   const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( mGeometry );
 
 1066   if ( linesToProcess.empty() )
 
 1069     g.mLastError = QStringLiteral( 
"Input geometry was not a curve type geometry" );
 
 1073   QVector<QgsGeometry> bufferedLines;
 
 1074   bufferedLines.reserve( linesToProcess.size() );
 
 1076   for ( std::unique_ptr< QgsLineString > &line : linesToProcess )
 
 1078     QVector<QgsGeometry> parts;
 
 1080     double prevRadius = 0;
 
 1083     std::unique_ptr< double[] > widths = widthFunction( line.get() ) ;
 
 1088       double thisRadius = widths[ i ] / 2.0;
 
 1089       if ( thisRadius > 0 )
 
 1093         QgsCircle circ( thisPoint, thisRadius );
 
 1095         parts << thisCircle;
 
 1104         if ( prevRadius > 0 || thisRadius > 0 )
 
 1106           QVector< QgsPointXY > points = 
generateSegmentCurve( prevPoint, prevRadius, thisPoint, thisRadius );
 
 1107           if ( !points.empty() )
 
 1112             int beforeVertex = 0;
 
 1113             int afterVertex = 0;
 
 1115             double sqrDistPrev = 0;
 
 1116             for ( 
int j = 0; j < points.count(); ++j )
 
 1120               points[j] = sqrDistPrev < sqrDist ? pA : pB;
 
 1123             points.append( points.at( 0 ) );
 
 1125             std::unique_ptr< QgsPolygon > poly = std::make_unique< QgsPolygon >();
 
 1127             if ( poly->area() > 0 )
 
 1132       prevPoint = thisPoint;
 
 1133       prevRadius = thisRadius;
 
 1134       prevCircle = thisCircle;
 
 1146   start = std::fabs( start );
 
 1147   end = std::fabs( end );
 
 1153     std::unique_ptr< double [] > widths( 
new double[ line->nCoordinates() ] );
 
 1155     widths[line->nCoordinates() - 1] = end;
 
 1157     double lineLength = line->length();
 
 1158     double currentLength = 0;
 
 1159     QgsPoint prevPoint = line->pointN( 0 );
 
 1160     for ( 
int i = 1; i < line->nCoordinates() - 1; ++i )
 
 1162       QgsPoint point = line->pointN( i );
 
 1163       double segmentLength = point.
distance( prevPoint );
 
 1164       currentLength += segmentLength;
 
 1165       double lengthFraction = lineLength > 0 ? currentLength / lineLength : 1;
 
 1166       double delta = lengthFraction * ( end - start );
 
 1167       widths[i] = start + delta;
 
 1181     std::unique_ptr< double [] > widths( 
new double[ line->nCoordinates() ] );
 
 1182     for ( 
int i = 0; i < line->nCoordinates(); ++i )
 
 1184       widths[ i ] = line->mAt( i );
 
 1193     const std::function< 
bool( 
const QgsPointXY & ) > &acceptPoint, 
unsigned long seed, 
QgsFeedback *feedback, 
int maxTriesPerPoint )
 
 1196     return QVector< QgsPointXY >();
 
 1208         return QVector< QgsPointXY >();
 
 1216         std::unique_ptr< QgsPolygon > p( qgsgeometry_cast< QgsPolygon * >( ms->
geometryN( i )->
segmentize() ) );
 
 1223     if ( 
const QgsPolygon *poly = qgsgeometry_cast< const QgsPolygon * >( polygon.
constGet() ) )
 
 1229       std::unique_ptr< QgsPolygon > p( qgsgeometry_cast< QgsPolygon * >( polygon.
constGet()->
segmentize() ) );
 
 1235     return QVector< QgsPointXY >();
 
 1237   const QVector<float> triangleData = t.
data();
 
 1238   if ( triangleData.empty() )
 
 1239     return QVector< QgsPointXY >(); 
 
 1242   std::vector< double > cumulativeAreas;
 
 1244   double totalArea = 0;
 
 1245   for ( 
auto it = triangleData.constBegin(); it != triangleData.constEnd(); )
 
 1248       return QVector< QgsPointXY >();
 
 1250     const float aX = *it++;
 
 1252     const float aY = -( *it++ );
 
 1253     const float bX = *it++;
 
 1255     const float bY = -( *it++ );
 
 1256     const float cX = *it++;
 
 1258     const float cY = -( *it++ );
 
 1262     cumulativeAreas.emplace_back( totalArea );
 
 1265   std::random_device rd;
 
 1266   std::mt19937 mt( seed == 0 ? rd() : seed );
 
 1267   std::uniform_real_distribution<> uniformDist( 0, 1 );
 
 1270   auto selectRandomTriangle = [&cumulativeAreas, totalArea]( 
double random )->
int 
 1273     const double target = random * totalArea;
 
 1274     for ( 
auto it = cumulativeAreas.begin(); it != cumulativeAreas.end(); ++it, triangle++ )
 
 1279     Q_ASSERT_X( 
false, 
"QgsInternalGeometryEngine::randomPointsInPolygon", 
"Invalid random triangle index" );
 
 1284   QVector<QgsPointXY> result;
 
 1285   result.reserve( count );
 
 1287   for ( 
int i = 0; i < count; )
 
 1290       return QVector< QgsPointXY >();
 
 1292     const double triangleIndexRnd = uniformDist( mt );
 
 1294     const int triangleIndex = selectRandomTriangle( triangleIndexRnd );
 
 1297     const double weightB = uniformDist( mt );
 
 1298     const double weightC = uniformDist( mt );
 
 1303     const double aX = triangleData.at( triangleIndex * 9 ) + bounds.
xMinimum();
 
 1304     const double aY = -triangleData.at( triangleIndex * 9 + 2 ) + bounds.
yMinimum();
 
 1305     const double bX = triangleData.at( triangleIndex * 9 + 3 ) + bounds.
xMinimum();
 
 1306     const double bY = -triangleData.at( triangleIndex * 9 + 5 ) + bounds.
yMinimum();
 
 1307     const double cX = triangleData.at( triangleIndex * 9 + 6 ) + bounds.
xMinimum();
 
 1308     const double cY = -triangleData.at( triangleIndex * 9 + 8 ) + bounds.
yMinimum();
 
 1312     if ( acceptPoint( candidate ) )
 
 1318     else if ( maxTriesPerPoint != 0 )
 
 1322       if ( tries == maxTriesPerPoint )
 
 1335     double pointSpacingAngleTolerance )
 
 1337   std::unique_ptr< QgsCompoundCurve > out = std::make_unique< QgsCompoundCurve >();
 
 1340   const unsigned int minQuadEdges = 2;
 
 1353     out->addCurve( lineString->
clone() );
 
 1359   QVector< int > edgesInArcs( numEdges + 1, 0 );
 
 1363     double abX = b.x() - a.
x();
 
 1364     double abY = b.y() - a.
y();
 
 1366     double cbX = b.x() - 
c.x();
 
 1367     double cbY = b.y() - 
c.y();
 
 1369     double dot = ( abX * cbX + abY * cbY ); 
 
 1370     double cross = ( abX * cbY - abY * cbX ); 
 
 1372     double alpha = std::atan2( cross, dot );
 
 1387   double centerX = 0.0;
 
 1388   double centerY = 0.0;
 
 1391   while ( i < numEdges - 2 )
 
 1393     unsigned int arcEdges = 0;
 
 1394     double numQuadrants = 0;
 
 1397     bool foundArc = 
false;
 
 1399     a1 = lineString->
pointN( i );
 
 1400     a2 = lineString->
pointN( i + 1 );
 
 1401     a3 = lineString->
pointN( i + 2 );
 
 1404     for ( j = i + 3; j < numEdges + 1; j++ )
 
 1406       b = lineString->
pointN( j );
 
 1413         for ( k = j - 1; k > j - 4; k-- )
 
 1414           edgesInArcs[k] = currentArc;
 
 1434       arcEdges = j - 1 - i;
 
 1435       if ( first.
x() == b.x() && first.
y() == b.y() )
 
 1450         numQuadrants = ( 4 * 
angle ) / ( 2 * M_PI );
 
 1453       if ( arcEdges < minQuadEdges * numQuadrants )
 
 1456         for ( k = j - 1; k >= i; k-- )
 
 1473   int edgeType = edgesInArcs[0];
 
 1475   auto addPointsToCurve = [ lineString, &out ]( 
int start, 
int end, 
int type )
 
 1480       QVector< QgsPoint > points;
 
 1481       for ( 
int j = start; j < end + 2; ++ j )
 
 1483         points.append( lineString->
pointN( j ) );
 
 1485       std::unique_ptr< QgsCurve > straightSegment = std::make_unique< QgsLineString >( points );
 
 1486       out->addCurve( straightSegment.release() );
 
 1491       QVector< QgsPoint > points;
 
 1492       points.append( lineString->
pointN( start ) );
 
 1493       points.append( lineString->
pointN( ( start + end + 1 ) / 2 ) );
 
 1494       points.append( lineString->
pointN( end + 1 ) );
 
 1495       std::unique_ptr< QgsCircularString > curvedSegment = std::make_unique< QgsCircularString >();
 
 1496       curvedSegment->setPoints( points );
 
 1497       out->addCurve( curvedSegment.release() );
 
 1501   for ( 
int i = 1; i < numEdges; i++ )
 
 1503     if ( edgeType != edgesInArcs[i] )
 
 1506       addPointsToCurve( start, end, edgeType );
 
 1508       edgeType = edgesInArcs[i];
 
 1514   addPointsToCurve( start, end, edgeType );
 
 1529     std::unique_ptr< QgsCurvePolygon > result = std::make_unique< QgsCurvePolygon>();
 
 1532                                           distanceTolerance, angleTolerance ).release() );
 
 1536                                             distanceTolerance, angleTolerance ).release() );
 
 1556   if ( 
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
 
 1558     int numGeom = gc->numGeometries();
 
 1559     QVector< QgsAbstractGeometry * > geometryList;
 
 1560     geometryList.reserve( numGeom );
 
 1561     for ( 
int i = 0; i < numGeom; ++i )
 
 1584   area = std::numeric_limits<double>::max();
 
 1586   width = std::numeric_limits<double>::max();
 
 1587   height = std::numeric_limits<double>::max();
 
 1594   std::unique_ptr< QgsAbstractGeometry > hull( engine->convexHull( &mLastError ) );
 
 1605   double totalRotation = 0;
 
 1606   while ( hull->nextVertex( vertexId, pt2 ) )
 
 1609     double rotateAngle = 180.0 / M_PI * currentAngle;
 
 1610     totalRotation += rotateAngle;
 
 1612     QTransform t = QTransform::fromTranslate( pt0.
x(), pt0.
y() );
 
 1613     t.rotate( rotateAngle );
 
 1614     t.translate( -pt0.
x(), -pt0.
y() );
 
 1616     hull->transform( t );
 
 1619     double currentArea = bounds.
width() * bounds.
height();
 
 1620     if ( currentArea  < area )
 
 1624       angle = totalRotation;
 
 1625       width = bounds.
width();
 
 1626       height = bounds.
height();
 
 1632   if ( width > height )
 
 1634     width = minRect.
height();
 
 1635     height = minRect.
width();
 
 1643   if ( 
angle > 180.0 )
 
The vertex_iterator class provides STL-style iterator for vertices.
Abstract base class for all geometries.
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
virtual bool isEmpty() const
Returns true if the geometry is empty.
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
bool isMeasure() const SIP_HOLDGIL
Returns true if the geometry contains m values.
const QgsCurve * interiorRing(int i) const SIP_HOLDGIL
Retrieves an interior ring from the curve polygon.
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
int numInteriorRings() const SIP_HOLDGIL
Returns the number of interior rings contained with the curve polygon.
Abstract base class for curved geometry type.
virtual int numPoints() const =0
Returns the number of points in the curve.
QgsCurve * segmentize(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a geometry without curves.
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
virtual QgsPolygon * toPolygon(unsigned int segments=36) const
Returns a segmented polygon.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
int partCount() const override
Returns count of parts contained in the geometry.
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 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 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 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 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 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).
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometry collectGeometry(const QVector< QgsGeometry > &geometries)
Creates a new multipart geometry from a list of QgsGeometry objects.
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries)
Compute the unary union on a list of geometries.
QgsPointXY closestVertex(const QgsPointXY &point, int &closestVertexIndex, int &previousVertexIndex, int &nextVertexIndex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
Qgis::GeometryOperationResult addPart(const QVector< QgsPointXY > &points, QgsWkbTypes::GeometryType geomType=QgsWkbTypes::UnknownGeometry)
Adds a new part to a the geometry.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
QgsWkbTypes::GeometryType type
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine representing the specified geometry.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::GeometryOperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
QgsInternalGeometryEngine(const QgsGeometry &geometry)
The caller is responsible that the geometry is available and unchanged for the whole lifetime of this...
QgsGeometry poleOfInaccessibility(double precision, double *distanceFromBoundary=nullptr) const
Calculates the approximate pole of inaccessibility for a surface, which is the most distant internal ...
QgsGeometry variableWidthBufferByM(int segments) const
Calculates a variable width buffer using the m-values from a (multi)line geometry.
QgsGeometry extrude(double x, double y) const
Will extrude a line or (segmentized) curve by a given offset and return a polygon representation of i...
QgsGeometry orthogonalize(double tolerance=1.0E-8, int maxIterations=1000, double angleThreshold=15.0) const
Attempts to orthogonalize a line or polygon geometry by shifting vertices to make the geometries angl...
QgsGeometry variableWidthBuffer(int segments, const std::function< std::unique_ptr< double[] >(const QgsLineString *line) > &widthFunction) const
Calculates a variable width buffer for a (multi)curve geometry.
QString lastError() const
Returns an error string referring to the last error encountered.
QgsGeometry orientedMinimumBoundingBox(double &area, double &angle, double &width, double &height) const
Returns the oriented minimum bounding box for the geometry, which is the smallest (by area) rotated r...
QgsGeometry densifyByDistance(double distance) const
Densifies the geometry by adding regularly placed extra nodes inside each segment so that the maximum...
QgsGeometry taperedBuffer(double startWidth, double endWidth, int segments) const
Calculates a tapered width buffer for a (multi)curve geometry.
QgsGeometry densifyByCount(int extraNodesPerSegment) const
Densifies the geometry by adding the specified number of extra nodes within each segment of the geome...
static QVector< QgsPointXY > randomPointsInPolygon(const QgsGeometry &polygon, int count, const std::function< bool(const QgsPointXY &) > &acceptPoint, unsigned long seed=0, QgsFeedback *feedback=nullptr, int maxTriesPerPoint=0)
Returns a list of count random points generated inside a polygon geometry (if acceptPoint is specifie...
QgsGeometry convertToCurves(double distanceTolerance, double angleTolerance) const
Attempts to convert a non-curved geometry into a curved geometry type (e.g.
bool isAxisParallelRectangle(double maximumDeviation, bool simpleRectanglesOnly=false) const
Returns true if the geometry is a polygon that is almost an axis-parallel rectangle.
Represents a single 2D line segment, consisting of a 2D start and end vertex only.
QgsPointXY end() const SIP_HOLDGIL
Returns the segment's end point.
int pointLeftOfLine(const QgsPointXY &point) const SIP_HOLDGIL
Tests if a point is to the left of the line segment.
double endX() const SIP_HOLDGIL
Returns the segment's end x-coordinate.
double endY() const SIP_HOLDGIL
Returns the segment's end y-coordinate.
double startX() const SIP_HOLDGIL
Returns the segment's start x-coordinate.
QgsPointXY start() const SIP_HOLDGIL
Returns the segment's start point.
void reverse() SIP_HOLDGIL
Reverses the line segment, so that the start and end points are flipped.
double startY() const SIP_HOLDGIL
Returns the segment's start y-coordinate.
Line string geometry type, with support for z-dimension and m-values.
bool isClosed() const override SIP_HOLDGIL
Returns true if the curve is closed.
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the line string.
double mAt(int index) const
Returns the m value of the specified node in the line string.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the line string.
int nCoordinates() const override SIP_HOLDGIL
Returns the number of nodes contained in the geometry.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
double zAt(int index) const
Returns the z-coordinate of the specified node in the line string.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
Multi curve geometry collection.
Multi polygon geometry collection.
Multi surface geometry collection.
A class to represent a 2D point.
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 isEmpty() const override SIP_HOLDGIL
Returns true if the geometry is empty.
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
QgsPoint vertexAt(QgsVertexId) const override
Returns the point corresponding to a specified vertex id.
bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const override
Returns next vertex id and coordinates.
void setExteriorRing(QgsCurve *ring) override
Sets the exterior ring of the polygon.
void addInteriorRing(QgsCurve *ring) override
Adds an interior ring to the geometry (takes ownership)
bool intersects(const QgsLineSegment2D &segment, QgsPointXY &intersectPoint) const
Finds the closest intersection point of the ray and a line segment.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Class that takes care of tessellation of polygons into triangles.
QVector< float > data() const
Returns array of triangle vertex data.
void addPolygon(const QgsPolygon &polygon, float extrusionHeight)
Tessellates a triangle and adds its vertex entries to the output data array.
int dataVerticesCount() const
Returns the number of vertices stored in the output data array.
A class to represent a vector.
QgsVector normalized() const SIP_THROW(QgsException)
Returns the vector's normalized (or "unit") vector (ie same angle but length of 1....
double lengthSquared() const SIP_HOLDGIL
Returns the length of the vector.
double crossProduct(QgsVector v) const SIP_HOLDGIL
Returns the 2D cross product of this vector and another vector v.
double length() const SIP_HOLDGIL
Returns the length of the vector.
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
static bool isCurvedType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a curved type or can contain curved geometries.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB 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)
std::unique_ptr< GEOSGeometry, GeosDeleter > unique_ptr
Scoped GEOS pointer.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
bool matchesOrientation(std::array< Direction, 4 > dirs, std::array< Direction, 4 > oriented)
double normalizedDotProduct(const QgsPoint &a, const QgsPoint &b, const QgsPoint &c)
bool isClockwise(std::array< Direction, 4 > dirs)
Checks whether the 4 directions in dirs make up a clockwise rectangle.
QgsAbstractGeometry * densifyGeometry(const QgsAbstractGeometry *geom, int extraNodesPerSegment=1, double distance=1)
std::unique_ptr< QgsCompoundCurve > lineToCurve(const QgsLineString *lineString, double distanceTolerance, double pointSpacingAngleTolerance)
Direction getEdgeDirection(const QgsPoint &p1, const QgsPoint &p2, double maxDev)
Determines the direction of an edge from p1 to p2.
QVector< QgsPointXY > generateSegmentCurve(const QgsPoint ¢er1, const double radius1, const QgsPoint ¢er2, const double radius2)
QgsVector calcMotion(const QgsPoint &a, const QgsPoint &b, const QgsPoint &c, double lowerThreshold, double upperThreshold)
bool dotProductWithinAngleTolerance(double dotProduct, double lowerThreshold, double upperThreshold)
std::pair< bool, std::array< Direction, 4 > > getEdgeDirections(const QgsPolygon *g, double maxDev)
Checks whether the polygon consists of four nearly axis-parallel sides.
double squareness(QgsLineString *ring, double lowerThreshold, double upperThreshold)
QgsAbstractGeometry * orthogonalizeGeom(const QgsAbstractGeometry *geom, int maxIterations, double tolerance, double lowerThreshold, double upperThreshold)
std::unique_ptr< QgsAbstractGeometry > convertGeometryToCurves(const QgsAbstractGeometry *geom, double distanceTolerance, double angleTolerance)
bool isCounterClockwise(std::array< Direction, 4 > dirs)
Checks whether the 4 directions in dirs make up a counter-clockwise rectangle.
QgsLineString * doOrthogonalize(QgsLineString *ring, int iterations, double tolerance, double lowerThreshold, double upperThreshold)
QgsLineString * doDensify(const QgsLineString *ring, int extraNodesPerSegment=-1, double distance=1)
QLineF segment(int index, QRectF rect, double radius)
Utility class for identifying a unique vertex within a geometry.