[QGIS Commit] r15090 - in trunk/qgis/src/core: . symbology-ng
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Thu Jan 27 12:25:50 EST 2011
Author: mhugent
Date: 2011-01-27 09:25:50 -0800 (Thu, 27 Jan 2011)
New Revision: 15090
Modified:
trunk/qgis/src/core/qgsclipper.cpp
trunk/qgis/src/core/qgsclipper.h
trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp
Log:
Use 'fast clip' line clipping algorithm for long lines. Huge improvement for wms benchmark performance (long contour lines)
Modified: trunk/qgis/src/core/qgsclipper.cpp
===================================================================
--- trunk/qgis/src/core/qgsclipper.cpp 2011-01-27 14:18:02 UTC (rev 15089)
+++ trunk/qgis/src/core/qgsclipper.cpp 2011-01-27 17:25:50 UTC (rev 15090)
@@ -35,3 +35,171 @@
const double QgsClipper::MIN_Y = -16000;
const double QgsClipper::SMALL_NUM = 1e-12;
+
+unsigned char* QgsClipper::clippedLineWKB( unsigned char* wkb, const QgsRectangle& clipExtent, QPolygonF& line )
+{
+ wkb++; // jump over endian info
+ unsigned int wkbType = *(( int* ) wkb );
+ wkb += sizeof( unsigned int );
+ unsigned int nPoints = *(( int* ) wkb );
+ wkb += sizeof( unsigned int );
+
+ bool hasZValue = ( wkbType == QGis::WKBLineString25D );
+
+ double p0x, p0y, p1x, p1y; //original coordinates
+ double p1x_c, p1y_c; //clipped end coordinates
+ double lastClipX, lastClipY; //last successfully clipped coords
+
+ line.reserve( nPoints + 1 );
+ line.clear();
+
+ for ( unsigned int i = 0; i < nPoints; ++i )
+ {
+ if ( i == 0 )
+ {
+ memcpy( &p1x, wkb, sizeof( double ) );
+ wkb += sizeof( double );
+ memcpy( &p1y, wkb, sizeof( double ) );
+ wkb += sizeof( double );
+ if ( hasZValue ) // ignore Z value
+ {
+ wkb += sizeof( double );
+ }
+ continue;
+ }
+ else
+ {
+ p0x = p1x;
+ p0y = p1y;
+
+ memcpy( &p1x, wkb, sizeof( double ) );
+ wkb += sizeof( double );
+ memcpy( &p1y, wkb, sizeof( double ) );
+ wkb += sizeof( double );
+ if ( hasZValue ) // ignore Z value
+ {
+ wkb += sizeof( double );
+ }
+
+ p1x_c = p1x; p1y_c = p1y;
+ if ( clipLineSegment( clipExtent.xMinimum(), clipExtent.xMaximum(), clipExtent.yMinimum(), clipExtent.yMaximum(),
+ p0x, p0y, p1x_c, p1y_c ) )
+ {
+ bool newLine = line.size() > 0 && ( p1x_c != lastClipX || p1y_c != lastClipY );
+ if ( newLine )
+ {
+ //add edge points to connect old and new line
+ connectSeparatedLines( lastClipX, lastClipY, p0x, p0y, clipExtent, line );
+ }
+ if ( line.size() < 1 || newLine )
+ {
+ //add first point
+ line << QPointF( p0x, p0y );
+ }
+
+ //add second point
+ lastClipX = p1x_c; lastClipY = p1y_c;
+ line << QPointF( p1x_c, p1y_c );
+ }
+ }
+ }
+ return wkb;
+}
+
+void QgsClipper::connectSeparatedLines( double x0, double y0, double x1, double y1,
+ const QgsRectangle& clipRect, QPolygonF& pts )
+{
+ //test the different edge combinations...
+ if ( doubleNear( x0, clipRect.xMinimum() ) )
+ {
+ if ( doubleNear( x1, clipRect.xMinimum() ) )
+ {
+ return;
+ }
+ else if ( doubleNear( y1, clipRect.yMaximum() ) )
+ {
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() );
+ return;
+ }
+ else if ( doubleNear( x1, clipRect.xMaximum() ) )
+ {
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() );
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() );
+ return;
+ }
+ else if ( doubleNear( y1, clipRect.yMinimum() ) )
+ {
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() );
+ return;
+ }
+ }
+ else if ( doubleNear( y0, clipRect.yMaximum() ) )
+ {
+ if ( doubleNear( y1, clipRect.yMaximum() ) )
+ {
+ return;
+ }
+ else if ( doubleNear( x1, clipRect.xMaximum() ) )
+ {
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() );
+ return;
+ }
+ else if ( doubleNear( y1, clipRect.yMinimum() ) )
+ {
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() );
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() );
+ return;
+ }
+ else if ( doubleNear( x1, clipRect.xMinimum() ) )
+ {
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() );
+ return;
+ }
+ }
+ else if ( doubleNear( x0, clipRect.xMaximum() ) )
+ {
+ if ( doubleNear( x1, clipRect.xMaximum() ) )
+ {
+ return;
+ }
+ else if ( doubleNear( y1, clipRect.yMinimum() ) )
+ {
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() );
+ return;
+ }
+ else if ( doubleNear( x1, clipRect.xMinimum() ) )
+ {
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() );
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() );
+ return;
+ }
+ else if ( doubleNear( y1, clipRect.yMaximum() ) )
+ {
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMaximum() );
+ return;
+ }
+ }
+ else if ( doubleNear( y0, clipRect.yMinimum() ) )
+ {
+ if ( doubleNear( y1, clipRect.yMinimum() ) )
+ {
+ return;
+ }
+ else if ( doubleNear( x1, clipRect.xMinimum() ) )
+ {
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() );
+ return;
+ }
+ else if ( doubleNear( y1, clipRect.yMaximum() ) )
+ {
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMinimum() );
+ pts << QPointF( clipRect.xMinimum(), clipRect.yMaximum() );
+ return;
+ }
+ else if ( doubleNear( x1, clipRect.xMaximum() ) )
+ {
+ pts << QPointF( clipRect.xMaximum(), clipRect.yMinimum() );
+ return;
+ }
+ }
+}
Modified: trunk/qgis/src/core/qgsclipper.h
===================================================================
--- trunk/qgis/src/core/qgsclipper.h 2011-01-27 14:18:02 UTC (rev 15089)
+++ trunk/qgis/src/core/qgsclipper.h 2011-01-27 17:25:50 UTC (rev 15090)
@@ -22,10 +22,13 @@
#include "qgis.h"
#include "qgspoint.h"
+#include "qgsrectangle.h"
#include <vector>
#include <utility>
+#include <QPolygonF>
+
/** \ingroup core
* A class to trim lines and polygons to within a rectangular region.
* The functions in this class are likely to be called from within a
@@ -76,6 +79,12 @@
std::vector<double>& y,
bool shapeOpen );
+ /**Reads a polyline from WKB and clips it to clipExtent
+ @param wkb pointer to the start of the line wkb
+ @param clipExtent clipping bounds
+ @param line out: clipped line coordinates*/
+ static unsigned char* clippedLineWKB( unsigned char* wkb, const QgsRectangle& clipExtent, QPolygonF& line );
+
private:
// Used when testing for equivalance to 0.0
@@ -98,6 +107,30 @@
static QgsPoint intersect( const double x1, const double y1,
const double x2, const double y2,
Boundary b );
+
+ //Implementation of 'Fast clipping' algorithm (Sobkow et al. 1987, Computers & Graphics Vol.11, 4, p.459-467)
+ static bool clipLineSegment( double xLeft, double xRight, double yBottom, double yTop, double& x0, double& y0, double& x1, double& y1 );
+
+ /**Connects two lines splitted by the clip (by inserting points on the clip border)
+ @param x0 x-coordinate of the first line end
+ @param y0 y-coordinate of the first line end
+ @param x1 x-coordinate of the second line start
+ @param y1 y-coordinate of the second line start
+ @param clipRect clip rectangle
+ @param pts: in/out array of clipped points
+ @param writePtr in/out: writing poisiton in the wkb array*/
+ static void connectSeparatedLines( double x0, double y0, double x1, double y1,
+ const QgsRectangle& clipRect, QPolygonF& pts );
+
+ //low level clip methods for fast clip algorithm
+ static void clipStartTop( double& x0, double& y0, const double& x1, const double& y1, double yMax );
+ static void clipStartBottom( double& x0, double& y0, const double& x1, const double& y1, double yMin );
+ static void clipStartRight( double& x0, double& y0, const double& x1, const double& y1, double xMax );
+ static void clipStartLeft( double& x0, double& y0, const double& x1, const double& y1, double xMin );
+ static void clipEndTop( const double& x0, const double& y0, double& x1, double& y1, double yMax );
+ static void clipEndBottom( const double& x0, const double& y0, double& x1, double& y1, double yMin );
+ static void clipEndRight( const double& x0, const double& y0, double& x1, double& y1, double xMax );
+ static void clipEndLeft( const double& x0, const double& y0, double& x1, double& y1, double xMin );
};
// The inline functions
@@ -283,5 +316,442 @@
return p;
}
+inline void QgsClipper::clipStartTop( double& x0, double& y0, const double& x1, const double& y1, double yMax )
+{
+ x0 += ( x1 - x0 ) * ( yMax - y0 ) / ( y1 - y0 );
+ y0 = yMax;
+}
+inline void QgsClipper::clipStartBottom( double& x0, double& y0, const double& x1, const double& y1, double yMin )
+{
+ x0 += ( x1 - x0 ) * ( yMin - y0 ) / ( y1 - y0 );
+ y0 = yMin;
+}
+
+inline void QgsClipper::clipStartRight( double& x0, double& y0, const double& x1, const double& y1, double xMax )
+{
+ y0 += ( y1 - y0 ) * ( xMax - x0 ) / ( x1 - x0 );
+ x0 = xMax;
+}
+
+inline void QgsClipper::clipStartLeft( double& x0, double& y0, const double& x1, const double& y1, double xMin )
+{
+ y0 += ( y1 - y0 ) * ( xMin - x0 ) / ( x1 - x0 );
+ x0 = xMin;
+}
+
+inline void QgsClipper::clipEndTop( const double& x0, const double& y0, double& x1, double& y1, double yMax )
+{
+ x1 += ( x1 - x0 ) * ( yMax - y1 ) / ( y1 - y0 );
+ y1 = yMax;
+}
+
+inline void QgsClipper::clipEndBottom( const double& x0, const double& y0, double& x1, double& y1, double yMin )
+{
+ x1 += ( x1 - x0 ) * ( yMin - y1 ) / ( y1 - y0 );
+ y1 = yMin;
+}
+
+inline void QgsClipper::clipEndRight( const double& x0, const double& y0, double& x1, double& y1, double xMax )
+{
+ y1 += ( y1 - y0 ) * ( xMax - x1 ) / ( x1 - x0 );
+ x1 = xMax;
+}
+
+inline void QgsClipper::clipEndLeft( const double& x0, const double& y0, double& x1, double& y1, double xMin )
+{
+ y1 += ( y1 - y0 ) * ( xMin - x1 ) / ( x1 - x0 );
+ x1 = xMin;
+}
+
+//'Fast clipping' algorithm (Sobkow et al. 1987, Computers & Graphics Vol.11, 4, p.459-467)
+inline bool QgsClipper::clipLineSegment( double xLeft, double xRight, double yBottom, double yTop, double& x0, double& y0, double& x1, double& y1 )
+{
+ int lineCode = 0;
+
+ if ( y1 < yBottom )
+ lineCode |= 4;
+ else if ( y1 > yTop )
+ lineCode |= 8;
+
+ if ( x1 > xRight )
+ lineCode |= 2;
+ else if ( x1 < xLeft )
+ lineCode |= 1;
+
+ if ( y0 < yBottom )
+ lineCode |= 64;
+ else if ( y0 > yTop )
+ lineCode |= 128;
+
+ if ( x0 > xRight )
+ lineCode |= 32;
+ else if ( x0 < xLeft )
+ lineCode |= 16;
+
+ switch ( lineCode )
+ {
+ case 0: //completely inside
+ return true;
+
+ case 1:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 2:
+ clipEndRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 4:
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 5:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 6:
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 8:
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 9:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 > yTop )
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 10:
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 > yTop )
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 16:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 18:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ clipEndRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 20:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 < yBottom )
+ return false;
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 22:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 < yBottom )
+ return false;
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ if ( x1 > xRight )
+ clipEndRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 24:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 > yTop )
+ return false;
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 26:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 > yTop )
+ return false;
+ clipEndTop( x0, y0, x1, y1, yTop );
+ if ( x1 > xRight )
+ clipEndRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 32:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 33:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 36:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 < yBottom )
+ return false;
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 37:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 < yBottom )
+ return false;
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ if ( x1 < xLeft )
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 40:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 > yTop )
+ return false;
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 41:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 > yTop )
+ return false;
+ clipEndTop( x0, y0, x1, y1, yTop );
+ if ( x1 < xLeft )
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 64:
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 65:
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 < xLeft )
+ return false;
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 66:
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 > xRight )
+ return false;
+ clipEndRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 72:
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 73:
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 < xLeft )
+ return false;
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 > yTop )
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 74:
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 > xRight )
+ return false;
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 > yTop )
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 80:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 < yBottom )
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 82:
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 < yBottom )
+ return false;
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 < xLeft )
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 88:
+ clipEndTop( x0, y0, x1, y1, yTop );
+ if ( x1 < xLeft )
+ return false;
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 < xLeft )
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 90:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 > yTop )
+ return false;
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 < yBottom )
+ return false;
+ if ( y0 < yBottom )
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( y1 > yTop )
+ clipEndTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 96:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 < yBottom )
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 97:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 < yBottom )
+ return false;
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ if ( x0 > xRight )
+ clipStartRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 104:
+ clipEndTop( x0, y0, x1, y1, yTop );
+ if ( x1 > xRight )
+ return false;
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 < yBottom )
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 105:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 < yBottom )
+ return false;
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 > yTop )
+ return false;
+ if ( y1 > yTop )
+ clipEndTop( x0, y0, x1, y1, yTop );
+ if ( y0 < yBottom )
+ clipStartBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 128:
+ clipStartTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 129:
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( x0 < xLeft )
+ return false;
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 130:
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( x0 > xRight )
+ return false;
+ clipEndRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 132:
+ clipStartTop( x0, y0, x1, y1, yTop );
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 133:
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( x0 < xLeft )
+ return false;
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 134:
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( x0 > xRight )
+ return false;
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 144:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 > yTop )
+ clipStartTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 146:
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 > yTop )
+ return false;
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( x0 < xLeft )
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ return true;
+
+ case 148:
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ if ( x1 < xLeft )
+ return false;
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 > yTop )
+ clipStartTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 150:
+ clipStartLeft( x0, y0, x1, y1, xLeft );
+ if ( y0 < yBottom )
+ return false;
+ clipEndRight( x0, y0, x1, y1, xRight );
+ if ( y1 > yTop )
+ return false;
+ if ( y0 > yTop )
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ return true;
+
+ case 160:
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 > yTop )
+ clipStartTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 161:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 > yTop )
+ return false;
+ clipStartTop( x0, y0, x1, y1, yTop );
+ if ( x0 > xRight )
+ clipStartRight( x0, y0, x1, y1, xRight );
+ return true;
+
+ case 164:
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ if ( x1 > xRight )
+ return false;
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 > yTop )
+ clipStartTop( x0, y0, x1, y1, yTop );
+ return true;
+
+ case 165:
+ clipEndLeft( x0, y0, x1, y1, xLeft );
+ if ( y1 > yTop )
+ return false;
+ clipStartRight( x0, y0, x1, y1, xRight );
+ if ( y0 < yBottom )
+ return false;
+ if ( y1 < yBottom )
+ clipEndBottom( x0, y0, x1, y1, yBottom );
+ if ( y0 > yTop )
+ clipStartTop( x0, y0, x1, y1, yTop );
+ return true;
+ }
+
+ return false;
+
+}
+
+
#endif
Modified: trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp 2011-01-27 14:18:02 UTC (rev 15089)
+++ trunk/qgis/src/core/symbology-ng/qgsrendererv2.cpp 2011-01-27 17:25:50 UTC (rev 15090)
@@ -8,6 +8,7 @@
#include "qgsrendererv2registry.h"
#include "qgsrendercontext.h"
+#include "qgsclipper.h"
#include "qgsgeometry.h"
#include "qgsfeature.h"
#include "qgslogger.h"
@@ -54,31 +55,45 @@
bool hasZValue = ( wkbType == QGis::WKBLineString25D );
double x, y;
- pts.resize( nPoints );
-
const QgsCoordinateTransform* ct = context.coordinateTransform();
const QgsMapToPixel& mtp = context.mapToPixel();
double z = 0; // dummy variable for coordiante transform
- for ( unsigned int i = 0; i < nPoints; ++i )
+ //apply clipping for large lines to achieve a better rendering performance
+ if ( nPoints > 100 )
{
- x = *(( double * ) wkb );
- wkb += sizeof( double );
- y = *(( double * ) wkb );
- wkb += sizeof( double );
+ const QgsRectangle& e = context.extent();
+ double cw = e.width() / 10; double ch = e.height() / 10;
+ QgsRectangle clipRect( e.xMinimum() - cw, e.yMinimum() - ch, e.xMaximum() + cw, e.yMaximum() + ch );
+ wkb = QgsClipper::clippedLineWKB( wkb - ( 2 * sizeof( unsigned int ) + 1 ), clipRect, pts );
+ }
+ else
+ {
+ pts.resize( nPoints );
- if ( hasZValue ) // ignore Z value
+ for ( unsigned int i = 0; i < nPoints; ++i )
+ {
+ x = *(( double * ) wkb );
wkb += sizeof( double );
+ y = *(( double * ) wkb );
+ wkb += sizeof( double );
- // TODO: maybe to the transform at once (faster?)
- if ( ct )
- ct->transformInPlace( x, y, z );
- mtp.transformInPlace( x, y );
+ if ( hasZValue ) // ignore Z value
+ wkb += sizeof( double );
- pts[i] = QPointF( x, y );
+ pts[i] = QPointF( x, y );
+ }
+ }
+ //transform the QPolygonF to screen coordinates
+ for ( unsigned int i = 0; i < pts.size(); ++i )
+ {
+ if ( ct )
+ ct->transformInPlace( pts[i].rx(), pts[i].ry(), z );
+ mtp.transformInPlace( pts[i].rx(), pts[i].ry() );
}
+
return wkb;
}
More information about the QGIS-commit
mailing list