39 : mGeometry( geometry.constGet() )
58 QVector<QgsLineString *> linesToProcess;
60 const QgsMultiCurve *multiCurve = qgsgeometry_cast< const QgsMultiCurve * >( mGeometry );
63 linesToProcess.reserve( multiCurve->
partCount() );
64 for (
int i = 0; i < multiCurve->
partCount(); ++i )
66 linesToProcess << static_cast<QgsLineString *>( multiCurve->
geometryN( i )->
clone() );
70 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( mGeometry );
73 linesToProcess << static_cast<QgsLineString *>( curve->
segmentize() );
76 std::unique_ptr<QgsMultiPolygon> multipolygon( linesToProcess.size() > 1 ?
new QgsMultiPolygon() :
nullptr );
79 if ( !linesToProcess.empty() )
81 std::unique_ptr< QgsLineString > secondline;
82 for (
QgsLineString *line : qgis::as_const( linesToProcess ) )
84 QTransform transform = QTransform::fromTranslate( x, y );
86 secondline.reset( line->reversed() );
87 secondline->transform( transform );
89 line->append( secondline.get() );
90 line->addVertex( line->pointN( 0 ) );
96 multipolygon->addGeometry( polygon );
118 Cell(
double x,
double y,
double h,
const QgsPolygon *polygon )
122 , d( polygon->pointDistanceToBoundary( x, y ) )
123 , max( d + h * M_SQRT2 )
138 struct GreaterThanByMax
140 bool operator()(
const Cell *lhs,
const Cell *rhs )
142 return rhs->max > lhs->max;
146 Cell *getCentroidCell(
const QgsPolygon *polygon )
154 for (
int i = 0, j = len - 1; i < len; j = i++ )
156 double aX = exterior->
xAt( i );
157 double aY = exterior->
yAt( i );
158 double bX = exterior->
xAt( j );
159 double bY = exterior->
yAt( j );
160 double f = aX * bY - bX * aY;
161 x += ( aX + bX ) * f;
162 y += ( aY + bY ) * f;
166 return new Cell( exterior->
xAt( 0 ), exterior->
yAt( 0 ), 0, polygon );
168 return new Cell( x / area, y / area, 0.0, polygon );
173 std::unique_ptr< QgsPolygon > segmentizedPoly;
174 const QgsPolygon *polygon = qgsgeometry_cast< const QgsPolygon * >( surface );
178 polygon = segmentizedPoly.get();
185 double cellSize = std::min( bounds.
width(), bounds.
height() );
190 double h = cellSize / 2.0;
191 std::priority_queue< Cell *, std::vector<Cell *>, GreaterThanByMax > cellQueue;
198 cellQueue.push(
new Cell( x + h, y + h, h, polygon ) );
203 std::unique_ptr< Cell > bestCell( getCentroidCell( polygon ) );
206 std::unique_ptr< Cell > bboxCell(
new Cell( bounds.
xMinimum() + bounds.
width() / 2.0,
209 if ( bboxCell->d > bestCell->d )
211 bestCell = std::move( bboxCell );
214 while ( !cellQueue.empty() )
217 std::unique_ptr< Cell > cell( cellQueue.top() );
219 Cell *currentCell = cell.get();
222 if ( currentCell->d > bestCell->d )
224 bestCell = std::move( cell );
228 if ( currentCell->max - bestCell->d <=
precision )
232 h = currentCell->h / 2.0;
233 cellQueue.push(
new Cell( currentCell->x - h, currentCell->y - h, h, polygon ) );
234 cellQueue.push(
new Cell( currentCell->x + h, currentCell->y - h, h, polygon ) );
235 cellQueue.push(
new Cell( currentCell->x - h, currentCell->y + h, h, polygon ) );
236 cellQueue.push(
new Cell( currentCell->x + h, currentCell->y + h, h, polygon ) );
239 distanceFromBoundary = bestCell->d;
241 return QgsPoint( bestCell->x, bestCell->y );
249 if ( distanceFromBoundary )
250 *distanceFromBoundary = std::numeric_limits<double>::max();
252 if ( !mGeometry || mGeometry->
isEmpty() )
258 if (
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
260 int numGeom = gc->numGeometries();
264 for (
int i = 0; i < numGeom; ++i )
266 const QgsSurface *surface = qgsgeometry_cast< const QgsSurface * >( gc->geometryN( i ) );
271 double dist = std::numeric_limits<double>::max();
273 if ( dist > maxDist )
283 if ( distanceFromBoundary )
284 *distanceFromBoundary = maxDist;
289 const QgsSurface *surface = qgsgeometry_cast< const QgsSurface * >( mGeometry );
293 double dist = std::numeric_limits<double>::max();
295 if ( distanceFromBoundary )
296 *distanceFromBoundary = dist;
307 return lowerThreshold > std::fabs( dotProduct ) || std::fabs( dotProduct ) > upperThreshold;
333 for (
int i = 0; i < numPoints; ++i )
335 if ( !isClosed && i == numPoints - 1 )
337 else if ( !isClosed && i == 0 )
346 a = ring->
pointN( numPoints - 1 );
349 if ( i == numPoints - 1 )
358 sum += 2.0 * std::min( std::fabs( dotProduct - 1.0 ), std::min( std::fabs( dotProduct ), std::fabs( dotProduct + 1 ) ) );
368 double lowerThreshold,
double upperThreshold )
377 double scale = 2.0 * std::min( p.
length(), q.
length() );
381 double dotProduct = p * q;
390 if ( dotProduct < -M_SQRT1_2 )
395 return new_v.
normalized() * ( 0.1 * dotProduct * scale );
400 double minScore = std::numeric_limits<double>::max();
405 std::unique_ptr< QgsLineString > best( ring->
clone() );
407 QVector< QgsVector > motions;
408 motions.reserve( numPoints );
410 for (
int it = 0; it < iterations; ++it )
418 for (
int i = 0; i < numPoints; ++i )
420 if ( isClosed && i == numPoints - 1 )
421 motions << motions.at( 0 );
422 else if ( !isClosed && ( i == 0 || i == numPoints - 1 ) )
432 a = ring->
pointN( numPoints - 1 );
435 if ( i == numPoints - 1 )
440 motions <<
calcMotion( a, b,
c, lowerThreshold, upperThreshold );
447 for (
int i = 0; i < numPoints; ++i )
449 ring->
setXAt( i, ring->
xAt( i ) + motions.at( i ).x() );
450 ring->
setYAt( i, ring->
yAt( i ) + motions.at( i ).y() );
453 double newScore =
squareness( ring, lowerThreshold, upperThreshold );
454 if ( newScore < minScore )
456 best.reset( ring->
clone() );
460 if ( minScore < tolerance )
466 return best.release();
472 std::unique_ptr< QgsAbstractGeometry > segmentizedCopy;
476 geom = segmentizedCopy.get();
482 maxIterations, tolerance, lowerThreshold, upperThreshold );
491 maxIterations, tolerance, lowerThreshold, upperThreshold ) );
495 maxIterations, tolerance, lowerThreshold, upperThreshold ) );
511 double lowerThreshold = std::cos( ( 90 - angleThreshold ) * M_PI / 180.00 );
512 double upperThreshold = std::cos( angleThreshold * M_PI / 180.0 );
514 if (
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
516 int numGeom = gc->numGeometries();
517 QVector< QgsAbstractGeometry * > geometryList;
518 geometryList.reserve( numGeom );
519 for (
int i = 0; i < numGeom; ++i )
521 geometryList <<
orthogonalizeGeom( gc->geometryN( i ), maxIterations, tolerance, lowerThreshold, upperThreshold );
540 QVector< double > outX;
541 QVector< double > outY;
542 QVector< double > outZ;
543 QVector< double > outM;
544 double multiplier = 1.0 / double( extraNodesPerSegment + 1 );
547 outX.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
548 outY.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
549 bool withZ = ring->
is3D();
551 outZ.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
554 outM.reserve( ( extraNodesPerSegment + 1 ) * nPoints );
567 int extraNodesThisSegment = extraNodesPerSegment;
568 for (
int i = 0; i < nPoints - 1; ++i )
571 x2 = ring->
xAt( i + 1 );
573 y2 = ring->
yAt( i + 1 );
577 z2 = ring->
zAt( i + 1 );
582 m2 = ring->
mAt( i + 1 );
592 if ( extraNodesPerSegment < 0 )
595 extraNodesThisSegment = std::floor( std::sqrt( ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) ) / distance );
596 if ( extraNodesThisSegment >= 1 )
597 multiplier = 1.0 / ( extraNodesThisSegment + 1 );
600 for (
int j = 0; j < extraNodesThisSegment; ++j )
602 double delta = multiplier * ( j + 1 );
603 xOut = x1 + delta * ( x2 - x1 );
604 yOut = y1 + delta * ( y2 - y1 );
606 zOut = z1 + delta * ( z2 - z1 );
608 mOut = m1 + delta * ( m2 - m1 );
618 outX << ring->
xAt( nPoints - 1 );
619 outY << ring->
yAt( nPoints - 1 );
621 outZ << ring->
zAt( nPoints - 1 );
623 outM << ring->
mAt( nPoints - 1 );
631 std::unique_ptr< QgsAbstractGeometry > segmentizedCopy;
635 geom = segmentizedCopy.get();
649 extraNodesPerSegment, distance ) );
653 extraNodesPerSegment, distance ) );
673 if (
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
675 int numGeom = gc->numGeometries();
676 QVector< QgsAbstractGeometry * > geometryList;
677 geometryList.reserve( numGeom );
678 for (
int i = 0; i < numGeom; ++i )
680 geometryList <<
densifyGeometry( gc->geometryN( i ), extraNodesPerSegment );
709 if (
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
711 int numGeom = gc->numGeometries();
712 QVector< QgsAbstractGeometry * > geometryList;
713 geometryList.reserve( numGeom );
714 for (
int i = 0; i < numGeom; ++i )
741 "line_segment_dist_comparer",
742 "AB must not be collinear with the origin." );
744 "line_segment_dist_comparer",
745 "CD must not be collinear with the origin." );
759 if ( ab.
end() == cd.
end() || oad != oab )
769 if ( cdb == 0 && cda == 0 )
771 return mOrigin.sqrDist( ab.
start() ) < mOrigin.sqrDist( cd.
start() );
773 else if ( cda == cdb || cda == 0 || cdb == 0 )
776 return cdo == cda || cdo == cdb;
792 const bool aIsLeft = a.
x() < mVertex.x();
793 const bool bIsLeft = b.
x() < mVertex.x();
794 if ( aIsLeft != bIsLeft )
799 if ( a.
y() >= mVertex.y() || b.
y() >= mVertex.y() )
801 return b.
y() < a.
y();
805 return a.
y() < b.
y();
844 const double distA = ao * direction;
845 const double distB = ( origin - segment.
end() ) * direction;
847 if ( distA > 0 && distB > 0 )
853 if ( ( distA > 0 ) != ( distB > 0 ) )
854 intersectPoint = origin;
855 else if ( distA > distB )
856 intersectPoint = segment.
start();
858 intersectPoint = segment.
end();
866 if ( u < 0.0 || 1.0 < u )
873 intersectPoint = origin + direction * t;
882 if ( radius1 > radius2 )
889 QVector<QgsPointXY> points;
911 std::vector< std::unique_ptr<QgsLineString > > linesToProcess;
913 const QgsMultiCurve *multiCurve = qgsgeometry_cast< const QgsMultiCurve * >( mGeometry );
916 for (
int i = 0; i < multiCurve->
partCount(); ++i )
925 const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( mGeometry );
932 if ( linesToProcess.empty() )
935 g.mLastError = QStringLiteral(
"Input geometry was not a curve type geometry" );
939 QVector<QgsGeometry> bufferedLines;
940 bufferedLines.reserve( linesToProcess.size() );
942 for ( std::unique_ptr< QgsLineString > &line : linesToProcess )
944 QVector<QgsGeometry> parts;
946 double prevRadius = 0;
949 std::unique_ptr< double[] > widths = widthFunction( line.get() ) ;
954 double thisRadius = widths[ i ] / 2.0;
955 if ( thisRadius > 0 )
970 if ( prevRadius > 0 || thisRadius > 0 )
972 QVector< QgsPointXY > points =
generateSegmentCurve( prevPoint, prevRadius, thisPoint, thisRadius );
973 if ( !points.empty() )
978 int beforeVertex = 0;
981 double sqrDistPrev = 0;
982 for (
int j = 0; j < points.count(); ++j )
986 points[j] = sqrDistPrev < sqrDist ? pA : pB;
989 points.append( points.at( 0 ) );
991 std::unique_ptr< QgsPolygon > poly = qgis::make_unique< QgsPolygon >();
993 if ( poly->area() > 0 )
998 prevPoint = thisPoint;
999 prevRadius = thisRadius;
1000 prevCircle = thisCircle;
1012 start = std::fabs( start );
1013 end = std::fabs( end );
1019 std::unique_ptr< double [] > widths(
new double[ line->nCoordinates() ] );
1021 widths[line->nCoordinates() - 1] = end;
1023 double lineLength = line->length();
1024 double currentLength = 0;
1025 QgsPoint prevPoint = line->pointN( 0 );
1026 for (
int i = 1; i < line->nCoordinates() - 1; ++i )
1028 QgsPoint point = line->pointN( i );
1029 double segmentLength = point.
distance( prevPoint );
1030 currentLength += segmentLength;
1031 double lengthFraction = lineLength > 0 ? currentLength / lineLength : 1;
1032 double delta = lengthFraction * ( end - start );
1033 widths[i] = start + delta;
1047 std::unique_ptr< double [] > widths(
new double[ line->nCoordinates() ] );
1048 for (
int i = 0; i < line->nCoordinates(); ++i )
1050 widths[ i ] = line->mAt( i );
1059 const std::function<
bool(
const QgsPointXY & ) > &acceptPoint,
unsigned long seed,
QgsFeedback *feedback,
int maxTriesPerPoint )
1062 return QVector< QgsPointXY >();
1074 return QVector< QgsPointXY >();
1082 std::unique_ptr< QgsPolygon > p( qgsgeometry_cast< QgsPolygon * >( ms->
geometryN( i )->
segmentize() ) );
1089 if (
const QgsPolygon *poly = qgsgeometry_cast< const QgsPolygon * >( polygon.
constGet() ) )
1095 std::unique_ptr< QgsPolygon > p( qgsgeometry_cast< QgsPolygon * >( polygon.
constGet()->
segmentize() ) );
1101 return QVector< QgsPointXY >();
1103 const QVector<float> triangleData = t.
data();
1104 if ( triangleData.empty() )
1105 return QVector< QgsPointXY >();
1108 std::vector< double > cumulativeAreas;
1110 double totalArea = 0;
1111 for (
auto it = triangleData.constBegin(); it != triangleData.constEnd(); )
1114 return QVector< QgsPointXY >();
1116 const float aX = *it++;
1118 const float aY = -( *it++ );
1119 const float bX = *it++;
1121 const float bY = -( *it++ );
1122 const float cX = *it++;
1124 const float cY = -( *it++ );
1128 cumulativeAreas.emplace_back( totalArea );
1131 std::random_device rd;
1132 std::mt19937 mt( seed == 0 ? rd() : seed );
1133 std::uniform_real_distribution<> uniformDist( 0, 1 );
1136 auto selectRandomTriangle = [&cumulativeAreas, totalArea](
double random )->
int
1139 const double target = random * totalArea;
1140 for (
auto it = cumulativeAreas.begin(); it != cumulativeAreas.end(); ++it, triangle++ )
1145 Q_ASSERT_X(
false,
"QgsInternalGeometryEngine::randomPointsInPolygon",
"Invalid random triangle index" );
1150 QVector<QgsPointXY> result;
1151 result.reserve( count );
1153 for (
int i = 0; i < count; )
1156 return QVector< QgsPointXY >();
1158 const double triangleIndexRnd = uniformDist( mt );
1160 const int triangleIndex = selectRandomTriangle( triangleIndexRnd );
1163 const double weightB = uniformDist( mt );
1164 const double weightC = uniformDist( mt );
1169 const double aX = triangleData.at( triangleIndex * 9 ) + bounds.
xMinimum();
1170 const double aY = -triangleData.at( triangleIndex * 9 + 2 ) + bounds.
yMinimum();
1171 const double bX = triangleData.at( triangleIndex * 9 + 3 ) + bounds.
xMinimum();
1172 const double bY = -triangleData.at( triangleIndex * 9 + 5 ) + bounds.
yMinimum();
1173 const double cX = triangleData.at( triangleIndex * 9 + 6 ) + bounds.
xMinimum();
1174 const double cY = -triangleData.at( triangleIndex * 9 + 8 ) + bounds.
yMinimum();
1178 if ( acceptPoint( candidate ) )
1184 else if ( maxTriesPerPoint != 0 )
1188 if ( tries == maxTriesPerPoint )
1201 double pointSpacingAngleTolerance )
1203 std::unique_ptr< QgsCompoundCurve > out = qgis::make_unique< QgsCompoundCurve >();
1206 const unsigned int minQuadEdges = 2;
1219 out->addCurve( lineString->
clone() );
1225 QVector< int > edgesInArcs( numEdges + 1, 0 );
1229 double abX = b.x() - a.
x();
1230 double abY = b.y() - a.
y();
1232 double cbX = b.x() -
c.x();
1233 double cbY = b.y() -
c.y();
1235 double dot = ( abX * cbX + abY * cbY );
1236 double cross = ( abX * cbY - abY * cbX );
1238 double alpha = std::atan2( cross, dot );
1253 double centerX = 0.0;
1254 double centerY = 0.0;
1257 while ( i < numEdges - 2 )
1259 unsigned int arcEdges = 0;
1260 double numQuadrants = 0;
1263 bool foundArc =
false;
1265 a1 = lineString->
pointN( i );
1266 a2 = lineString->
pointN( i + 1 );
1267 a3 = lineString->
pointN( i + 2 );
1270 for ( j = i + 3; j < numEdges + 1; j++ )
1272 b = lineString->
pointN( j );
1279 for ( k = j - 1; k > j - 4; k-- )
1280 edgesInArcs[k] = currentArc;
1300 arcEdges = j - 1 - i;
1301 if ( first.
x() == b.x() && first.
y() == b.y() )
1316 numQuadrants = ( 4 *
angle ) / ( 2 * M_PI );
1319 if ( arcEdges < minQuadEdges * numQuadrants )
1322 for ( k = j - 1; k >= i; k-- )
1339 int edgeType = edgesInArcs[0];
1341 auto addPointsToCurve = [ lineString, &out ](
int start,
int end,
int type )
1346 QVector< QgsPoint > points;
1347 for (
int j = start; j < end + 2; ++ j )
1349 points.append( lineString->
pointN( j ) );
1351 std::unique_ptr< QgsCurve > straightSegment = qgis::make_unique< QgsLineString >( points );
1352 out->addCurve( straightSegment.release() );
1357 QVector< QgsPoint > points;
1358 points.append( lineString->
pointN( start ) );
1359 points.append( lineString->
pointN( ( start + end + 1 ) / 2 ) );
1360 points.append( lineString->
pointN( end + 1 ) );
1361 std::unique_ptr< QgsCircularString > curvedSegment = qgis::make_unique< QgsCircularString >();
1362 curvedSegment->setPoints( points );
1363 out->addCurve( curvedSegment.release() );
1367 for (
int i = 1; i < numEdges; i++ )
1369 if ( edgeType != edgesInArcs[i] )
1372 addPointsToCurve( start, end, edgeType );
1374 edgeType = edgesInArcs[i];
1380 addPointsToCurve( start, end, edgeType );
1395 std::unique_ptr< QgsCurvePolygon > result = qgis::make_unique< QgsCurvePolygon>();
1398 distanceTolerance, angleTolerance ).release() );
1402 distanceTolerance, angleTolerance ).release() );
1429 if (
const QgsGeometryCollection *gc = qgsgeometry_cast< const QgsGeometryCollection *>( mGeometry ) )
1431 int numGeom = gc->numGeometries();
1432 QVector< QgsAbstractGeometry * > geometryList;
1433 geometryList.reserve( numGeom );
1434 for (
int i = 0; i < numGeom; ++i )
1457 area = std::numeric_limits<double>::max();
1459 width = std::numeric_limits<double>::max();
1460 height = std::numeric_limits<double>::max();
1467 std::unique_ptr< QgsAbstractGeometry > hull( engine->convexHull( &mLastError ) );
1478 double totalRotation = 0;
1479 while ( hull->nextVertex( vertexId, pt2 ) )
1482 double rotateAngle = 180.0 / M_PI * currentAngle;
1483 totalRotation += rotateAngle;
1485 QTransform t = QTransform::fromTranslate( pt0.
x(), pt0.
y() );
1486 t.rotate( rotateAngle );
1487 t.translate( -pt0.
x(), -pt0.
y() );
1489 hull->transform( t );
1492 double currentArea = bounds.
width() * bounds.
height();
1493 if ( currentArea < area )
1497 angle = totalRotation;
1498 width = bounds.
width();
1499 height = bounds.
height();
1509 if (
angle > 180.0 )
Abstract base class for all geometries.
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.
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.
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
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.
OperationResult addPart(const QVector< QgsPointXY > &points, QgsWkbTypes::GeometryType geomType=QgsWkbTypes::UnknownGeometry)
Adds a new part to a the geometry.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
OperationResult rotate(double rotation, const QgsPointXY ¢er)
Rotate this geometry around the Z axis.
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 ...
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.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
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.
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.
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.
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.
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)
double normalizedDotProduct(const QgsPoint &a, const QgsPoint &b, const QgsPoint &c)
QgsAbstractGeometry * densifyGeometry(const QgsAbstractGeometry *geom, int extraNodesPerSegment=1, double distance=1)
std::unique_ptr< QgsCompoundCurve > lineToCurve(const QgsLineString *lineString, double distanceTolerance, double pointSpacingAngleTolerance)
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)
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)
QgsLineString * doOrthogonalize(QgsLineString *ring, int iterations, double tolerance, double lowerThreshold, double upperThreshold)
QgsLineString * doDensify(const QgsLineString *ring, int extraNodesPerSegment=-1, double distance=1)
Utility class for identifying a unique vertex within a geometry.