102 static void trimFeature( QVector<double> &x,
114 static void trimPolygon( QPolygonF &pts,
const QgsRectangle &clipRect );
122 static void trimPolygon( QVector< double > &x, QVector< double > &y, QVector< double> &z,
const QgsBox3d &clipRect )
SIP_SKIP;
129 static void clipped3dLine(
const QVector< double > &xIn,
const QVector< double > &yIn,
const QVector<double> &zIn, QVector< double > &x, QVector< double > &y, QVector< double > &z,
const QgsBox3d &clipExtent )
SIP_SKIP;
146 static QPolygonF clippedLine(
const QPolygonF &curve,
const QgsRectangle &clipExtent );
170 static const double SMALL_NUM;
174 static inline void trimFeatureToBoundary(
const QVector<double> &inX,
175 const QVector<double> &inY,
176 QVector<double> &outX,
177 QVector<double> &outY,
181 static inline void trimPolygonToBoundary(
const QPolygonF &inPts, QPolygonF &outPts,
const QgsRectangle &rect, Boundary b,
double boundaryValue );
183 static inline void trimPolygonToBoundary(
const QVector<double> &inX,
const QVector<double> &inY,
const QVector< double > &inZ,
184 QVector<double> &outX, QVector<double> &outY, QVector<double> &outZ,
const QgsBox3d &rect, Boundary
boundary,
double boundaryValue );
187 static inline bool inside(
double x,
double y, Boundary b );
189 static inline bool inside( QPointF pt, Boundary b,
double val );
191 static inline bool inside(
double x,
double y,
double z, Boundary
boundary,
double boundaryValue );
195 static inline QgsPointXY intersect(
double x1,
double y1,
196 double x2,
double y2,
199 static inline QPointF intersectRect( QPointF pt1,
203 static inline void intersectRect(
double x1,
double y1,
double z1,
double x2,
double y2,
double z2,
204 double &xOut,
double &yOut,
double &zOut,
207 static bool clipLineSegment(
const QgsBox3d &extent,
double &x0,
double &y0,
double &z0,
double &x1,
double &y1,
double &z1 );
218 static void connectSeparatedLines(
double x0,
double y0,
double x1,
double y1,
234 static void connectSeparatedLines(
double x0,
double y0,
double z0,
double x1,
double y1,
double z1,
235 const QgsBox3d &clipRect, QVector< double > &ptsX, QVector< double > &ptsY, QVector<double> &ptsZ );
238 static void clipStartTop(
double &x0,
double &y0,
double x1,
double y1,
double yMax );
239 static void clipStartBottom(
double &x0,
double &y0,
double x1,
double y1,
double yMin );
240 static void clipStartRight(
double &x0,
double &y0,
double x1,
double y1,
double xMax );
241 static void clipStartLeft(
double &x0,
double &y0,
double &x1,
double &y1,
double xMin );
242 static void clipEndTop(
double x0,
double y0,
double &x1,
double &y1,
double yMax );
243 static void clipEndBottom(
double x0,
double y0,
double &x1,
double &y1,
double yMin );
244 static void clipEndRight(
double x0,
double y0,
double &x1,
double &y1,
double xMax );
245 static void clipEndLeft(
double x0,
double y0,
double &x1,
double &y1,
double xMin );
268 QVector<double> tmpX;
269 QVector<double> tmpY;
270 trimFeatureToBoundary( x, y, tmpX, tmpY,
XMax, shapeOpen );
274 trimFeatureToBoundary( tmpX, tmpY, x, y,
YMax, shapeOpen );
278 trimFeatureToBoundary( x, y, tmpX, tmpY,
XMin, shapeOpen );
282 trimFeatureToBoundary( tmpX, tmpY, x, y,
YMin, shapeOpen );
288 tmpPts.reserve( pts.size() );
290 trimPolygonToBoundary( pts, tmpPts, clipRect,
XMax, clipRect.
xMaximum() );
292 trimPolygonToBoundary( tmpPts, pts, clipRect,
YMax, clipRect.
yMaximum() );
294 trimPolygonToBoundary( pts, tmpPts, clipRect,
XMin, clipRect.
xMinimum() );
296 trimPolygonToBoundary( tmpPts, pts, clipRect,
YMin, clipRect.
yMinimum() );
301 QVector< double > tempX;
302 QVector< double > tempY;
303 QVector< double > tempZ;
304 const int size = x.size();
305 tempX.reserve( size );
306 tempY.reserve( size );
307 tempZ.reserve( size );
309 trimPolygonToBoundary( x, y, z, tempX, tempY, tempZ, clipRect,
XMax, clipRect.
xMaximum() );
313 trimPolygonToBoundary( tempX, tempY, tempZ, x, y, z, clipRect,
YMax, clipRect.
yMaximum() );
317 trimPolygonToBoundary( x, y, z, tempX, tempY, tempZ, clipRect,
XMin, clipRect.
xMinimum() );
321 trimPolygonToBoundary( tempX, tempY, tempZ, x, y, z, clipRect,
YMin, clipRect.
yMinimum() );
323 if ( !clipRect.
is2d() )
328 trimPolygonToBoundary( x, y, z, tempX, tempY, tempZ, clipRect,
ZMax, clipRect.
zMaximum() );
332 trimPolygonToBoundary( tempX, tempY, tempZ, x, y, z, clipRect,
ZMin, clipRect.
zMinimum() );
341inline void QgsClipper::trimFeatureToBoundary(
342 const QVector<double> &inX,
343 const QVector<double> &inY,
344 QVector<double> &outX,
345 QVector<double> &outY,
346 Boundary b,
bool shapeOpen )
352 int i1 = inX.size() - 1;
355 for (
int i2 = 0; i2 < inX.size() ; ++i2 )
360 if ( std::isnan( inX[i2] ) || std::isnan( inY[i2] ) || std::isinf( inX[i2] ) || std::isinf( inY[i2] )
361 || std::isnan( inX[i1] ) || std::isnan( inY[i1] ) || std::isinf( inX[i1] ) || std::isinf( inY[i1] ) )
368 if ( inside( inX[i2], inY[i2], b ) )
370 if ( inside( inX[i1], inY[i1], b ) )
372 outX.push_back( inX[i2] );
373 outY.push_back( inY[i2] );
379 if ( !( i2 == 0 && shapeOpen ) )
381 const QgsPointXY p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
382 outX.push_back( p.
x() );
383 outY.push_back( p.
y() );
386 outX.push_back( inX[i2] );
387 outY.push_back( inY[i2] );
393 if ( inside( inX[i1], inY[i1], b ) )
395 if ( !( i2 == 0 && shapeOpen ) )
397 const QgsPointXY p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
398 outX.push_back( p.
x() );
399 outY.push_back( p.
y() );
407inline void QgsClipper::trimPolygonToBoundary(
const QPolygonF &inPts, QPolygonF &outPts,
const QgsRectangle &rect, Boundary b,
double boundaryValue )
409 int i1 = inPts.size() - 1;
412 for (
int i2 = 0; i2 < inPts.size() ; ++i2 )
415 if ( inside( inPts[i2], b, boundaryValue ) )
417 if ( inside( inPts[i1], b, boundaryValue ) )
419 outPts.append( inPts[i2] );
425 outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
426 outPts.append( inPts[i2] );
432 if ( inside( inPts[i1], b, boundaryValue ) )
434 outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
441inline void QgsClipper::trimPolygonToBoundary(
const QVector<double> &inX,
const QVector<double> &inY,
const QVector< double > &inZ,
442 QVector<double> &outX, QVector<double> &outY, QVector<double> &outZ,
const QgsBox3d &rect, Boundary
boundary,
double boundaryValue )
444 const double len = inX.length();
453 double inI1X = inX.at( len - 1 );
454 double inI1Y = inY.at( len - 1 );
455 double inI1Z = inZ.at( len - 1 );
462 for (
int i2 = 0; i2 < len; ++i2 )
464 double inI2X = inX.at( i2 );
465 double inI2Y = inY.at( i2 );
466 double inI2Z = inZ.at( i2 );
469 if ( inside( inI2X, inI2Y, inI2Z,
boundary, boundaryValue ) )
471 if ( inside( inI1X, inI1Y, inI1Z,
boundary, boundaryValue ) )
481 intersectRect( inI1X, inI1Y, inI1Z, inI2X, inI2Y, inI2Z, xTemp, yTemp, zTemp,
boundary, rect ) ;
493 if ( inside( inI1X, inI1Y, inI1Z,
boundary, boundaryValue ) )
495 intersectRect( inI1X, inI1Y, inI1Z, inI2X, inI2Y, inI2Z, xTemp, yTemp, zTemp,
boundary, rect );
510inline bool QgsClipper::inside(
const double x,
const double y, Boundary b )
537inline bool QgsClipper::inside( QPointF pt, Boundary b,
double val )
542 return ( pt.x() < val );
544 return ( pt.x() > val );
546 return ( pt.y() < val );
548 return ( pt.y() > val );
556inline bool QgsClipper::inside(
double x,
double y,
double z, Boundary
boundary,
double boundaryValue )
561 return ( x < boundaryValue );
563 return ( x > boundaryValue );
565 return ( y < boundaryValue );
567 return ( y > boundaryValue );
569 return z < boundaryValue || std::isnan( z ) ;
571 return z > boundaryValue || std::isnan( z );
581inline QgsPointXY QgsClipper::intersect(
const double x1,
const double y1,
582 const double x2,
const double y2,
589 double r_n = SMALL_NUM, r_d = SMALL_NUM;
616 if ( std::fabs( r_d ) > SMALL_NUM && std::fabs( r_n ) > SMALL_NUM )
619 const double r = r_n / r_d;
620 p.
set( x1 + r * ( x2 - x1 ), y1 + r * ( y2 - y1 ) );
626 Q_ASSERT( std::fabs( r_d ) > SMALL_NUM && std::fabs( r_n ) > SMALL_NUM );
632inline QPointF QgsClipper::intersectRect( QPointF pt1,
640 double r_n = SMALL_NUM, r_d = SMALL_NUM;
641 const double x1 = pt1.x(), x2 = pt2.x();
642 const double y1 = pt1.y(), y2 = pt2.y();
672 return QPointF( x1 + r * ( x2 - x1 ), y1 + r * ( y2 - y1 ) );
675inline void QgsClipper::intersectRect(
const double x1,
const double y1,
const double z1,
676 const double x2,
const double y2,
const double z2,
677 double &xOut,
double &yOut,
double &zOut,
684 double r_n = SMALL_NUM, r_d = SMALL_NUM;
719 xOut = x1 + r * ( x2 - x1 );
720 yOut = y1 + r * ( y2 - y1 );
721 zOut = z1 + r * ( z2 - z1 );
724inline void QgsClipper::clipStartTop(
double &x0,
double &y0,
double x1,
double y1,
double yMax )
726 x0 += ( x1 - x0 ) * ( yMax - y0 ) / ( y1 - y0 );
730inline void QgsClipper::clipStartBottom(
double &x0,
double &y0,
double x1,
double y1,
double yMin )
732 x0 += ( x1 - x0 ) * ( yMin - y0 ) / ( y1 - y0 );
736inline void QgsClipper::clipStartRight(
double &x0,
double &y0,
double x1,
double y1,
double xMax )
738 y0 += ( y1 - y0 ) * ( xMax - x0 ) / ( x1 - x0 );
742inline void QgsClipper::clipStartLeft(
double &x0,
double &y0,
double &x1,
double &y1,
double xMin )
744 y0 += ( y1 - y0 ) * ( xMin - x0 ) / ( x1 - x0 );
748inline void QgsClipper::clipEndTop(
double x0,
double y0,
double &x1,
double &y1,
double yMax )
750 x1 += ( x1 - x0 ) * ( yMax - y1 ) / ( y1 - y0 );
754inline void QgsClipper::clipEndBottom(
double x0,
double y0,
double &x1,
double &y1,
double yMin )
756 x1 += ( x1 - x0 ) * ( yMin - y1 ) / ( y1 - y0 );
760inline void QgsClipper::clipEndRight(
double x0,
double y0,
double &x1,
double &y1,
double xMax )
762 y1 += ( y1 - y0 ) * ( xMax - x1 ) / ( x1 - x0 );
766inline void QgsClipper::clipEndLeft(
double x0,
double y0,
double &x1,
double &y1,
double xMin )
768 y1 += ( y1 - y0 ) * ( xMin - x1 ) / ( x1 - x0 );
780inline bool QgsClipper::clipLineSegment(
double xLeft,
double xRight,
double yBottom,
double yTop,
double &x0,
double &y0,
double &x1,
double &y1 )
786 else if ( y1 > yTop )
791 else if ( x1 < xLeft )
796 else if ( y0 > yTop )
801 else if ( x0 < xLeft )
810 clipEndLeft( x0, y0, x1, y1, xLeft );
814 clipEndRight( x0, y0, x1, y1, xRight );
818 clipEndBottom( x0, y0, x1, y1, yBottom );
822 clipEndLeft( x0, y0, x1, y1, xLeft );
824 clipEndBottom( x0, y0, x1, y1, yBottom );
828 clipEndRight( x0, y0, x1, y1, xRight );
830 clipEndBottom( x0, y0, x1, y1, yBottom );
834 clipEndTop( x0, y0, x1, y1, yTop );
838 clipEndLeft( x0, y0, x1, y1, xLeft );
840 clipEndTop( x0, y0, x1, y1, yTop );
844 clipEndRight( x0, y0, x1, y1, xRight );
846 clipEndTop( x0, y0, x1, y1, yTop );
850 clipStartLeft( x0, y0, x1, y1, xLeft );
854 clipStartLeft( x0, y0, x1, y1, xLeft );
855 clipEndRight( x0, y0, x1, y1, xRight );
859 clipStartLeft( x0, y0, x1, y1, xLeft );
862 clipEndBottom( x0, y0, x1, y1, yBottom );
866 clipStartLeft( x0, y0, x1, y1, xLeft );
869 clipEndBottom( x0, y0, x1, y1, yBottom );
871 clipEndRight( x0, y0, x1, y1, xRight );
875 clipStartLeft( x0, y0, x1, y1, xLeft );
878 clipEndTop( x0, y0, x1, y1, yTop );
882 clipStartLeft( x0, y0, x1, y1, xLeft );
885 clipEndTop( x0, y0, x1, y1, yTop );
887 clipEndRight( x0, y0, x1, y1, xRight );
891 clipStartRight( x0, y0, x1, y1, xRight );
895 clipStartRight( x0, y0, x1, y1, xRight );
896 clipEndLeft( x0, y0, x1, y1, xLeft );
900 clipStartRight( x0, y0, x1, y1, xRight );
903 clipEndBottom( x0, y0, x1, y1, yBottom );
907 clipStartRight( x0, y0, x1, y1, xRight );
910 clipEndBottom( x0, y0, x1, y1, yBottom );
912 clipEndLeft( x0, y0, x1, y1, xLeft );
916 clipStartRight( x0, y0, x1, y1, xRight );
919 clipEndTop( x0, y0, x1, y1, yTop );
923 clipStartRight( x0, y0, x1, y1, xRight );
926 clipEndTop( x0, y0, x1, y1, yTop );
928 clipEndLeft( x0, y0, x1, y1, xLeft );
932 clipStartBottom( x0, y0, x1, y1, yBottom );
936 clipStartBottom( x0, y0, x1, y1, yBottom );
939 clipEndLeft( x0, y0, x1, y1, xLeft );
941 clipEndBottom( x0, y0, x1, y1, yBottom );
945 clipStartBottom( x0, y0, x1, y1, yBottom );
948 clipEndRight( x0, y0, x1, y1, xRight );
952 clipStartBottom( x0, y0, x1, y1, yBottom );
953 clipEndTop( x0, y0, x1, y1, yTop );
957 clipStartBottom( x0, y0, x1, y1, yBottom );
960 clipEndLeft( x0, y0, x1, y1, xLeft );
962 clipEndTop( x0, y0, x1, y1, yTop );
966 clipStartBottom( x0, y0, x1, y1, yBottom );
969 clipEndRight( x0, y0, x1, y1, xRight );
971 clipEndTop( x0, y0, x1, y1, yTop );
975 clipStartLeft( x0, y0, x1, y1, xLeft );
977 clipStartBottom( x0, y0, x1, y1, yBottom );
981 clipEndRight( x0, y0, x1, y1, xRight );
984 clipStartBottom( x0, y0, x1, y1, yBottom );
986 clipStartLeft( x0, y0, x1, y1, xLeft );
990 clipEndTop( x0, y0, x1, y1, yTop );
993 clipStartBottom( x0, y0, x1, y1, yBottom );
995 clipStartLeft( x0, y0, x1, y1, xLeft );
999 clipStartLeft( x0, y0, x1, y1, xLeft );
1002 clipEndRight( x0, y0, x1, y1, xRight );
1006 clipStartBottom( x0, y0, x1, y1, yBottom );
1008 clipEndTop( x0, y0, x1, y1, yTop );
1012 clipStartRight( x0, y0, x1, y1, xRight );
1014 clipStartBottom( x0, y0, x1, y1, yBottom );
1018 clipEndLeft( x0, y0, x1, y1, xLeft );
1021 clipStartBottom( x0, y0, x1, y1, yBottom );
1023 clipStartRight( x0, y0, x1, y1, xRight );
1027 clipEndTop( x0, y0, x1, y1, yTop );
1030 clipStartRight( x0, y0, x1, y1, xRight );
1032 clipStartBottom( x0, y0, x1, y1, yBottom );
1036 clipEndLeft( x0, y0, x1, y1, xLeft );
1039 clipStartRight( x0, y0, x1, y1, xRight );
1043 clipEndTop( x0, y0, x1, y1, yTop );
1045 clipStartBottom( x0, y0, x1, y1, yBottom );
1049 clipStartTop( x0, y0, x1, y1, yTop );
1053 clipStartTop( x0, y0, x1, y1, yTop );
1056 clipEndLeft( x0, y0, x1, y1, xLeft );
1060 clipStartTop( x0, y0, x1, y1, yTop );
1063 clipEndRight( x0, y0, x1, y1, xRight );
1067 clipStartTop( x0, y0, x1, y1, yTop );
1068 clipEndBottom( x0, y0, x1, y1, yBottom );
1072 clipStartTop( x0, y0, x1, y1, yTop );
1075 clipEndLeft( x0, y0, x1, y1, xLeft );
1077 clipEndBottom( x0, y0, x1, y1, yBottom );
1081 clipStartTop( x0, y0, x1, y1, yTop );
1084 clipEndRight( x0, y0, x1, y1, xRight );
1086 clipEndBottom( x0, y0, x1, y1, yBottom );
1090 clipStartLeft( x0, y0, x1, y1, xLeft );
1092 clipStartTop( x0, y0, x1, y1, yTop );
1096 clipEndRight( x0, y0, x1, y1, xRight );
1099 clipStartTop( x0, y0, x1, y1, yTop );
1101 clipStartLeft( x0, y0, x1, y1, xLeft );
1105 clipEndBottom( x0, y0, x1, y1, yBottom );
1108 clipStartLeft( x0, y0, x1, y1, xLeft );
1110 clipStartTop( x0, y0, x1, y1, yTop );
1114 clipStartLeft( x0, y0, x1, y1, xLeft );
1117 clipEndRight( x0, y0, x1, y1, xRight );
1121 clipStartTop( x0, y0, x1, y1, yTop );
1123 clipEndBottom( x0, y0, x1, y1, yBottom );
1127 clipStartRight( x0, y0, x1, y1, xRight );
1129 clipStartTop( x0, y0, x1, y1, yTop );
1133 clipEndLeft( x0, y0, x1, y1, xLeft );
1136 clipStartTop( x0, y0, x1, y1, yTop );
1138 clipStartRight( x0, y0, x1, y1, xRight );
1142 clipEndBottom( x0, y0, x1, y1, yBottom );
1145 clipStartRight( x0, y0, x1, y1, xRight );
1147 clipStartTop( x0, y0, x1, y1, yTop );
1151 clipEndLeft( x0, y0, x1, y1, xLeft );
1154 clipStartRight( x0, y0, x1, y1, xRight );
1158 clipEndBottom( x0, y0, x1, y1, yBottom );
1160 clipStartTop( x0, y0, x1, y1, yTop );
A 3-dimensional box composed of x, y, z coordinates.
double yMaximum() const SIP_HOLDGIL
Returns the maximum y value.
bool is2d() const SIP_HOLDGIL
Returns true if the box can be considered a 2-dimensional box, i.e.
double zMaximum() const SIP_HOLDGIL
Returns the maximum z value.
double zMinimum() const SIP_HOLDGIL
Returns the minimum z value.
double xMinimum() const SIP_HOLDGIL
Returns the minimum x value.
double xMaximum() const SIP_HOLDGIL
Returns the maximum x value.
double yMinimum() const SIP_HOLDGIL
Returns the minimum y value.
A class to trim lines and polygons to within a rectangular region.
static void trimPolygon(QPolygonF &pts, const QgsRectangle &clipRect)
Trims the given polygon to a rectangular box, by modifying the given polygon in place.
static bool clipLineSegment(double left, double right, double bottom, double top, double &x0, double &y0, double &x1, double &y1)
Clips a line segment to a rectangle.
Boundary
A handy way to refer to the four boundaries.
@ ZMin
Minimum Z (since QGIS 3.26)
@ ZMax
Maximum Z (since QGIS 3.26)
static const double MAX_X
Maximum X-coordinate of the rectangular box used for clipping.
static const double MIN_Y
Minimum Y-coordinate of the rectangular box used for clipping.
static const double MAX_Y
Maximum Y-coordinate of the rectangular box used for clipping.
static const double MIN_X
Minimum X-coordinate of the rectangular box used for clipping.
static void trimFeature(QVector< double > &x, QVector< double > &y, bool shapeOpen)
Trims the given feature to a rectangular box.
Abstract base class for curved geometry type.
QgsAbstractGeometry * boundary() const override
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
Line string geometry type, with support for z-dimension and m-values.
A class to represent a 2D point.
void set(double x, double y) SIP_HOLDGIL
Sets the x and y value of the point.
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).
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define SIP_IF_FEATURE(feature)
#define SIP_FEATURE(feature)