77 static void trimFeature( QVector<double>& x,
81 static void trimPolygon( QPolygonF& pts,
const QgsRectangle& clipRect );
87 static const unsigned char* clippedLineWKB(
const unsigned char* wkb,
const QgsRectangle& clipExtent, QPolygonF& line );
92 static const double SMALL_NUM;
96 static void trimFeatureToBoundary(
const QVector<double>& inX,
97 const QVector<double>& inY,
98 QVector<double>& outX,
99 QVector<double>& outY,
103 static void trimPolygonToBoundary(
const QPolygonF& inPts, QPolygonF& outPts,
const QgsRectangle& rect, Boundary b,
double boundaryValue );
106 static bool inside(
const double x,
const double y, Boundary b );
108 static bool inside(
const QPointF& pt, Boundary b,
double val );
112 static QgsPoint intersect(
const double x1,
const double y1,
113 const double x2,
const double y2,
116 static QPointF intersectRect(
const QPointF& pt1,
121 static bool clipLineSegment(
double xLeft,
double xRight,
double yBottom,
double yTop,
double& x0,
double& y0,
double& x1,
double& y1 );
131 static void connectSeparatedLines(
double x0,
double y0,
double x1,
double y1,
135 static void clipStartTop(
double& x0,
double& y0,
const double& x1,
const double& y1,
double yMax );
136 static void clipStartBottom(
double& x0,
double& y0,
const double& x1,
const double& y1,
double yMin );
137 static void clipStartRight(
double& x0,
double& y0,
const double& x1,
const double& y1,
double xMax );
138 static void clipStartLeft(
double& x0,
double& y0,
const double& x1,
const double& y1,
double xMin );
139 static void clipEndTop(
const double& x0,
const double& y0,
double& x1,
double& y1,
double yMax );
140 static void clipEndBottom(
const double& x0,
const double& y0,
double& x1,
double& y1,
double yMin );
141 static void clipEndRight(
const double& x0,
const double& y0,
double& x1,
double& y1,
double xMax );
142 static void clipEndLeft(
const double& x0,
const double& y0,
double& x1,
double& y1,
double xMin );
161 QVector<double> tmpX;
162 QVector<double> tmpY;
163 trimFeatureToBoundary( x, y, tmpX, tmpY,
XMax, shapeOpen );
167 trimFeatureToBoundary( tmpX, tmpY, x, y,
YMax, shapeOpen );
171 trimFeatureToBoundary( x, y, tmpX, tmpY,
XMin, shapeOpen );
175 trimFeatureToBoundary( tmpX, tmpY, x, y,
YMin, shapeOpen );
181 tmpPts.reserve( pts.size() );
183 trimPolygonToBoundary( pts, tmpPts, clipRect,
XMax, clipRect.
xMaximum() );
185 trimPolygonToBoundary( tmpPts, pts, clipRect,
YMax, clipRect.
yMaximum() );
187 trimPolygonToBoundary( pts, tmpPts, clipRect,
XMin, clipRect.
xMinimum() );
189 trimPolygonToBoundary( tmpPts, pts, clipRect,
YMin, clipRect.
yMinimum() );
197 inline void QgsClipper::trimFeatureToBoundary(
198 const QVector<double>& inX,
199 const QVector<double>& inY,
200 QVector<double>& outX,
201 QVector<double>& outY,
202 Boundary b,
bool shapeOpen )
208 int i1 = inX.size() - 1;
211 for (
int i2 = 0; i2 < inX.size() ; ++i2 )
216 if ( qIsNaN( inX[i2] ) || qIsNaN( inY[i2] ) || qIsInf( inX[i2] ) || qIsInf( inY[i2] )
217 || qIsNaN( inX[i1] ) || qIsNaN( inY[i1] ) || qIsInf( inX[i1] ) || qIsInf( inY[i1] ) )
224 if ( inside( inX[i2], inY[i2], b ) )
226 if ( inside( inX[i1], inY[i1], b ) )
228 outX.push_back( inX[i2] );
229 outY.push_back( inY[i2] );
235 if ( !( i2 == 0 && shapeOpen ) )
237 QgsPoint p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
238 outX.push_back( p.
x() );
239 outY.push_back( p.
y() );
242 outX.push_back( inX[i2] );
243 outY.push_back( inY[i2] );
249 if ( inside( inX[i1], inY[i1], b ) )
251 if ( !( i2 == 0 && shapeOpen ) )
253 QgsPoint p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
254 outX.push_back( p.
x() );
255 outY.push_back( p.
y() );
263 inline void QgsClipper::trimPolygonToBoundary(
const QPolygonF& inPts, QPolygonF& outPts,
const QgsRectangle& rect, Boundary b,
double boundaryValue )
265 int i1 = inPts.size() - 1;
268 for (
int i2 = 0; i2 < inPts.size() ; ++i2 )
270 if ( inside( inPts[i2], b, boundaryValue ) )
272 if ( inside( inPts[i1], b, boundaryValue ) )
274 outPts.append( inPts[i2] );
280 outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
281 outPts.append( inPts[i2] );
287 if ( inside( inPts[i1], b, boundaryValue ) )
289 outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
299 inline bool QgsClipper::inside(
const double x,
const double y, Boundary b )
323 inline bool QgsClipper::inside(
const QPointF& pt, Boundary b,
double val )
328 return ( pt.x() < val );
330 return ( pt.x() > val );
332 return ( pt.y() < val );
334 return ( pt.y() > val );
344 inline QgsPoint QgsClipper::intersect(
const double x1,
const double y1,
345 const double x2,
const double y2,
352 double r_n = SMALL_NUM, r_d = SMALL_NUM;
376 if ( qAbs( r_d ) > SMALL_NUM && qAbs( r_n ) > SMALL_NUM )
378 double r = r_n / r_d;
379 p.
set( x1 + r*( x2 - x1 ), y1 + r*( y2 - y1 ) );
385 Q_ASSERT( qAbs( r_d ) > SMALL_NUM && qAbs( r_n ) > SMALL_NUM );
391 inline QPointF QgsClipper::intersectRect(
const QPointF& pt1,
399 double r_n = SMALL_NUM, r_d = SMALL_NUM;
400 const double x1 = pt1.x(), x2 = pt2.x();
401 const double y1 = pt1.y(), y2 = pt2.y();
428 return QPointF( x1 + r*( x2 - x1 ), y1 + r*( y2 - y1 ) );
431 inline void QgsClipper::clipStartTop(
double& x0,
double& y0,
const double& x1,
const double& y1,
double yMax )
433 x0 += ( x1 - x0 ) * ( yMax - y0 ) / ( y1 - y0 );
437 inline void QgsClipper::clipStartBottom(
double& x0,
double& y0,
const double& x1,
const double& y1,
double yMin )
439 x0 += ( x1 - x0 ) * ( yMin - y0 ) / ( y1 - y0 );
443 inline void QgsClipper::clipStartRight(
double& x0,
double& y0,
const double& x1,
const double& y1,
double xMax )
445 y0 += ( y1 - y0 ) * ( xMax - x0 ) / ( x1 - x0 );
449 inline void QgsClipper::clipStartLeft(
double& x0,
double& y0,
const double& x1,
const double& y1,
double xMin )
451 y0 += ( y1 - y0 ) * ( xMin - x0 ) / ( x1 - x0 );
455 inline void QgsClipper::clipEndTop(
const double& x0,
const double& y0,
double& x1,
double& y1,
double yMax )
457 x1 += ( x1 - x0 ) * ( yMax - y1 ) / ( y1 - y0 );
461 inline void QgsClipper::clipEndBottom(
const double& x0,
const double& y0,
double& x1,
double& y1,
double yMin )
463 x1 += ( x1 - x0 ) * ( yMin - y1 ) / ( y1 - y0 );
467 inline void QgsClipper::clipEndRight(
const double& x0,
const double& y0,
double& x1,
double& y1,
double xMax )
469 y1 += ( y1 - y0 ) * ( xMax - x1 ) / ( x1 - x0 );
473 inline void QgsClipper::clipEndLeft(
const double& x0,
const double& y0,
double& x1,
double& y1,
double xMin )
475 y1 += ( y1 - y0 ) * ( xMin - x1 ) / ( x1 - x0 );
480 inline bool QgsClipper::clipLineSegment(
double xLeft,
double xRight,
double yBottom,
double yTop,
double& x0,
double& y0,
double& x1,
double& y1 )
486 else if ( y1 > yTop )
491 else if ( x1 < xLeft )
496 else if ( y0 > yTop )
501 else if ( x0 < xLeft )
510 clipEndLeft( x0, y0, x1, y1, xLeft );
514 clipEndRight( x0, y0, x1, y1, xRight );
518 clipEndBottom( x0, y0, x1, y1, yBottom );
522 clipEndLeft( x0, y0, x1, y1, xLeft );
524 clipEndBottom( x0, y0, x1, y1, yBottom );
528 clipEndRight( x0, y0, x1, y1, xRight );
530 clipEndBottom( x0, y0, x1, y1, yBottom );
534 clipEndTop( x0, y0, x1, y1, yTop );
538 clipEndLeft( x0, y0, x1, y1, xLeft );
540 clipEndTop( x0, y0, x1, y1, yTop );
544 clipEndRight( x0, y0, x1, y1, xRight );
546 clipEndTop( x0, y0, x1, y1, yTop );
550 clipStartLeft( x0, y0, x1, y1, xLeft );
554 clipStartLeft( x0, y0, x1, y1, xLeft );
555 clipEndRight( x0, y0, x1, y1, xRight );
559 clipStartLeft( x0, y0, x1, y1, xLeft );
562 clipEndBottom( x0, y0, x1, y1, yBottom );
566 clipStartLeft( x0, y0, x1, y1, xLeft );
569 clipEndBottom( x0, y0, x1, y1, yBottom );
571 clipEndRight( x0, y0, x1, y1, xRight );
575 clipStartLeft( x0, y0, x1, y1, xLeft );
578 clipEndTop( x0, y0, x1, y1, yTop );
582 clipStartLeft( x0, y0, x1, y1, xLeft );
585 clipEndTop( x0, y0, x1, y1, yTop );
587 clipEndRight( x0, y0, x1, y1, xRight );
591 clipStartRight( x0, y0, x1, y1, xRight );
595 clipStartRight( x0, y0, x1, y1, xRight );
596 clipEndLeft( x0, y0, x1, y1, xLeft );
600 clipStartRight( x0, y0, x1, y1, xRight );
603 clipEndBottom( x0, y0, x1, y1, yBottom );
607 clipStartRight( x0, y0, x1, y1, xRight );
610 clipEndBottom( x0, y0, x1, y1, yBottom );
612 clipEndLeft( x0, y0, x1, y1, xLeft );
616 clipStartRight( x0, y0, x1, y1, xRight );
619 clipEndTop( x0, y0, x1, y1, yTop );
623 clipStartRight( x0, y0, x1, y1, xRight );
626 clipEndTop( x0, y0, x1, y1, yTop );
628 clipEndLeft( x0, y0, x1, y1, xLeft );
632 clipStartBottom( x0, y0, x1, y1, yBottom );
636 clipStartBottom( x0, y0, x1, y1, yBottom );
639 clipEndLeft( x0, y0, x1, y1, xLeft );
641 clipEndBottom( x0, y0, x1, y1, yBottom );
645 clipStartBottom( x0, y0, x1, y1, yBottom );
648 clipEndRight( x0, y0, x1, y1, xRight );
652 clipStartBottom( x0, y0, x1, y1, yBottom );
653 clipEndTop( x0, y0, x1, y1, yTop );
657 clipStartBottom( x0, y0, x1, y1, yBottom );
660 clipEndLeft( x0, y0, x1, y1, xLeft );
662 clipEndTop( x0, y0, x1, y1, yTop );
666 clipStartBottom( x0, y0, x1, y1, yBottom );
669 clipEndRight( x0, y0, x1, y1, xRight );
671 clipEndTop( x0, y0, x1, y1, yTop );
675 clipStartLeft( x0, y0, x1, y1, xLeft );
677 clipStartBottom( x0, y0, x1, y1, yBottom );
681 clipEndRight( x0, y0, x1, y1, xRight );
684 clipStartBottom( x0, y0, x1, y1, yBottom );
686 clipStartLeft( x0, y0, x1, y1, xLeft );
690 clipEndTop( x0, y0, x1, y1, yTop );
693 clipStartBottom( x0, y0, x1, y1, yBottom );
695 clipStartLeft( x0, y0, x1, y1, xLeft );
699 clipStartLeft( x0, y0, x1, y1, xLeft );
702 clipEndRight( x0, y0, x1, y1, xRight );
706 clipStartBottom( x0, y0, x1, y1, yBottom );
708 clipEndTop( x0, y0, x1, y1, yTop );
712 clipStartRight( x0, y0, x1, y1, xRight );
714 clipStartBottom( x0, y0, x1, y1, yBottom );
718 clipEndLeft( x0, y0, x1, y1, xLeft );
721 clipStartBottom( x0, y0, x1, y1, yBottom );
723 clipStartRight( x0, y0, x1, y1, xRight );
727 clipEndTop( x0, y0, x1, y1, yTop );
730 clipStartRight( x0, y0, x1, y1, xRight );
732 clipStartBottom( x0, y0, x1, y1, yBottom );
736 clipEndLeft( x0, y0, x1, y1, xLeft );
739 clipStartRight( x0, y0, x1, y1, xRight );
743 clipEndTop( x0, y0, x1, y1, yTop );
745 clipStartBottom( x0, y0, x1, y1, yBottom );
749 clipStartTop( x0, y0, x1, y1, yTop );
753 clipStartTop( x0, y0, x1, y1, yTop );
756 clipEndLeft( x0, y0, x1, y1, xLeft );
760 clipStartTop( x0, y0, x1, y1, yTop );
763 clipEndRight( x0, y0, x1, y1, xRight );
767 clipStartTop( x0, y0, x1, y1, yTop );
768 clipEndBottom( x0, y0, x1, y1, yBottom );
772 clipStartTop( x0, y0, x1, y1, yTop );
775 clipEndLeft( x0, y0, x1, y1, xLeft );
777 clipEndBottom( x0, y0, x1, y1, yBottom );
781 clipStartTop( x0, y0, x1, y1, yTop );
784 clipEndRight( x0, y0, x1, y1, xRight );
786 clipEndBottom( x0, y0, x1, y1, yBottom );
790 clipStartLeft( x0, y0, x1, y1, xLeft );
792 clipStartTop( x0, y0, x1, y1, yTop );
796 clipEndRight( x0, y0, x1, y1, xRight );
799 clipStartTop( x0, y0, x1, y1, yTop );
801 clipStartLeft( x0, y0, x1, y1, xLeft );
805 clipEndBottom( x0, y0, x1, y1, yBottom );
808 clipStartLeft( x0, y0, x1, y1, xLeft );
810 clipStartTop( x0, y0, x1, y1, yTop );
814 clipStartLeft( x0, y0, x1, y1, xLeft );
817 clipEndRight( x0, y0, x1, y1, xRight );
821 clipStartTop( x0, y0, x1, y1, yTop );
823 clipEndBottom( x0, y0, x1, y1, yBottom );
827 clipStartRight( x0, y0, x1, y1, xRight );
829 clipStartTop( x0, y0, x1, y1, yTop );
833 clipEndLeft( x0, y0, x1, y1, xLeft );
836 clipStartTop( x0, y0, x1, y1, yTop );
838 clipStartRight( x0, y0, x1, y1, xRight );
842 clipEndBottom( x0, y0, x1, y1, yBottom );
845 clipStartRight( x0, y0, x1, y1, xRight );
847 clipStartTop( x0, y0, x1, y1, yTop );
851 clipEndLeft( x0, y0, x1, y1, xLeft );
854 clipStartRight( x0, y0, x1, y1, xRight );
858 clipEndBottom( x0, y0, x1, y1, yBottom );
860 clipStartTop( x0, y0, x1, y1, yTop );