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.