22 #include "qgis_core.h" 
   96     static void trimFeature( QVector<double> &x,
 
  102     static void trimPolygon( QPolygonF &pts, 
const QgsRectangle &clipRect );
 
  117     static QPolygonF clippedLine( 
const QPolygonF &curve, 
const QgsRectangle &clipExtent );
 
  122     static const double SMALL_NUM;
 
  126     static inline void trimFeatureToBoundary( 
const QVector<double> &inX,
 
  127         const QVector<double> &inY,
 
  128         QVector<double> &outX,
 
  129         QVector<double> &outY,
 
  133     static inline void trimPolygonToBoundary( 
const QPolygonF &inPts, QPolygonF &outPts, 
const QgsRectangle &rect, Boundary b, 
double boundaryValue );
 
  136     static inline bool inside( 
double x, 
double y, Boundary b );
 
  138     static inline bool inside( QPointF pt, Boundary b, 
double val );
 
  142     static inline QgsPointXY intersect( 
double x1, 
double y1,
 
  143                                         double x2, 
double y2,
 
  146     static inline QPointF intersectRect( QPointF pt1,
 
  151     static bool clipLineSegment( 
double xLeft, 
double xRight, 
double yBottom, 
double yTop, 
double &x0, 
double &y0, 
double &x1, 
double &y1 );
 
  162     static void connectSeparatedLines( 
double x0, 
double y0, 
double x1, 
double y1,
 
  166     static void clipStartTop( 
double &x0, 
double &y0, 
double x1, 
double y1, 
double yMax );
 
  167     static void clipStartBottom( 
double &x0, 
double &y0, 
double x1, 
double y1, 
double yMin );
 
  168     static void clipStartRight( 
double &x0, 
double &y0, 
double x1, 
double y1, 
double xMax );
 
  169     static void clipStartLeft( 
double &x0, 
double &y0, 
double &x1, 
double &y1, 
double xMin );
 
  170     static void clipEndTop( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double yMax );
 
  171     static void clipEndBottom( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double yMin );
 
  172     static void clipEndRight( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double xMax );
 
  173     static void clipEndLeft( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double xMin );
 
  193   QVector<double> tmpX;
 
  194   QVector<double> tmpY;
 
  195   trimFeatureToBoundary( x, y, tmpX, tmpY, 
XMax, shapeOpen );
 
  199   trimFeatureToBoundary( tmpX, tmpY, x, y, 
YMax, shapeOpen );
 
  203   trimFeatureToBoundary( x, y, tmpX, tmpY, 
XMin, shapeOpen );
 
  207   trimFeatureToBoundary( tmpX, tmpY, x, y, 
YMin, shapeOpen );
 
  213   tmpPts.reserve( pts.size() );
 
  215   trimPolygonToBoundary( pts, tmpPts, clipRect, 
XMax, clipRect.
xMaximum() );
 
  217   trimPolygonToBoundary( tmpPts, pts, clipRect, 
YMax, clipRect.
yMaximum() );
 
  219   trimPolygonToBoundary( pts, tmpPts, clipRect, 
XMin, clipRect.
xMinimum() );
 
  221   trimPolygonToBoundary( tmpPts, pts, clipRect, 
YMin, clipRect.
yMinimum() );
 
  229 inline void QgsClipper::trimFeatureToBoundary(
 
  230   const QVector<double> &inX,
 
  231   const QVector<double> &inY,
 
  232   QVector<double> &outX,
 
  233   QVector<double> &outY,
 
  234   Boundary b, 
bool shapeOpen )
 
  240   int i1 = inX.size() - 1; 
 
  243   for ( 
int i2 = 0; i2 < inX.size() ; ++i2 )
 
  248     if ( std::isnan( inX[i2] ) || std::isnan( inY[i2] ) || std::isinf( inX[i2] ) || std::isinf( inY[i2] )
 
  249          || std::isnan( inX[i1] ) || std::isnan( inY[i1] ) || std::isinf( inX[i1] ) || std::isinf( inY[i1] ) )
 
  256     if ( inside( inX[i2], inY[i2], b ) ) 
 
  258       if ( inside( inX[i1], inY[i1], b ) )
 
  260         outX.push_back( inX[i2] );
 
  261         outY.push_back( inY[i2] );
 
  267         if ( !( i2 == 0 && shapeOpen ) )
 
  269           const QgsPointXY p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
 
  270           outX.push_back( p.
x() );
 
  271           outY.push_back( p.
y() );
 
  274         outX.push_back( inX[i2] );
 
  275         outY.push_back( inY[i2] );
 
  281       if ( inside( inX[i1], inY[i1], b ) )
 
  283         if ( !( i2 == 0 && shapeOpen ) )
 
  285           const QgsPointXY p = intersect( inX[i1], inY[i1], inX[i2], inY[i2], b );
 
  286           outX.push_back( p.
x() );
 
  287           outY.push_back( p.
y() );
 
  295 inline void QgsClipper::trimPolygonToBoundary( 
const QPolygonF &inPts, QPolygonF &outPts, 
const QgsRectangle &rect, Boundary b, 
double boundaryValue )
 
  297   int i1 = inPts.size() - 1; 
 
  300   for ( 
int i2 = 0; i2 < inPts.size() ; ++i2 )
 
  303     if ( inside( inPts[i2], b, boundaryValue ) ) 
 
  305       if ( inside( inPts[i1], b, boundaryValue ) )
 
  307         outPts.append( inPts[i2] );
 
  313         outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
 
  314         outPts.append( inPts[i2] );
 
  320       if ( inside( inPts[i1], b, boundaryValue ) )
 
  322         outPts.append( intersectRect( inPts[i1], inPts[i2], b, rect ) );
 
  332 inline bool QgsClipper::inside( 
const double x, 
const double y, Boundary b )
 
  356 inline bool QgsClipper::inside( QPointF pt, Boundary b, 
double val )
 
  361       return ( pt.x() < val );
 
  363       return ( pt.x() > val );
 
  365       return ( pt.y() < val );
 
  367       return ( pt.y() > val );
 
  377 inline QgsPointXY QgsClipper::intersect( 
const double x1, 
const double y1,
 
  378     const double x2, 
const double y2,
 
  385   double r_n = SMALL_NUM, r_d = SMALL_NUM;
 
  409   if ( std::fabs( r_d ) > SMALL_NUM && std::fabs( r_n ) > SMALL_NUM )
 
  412     const double r = r_n / r_d;
 
  413     p.
set( x1 + r * ( x2 - x1 ), y1 + r * ( y2 - y1 ) );
 
  419     Q_ASSERT( std::fabs( r_d ) > SMALL_NUM && std::fabs( r_n ) > SMALL_NUM );
 
  425 inline QPointF QgsClipper::intersectRect( QPointF pt1,
 
  433   double r_n = SMALL_NUM, r_d = SMALL_NUM;
 
  434   const double x1 = pt1.x(), x2 = pt2.x();
 
  435   const double y1 = pt1.y(), y2 = pt2.y();
 
  462   return QPointF( x1 + r * ( x2 - x1 ), y1 + r * ( y2 - y1 ) );
 
  465 inline void QgsClipper::clipStartTop( 
double &x0, 
double &y0, 
double x1, 
double y1, 
double yMax )
 
  467   x0 += ( x1 - x0 )  * ( yMax - y0 ) / ( y1 - y0 );
 
  471 inline void QgsClipper::clipStartBottom( 
double &x0, 
double &y0, 
double x1, 
double y1, 
double yMin )
 
  473   x0 += ( x1 - x0 ) * ( yMin - y0 ) / ( y1 - y0 );
 
  477 inline void QgsClipper::clipStartRight( 
double &x0, 
double &y0, 
double x1, 
double y1, 
double xMax )
 
  479   y0 += ( y1 - y0 ) * ( xMax - x0 ) / ( x1 - x0 );
 
  483 inline void QgsClipper::clipStartLeft( 
double &x0, 
double &y0, 
double &x1, 
double &y1, 
double xMin )
 
  485   y0 += ( y1 - y0 ) * ( xMin - x0 ) / ( x1 - x0 );
 
  489 inline void QgsClipper::clipEndTop( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double yMax )
 
  491   x1 += ( x1 - x0 ) * ( yMax - y1 ) / ( y1 - y0 );
 
  495 inline void QgsClipper::clipEndBottom( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double yMin )
 
  497   x1 += ( x1 - x0 ) * ( yMin - y1 ) / ( y1 - y0 );
 
  501 inline void QgsClipper::clipEndRight( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double xMax )
 
  503   y1 += ( y1 - y0 ) * ( xMax - x1 ) / ( x1 - x0 );
 
  507 inline void QgsClipper::clipEndLeft( 
double x0, 
double y0, 
double &x1, 
double &y1, 
double xMin )
 
  509   y1 += ( y1 - y0 ) * ( xMin - x1 ) / ( x1 - x0 );
 
  514 inline bool QgsClipper::clipLineSegment( 
double xLeft, 
double xRight, 
double yBottom, 
double yTop, 
double &x0, 
double &y0, 
double &x1, 
double &y1 )
 
  520   else if ( y1 > yTop )
 
  525   else if ( x1 < xLeft )
 
  530   else if ( y0 > yTop )
 
  535   else if ( x0 < xLeft )
 
  544       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  548       clipEndRight( x0, y0, x1, y1, xRight );
 
  552       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  556       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  558         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  562       clipEndRight( x0, y0, x1, y1, xRight );
 
  564         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  568       clipEndTop( x0, y0, x1, y1, yTop );
 
  572       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  574         clipEndTop( x0, y0, x1, y1, yTop );
 
  578       clipEndRight( x0, y0, x1, y1, xRight );
 
  580         clipEndTop( x0, y0, x1, y1, yTop );
 
  584       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  588       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  589       clipEndRight( x0, y0, x1, y1, xRight );
 
  593       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  596       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  600       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  603       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  605         clipEndRight( x0, y0, x1, y1, xRight );
 
  609       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  612       clipEndTop( x0, y0, x1, y1, yTop );
 
  616       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  619       clipEndTop( x0, y0, x1, y1, yTop );
 
  621         clipEndRight( x0, y0, x1, y1, xRight );
 
  625       clipStartRight( x0, y0, x1, y1, xRight );
 
  629       clipStartRight( x0, y0, x1, y1, xRight );
 
  630       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  634       clipStartRight( x0, y0, x1, y1, xRight );
 
  637       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  641       clipStartRight( x0, y0, x1, y1, xRight );
 
  644       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  646         clipEndLeft( x0, y0, x1, y1, xLeft );
 
  650       clipStartRight( x0, y0, x1, y1, xRight );
 
  653       clipEndTop( x0, y0, x1, y1, yTop );
 
  657       clipStartRight( x0, y0, x1, y1, xRight );
 
  660       clipEndTop( x0, y0, x1, y1, yTop );
 
  662         clipEndLeft( x0, y0, x1, y1, xLeft );
 
  666       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  670       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  673       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  675         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  679       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  682       clipEndRight( x0, y0, x1, y1, xRight );
 
  686       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  687       clipEndTop( x0, y0, x1, y1, yTop );
 
  691       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  694       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  696         clipEndTop( x0, y0, x1, y1, yTop );
 
  700       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  703       clipEndRight( x0, y0, x1, y1, xRight );
 
  705         clipEndTop( x0, y0, x1, y1, yTop );
 
  709       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  711         clipStartBottom( x0, y0, x1, y1, yBottom );
 
  715       clipEndRight( x0, y0, x1, y1, xRight );
 
  718       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  720         clipStartLeft( x0, y0, x1, y1, xLeft );
 
  724       clipEndTop( x0, y0, x1, y1, yTop );
 
  727       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  729         clipStartLeft( x0, y0, x1, y1, xLeft );
 
  733       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  736       clipEndRight( x0, y0, x1, y1, xRight );
 
  740         clipStartBottom( x0, y0, x1, y1, yBottom );
 
  742         clipEndTop( x0, y0, x1, y1, yTop );
 
  746       clipStartRight( x0, y0, x1, y1, xRight );
 
  748         clipStartBottom( x0, y0, x1, y1, yBottom );
 
  752       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  755       clipStartBottom( x0, y0, x1, y1, yBottom );
 
  757         clipStartRight( x0, y0, x1, y1, xRight );
 
  761       clipEndTop( x0, y0, x1, y1, yTop );
 
  764       clipStartRight( x0, y0, x1, y1, xRight );
 
  766         clipStartBottom( x0, y0, x1, y1, yBottom );
 
  770       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  773       clipStartRight( x0, y0, x1, y1, xRight );
 
  777         clipEndTop( x0, y0, x1, y1, yTop );
 
  779         clipStartBottom( x0, y0, x1, y1, yBottom );
 
  783       clipStartTop( x0, y0, x1, y1, yTop );
 
  787       clipStartTop( x0, y0, x1, y1, yTop );
 
  790       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  794       clipStartTop( x0, y0, x1, y1, yTop );
 
  797       clipEndRight( x0, y0, x1, y1, xRight );
 
  801       clipStartTop( x0, y0, x1, y1, yTop );
 
  802       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  806       clipStartTop( x0, y0, x1, y1, yTop );
 
  809       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  811         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  815       clipStartTop( x0, y0, x1, y1, yTop );
 
  818       clipEndRight( x0, y0, x1, y1, xRight );
 
  820         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  824       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  826         clipStartTop( x0, y0, x1, y1, yTop );
 
  830       clipEndRight( x0, y0, x1, y1, xRight );
 
  833       clipStartTop( x0, y0, x1, y1, yTop );
 
  835         clipStartLeft( x0, y0, x1, y1, xLeft );
 
  839       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  842       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  844         clipStartTop( x0, y0, x1, y1, yTop );
 
  848       clipStartLeft( x0, y0, x1, y1, xLeft );
 
  851       clipEndRight( x0, y0, x1, y1, xRight );
 
  855         clipStartTop( x0, y0, x1, y1, yTop );
 
  857         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  861       clipStartRight( x0, y0, x1, y1, xRight );
 
  863         clipStartTop( x0, y0, x1, y1, yTop );
 
  867       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  870       clipStartTop( x0, y0, x1, y1, yTop );
 
  872         clipStartRight( x0, y0, x1, y1, xRight );
 
  876       clipEndBottom( x0, y0, x1, y1, yBottom );
 
  879       clipStartRight( x0, y0, x1, y1, xRight );
 
  881         clipStartTop( x0, y0, x1, y1, yTop );
 
  885       clipEndLeft( x0, y0, x1, y1, xLeft );
 
  888       clipStartRight( x0, y0, x1, y1, xRight );
 
  892         clipEndBottom( x0, y0, x1, y1, yBottom );
 
  894         clipStartTop( x0, y0, x1, y1, yTop );
 
A class to trim lines and polygons to within a rectangular region.
static void trimPolygon(QPolygonF &pts, const QgsRectangle &clipRect)
Boundary
A handy way to refer to the four boundaries.
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.
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)