Skip to content

Commit db8eaf0

Browse files
committedOct 18, 2013
Feature #8725: Fast rendering of geom (v-OGR)
Implements fast rendering of LineStrings and Polygons pre-applying a view threshold filter to the geometries to render in qgis. Also disable 'Antialiasing' when it is possible. View Table of test results in 'http://hub.qgis.org/issues/8725' (This version of branch implements the improvement in vector-providers)
1 parent cecfff0 commit db8eaf0

23 files changed

+746
-44
lines changed
 

‎python/core/symbology-ng/qgssymbollayerv2.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,5 @@ class QgsFillSymbolLayerV2 : QgsSymbolLayerV2
202202
protected:
203203
QgsFillSymbolLayerV2( bool locked = false );
204204
/**Default method to render polygon*/
205-
void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings );
205+
void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
206206
};

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ SET(QGIS_CORE_SRCS
8181
qgslabelattributes.cpp
8282
qgslabelsearchtree.cpp
8383
qgslogger.cpp
84+
qgsmaprequest.cpp
8485
qgsmaplayer.cpp
8586
qgsmaplayerregistry.cpp
8687
qgsmaprenderer.cpp

‎src/core/qgsclipper.cpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const
4545

4646
bool hasZValue = ( wkbType == QGis::WKBLineString25D );
4747

48+
int sizeOfDoubleX = sizeof(double);
49+
int sizeOfDoubleY = hasZValue ? 2*sizeof(double) : sizeof(double);
50+
4851
double p0x, p0y, p1x = 0.0, p1y = 0.0; //original coordinates
4952
double p1x_c, p1y_c; //clipped end coordinates
5053
double lastClipX = 0.0, lastClipY = 0.0; //last successfully clipped coords
@@ -56,29 +59,18 @@ const unsigned char* QgsClipper::clippedLineWKB( const unsigned char* wkb, const
5659
{
5760
if ( i == 0 )
5861
{
59-
memcpy( &p1x, wkb, sizeof( double ) );
60-
wkb += sizeof( double );
61-
memcpy( &p1y, wkb, sizeof( double ) );
62-
wkb += sizeof( double );
63-
if ( hasZValue ) // ignore Z value
64-
{
65-
wkb += sizeof( double );
66-
}
62+
memcpy( &p1x, wkb, sizeof( double ) ); wkb += sizeOfDoubleX;
63+
memcpy( &p1y, wkb, sizeof( double ) ); wkb += sizeOfDoubleY;
64+
6765
continue;
6866
}
6967
else
7068
{
7169
p0x = p1x;
7270
p0y = p1y;
7371

74-
memcpy( &p1x, wkb, sizeof( double ) );
75-
wkb += sizeof( double );
76-
memcpy( &p1y, wkb, sizeof( double ) );
77-
wkb += sizeof( double );
78-
if ( hasZValue ) // ignore Z value
79-
{
80-
wkb += sizeof( double );
81-
}
72+
memcpy( &p1x, wkb, sizeof( double ) ); wkb += sizeOfDoubleX;
73+
memcpy( &p1y, wkb, sizeof( double ) ); wkb += sizeOfDoubleY;
8274

8375
p1x_c = p1x; p1y_c = p1y;
8476
if ( clipLineSegment( clipExtent.xMinimum(), clipExtent.xMaximum(), clipExtent.yMinimum(), clipExtent.yMaximum(),

‎src/core/qgsfeaturerequest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ QgsFeatureRequest::QgsFeatureRequest( const QgsFeatureRequest &rh )
4949

5050
QgsFeatureRequest& QgsFeatureRequest::operator=( const QgsFeatureRequest & rh )
5151
{
52+
QgsMapRequest::operator=( rh );
53+
5254
mFlags = rh.mFlags;
5355
mFilter = rh.mFilter;
5456
mFilterRect = rh.mFilterRect;

‎src/core/qgsfeaturerequest.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <QFlags>
1919

20+
#include "qgsmaprequest.h"
2021
#include "qgsfeature.h"
2122
#include "qgsrectangle.h"
2223
#include "qgsexpression.h"
@@ -53,15 +54,16 @@ typedef QList<int> QgsAttributeList;
5354
* QgsFeatureRequest().setFilterFid(45)
5455
*
5556
*/
56-
class CORE_EXPORT QgsFeatureRequest
57+
class CORE_EXPORT QgsFeatureRequest : public QgsMapRequest
5758
{
5859
public:
5960
enum Flag
6061
{
6162
NoFlags = 0,
6263
NoGeometry = 1, //!< Geometry is not required. It may still be returned if e.g. required for a filter condition.
6364
SubsetOfAttributes = 2, //!< Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
64-
ExactIntersect = 4 //!< Use exact geometry intersection (slower) instead of bounding boxes
65+
ExactIntersect = 4, //!< Use exact geometry intersection (slower) instead of bounding boxes
66+
SimplifyGeometries = 8 //!< Simplify the geometry using the current map2pixel context
6567
};
6668
Q_DECLARE_FLAGS( Flags, Flag )
6769

‎src/core/qgsmaprenderer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
278278
//so must be false at every new render operation
279279
mRenderContext.setRenderingStopped( false );
280280

281+
// Gets the configured Tolerance for simplify transformations between map coordinates and device coordinates
282+
QSettings mySettings2;
283+
mRenderContext.setMapToPixelTol( mySettings2.value( "Map/map2pixelTol", 1.0f ).toFloat() );
284+
281285
// set selection color
282286
QgsProject* prj = QgsProject::instance();
283287
int myRed = prj->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );

‎src/core/qgsmaprequest.cpp

Lines changed: 409 additions & 0 deletions
Large diffs are not rendered by default.

‎src/core/qgsmaprequest.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
qgsmaprequest.h
3+
----------------------
4+
begin : October 2013
5+
copyright : (C) 2013 by Alvaro Huarte
6+
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
7+
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
#ifndef QGSMAPREQUEST_H
18+
#define QGSMAPREQUEST_H
19+
20+
#include "qgscoordinatetransform.h"
21+
#include "qgsmaptopixel.h"
22+
23+
class QgsRectangle;
24+
class QgsGeometry;
25+
26+
/**
27+
* This class wraps a generic request for a map layer (or directly its data provider).
28+
* The request may apply a simplification using the map2pixel render state to fetch
29+
* only a particular subset of information.
30+
*/
31+
class CORE_EXPORT QgsMapRequest
32+
{
33+
public:
34+
//! construct a default request
35+
QgsMapRequest();
36+
//! copy constructor
37+
QgsMapRequest( const QgsMapRequest& rh );
38+
39+
QgsMapRequest& operator=( const QgsMapRequest& rh );
40+
41+
~QgsMapRequest();
42+
43+
public:
44+
const QgsCoordinateTransform* coordinateTransform() const { return mMapCoordTransform; }
45+
QgsMapRequest& setCoordinateTransform( const QgsCoordinateTransform* ct );
46+
47+
const QgsMapToPixel* mapToPixel() const { return mMapToPixel; }
48+
QgsMapRequest& setMapToPixel( const QgsMapToPixel* mtp );
49+
50+
float mapToPixelTol() const { return mMapToPixelTol; }
51+
QgsMapRequest& setMapToPixelTol( float map2pixelTol );
52+
53+
protected:
54+
//! For transformation between coordinate systems from current layer to map target. Can be 0 if on-the-fly reprojection is not used
55+
const QgsCoordinateTransform* mMapCoordTransform;
56+
//! For transformation between map coordinates and device coordinates
57+
const QgsMapToPixel* mMapToPixel;
58+
//! Factor tolterance to apply in transformation between map coordinates and device coordinates
59+
float mMapToPixelTol;
60+
61+
public:
62+
//! Returns whether the devided-geometry can be replaced by its BBOX when is applied the specified the map2pixel context
63+
static bool canbeGeneralizedByWndBoundingBox( const QgsRectangle& envelope, float mapToPixelTol = 1.0f );
64+
//! Returns whether the devided-geometry can be replaced by its BBOX when is applied the specified the map2pixel context
65+
static bool canbeGeneralizedByWndBoundingBox( const QVector<QPointF>& points, float mapToPixelTol = 1.0f );
66+
67+
//! Simplify the specified geometry (Removing duplicated points) when is applied the map2pixel context
68+
static bool simplifyGeometry( QgsGeometry* geometry,
69+
const QgsCoordinateTransform* coordinateTransform, const QgsMapToPixel* mtp, float mapToPixelTol = 1.0f );
70+
71+
//! Simplify the specified geometry (Removing duplicated points) when is applied the map2pixel context
72+
inline bool simplifyGeometry( QgsGeometry* geometry ) { return simplifyGeometry( geometry, mMapCoordTransform, mMapToPixel, mMapToPixelTol ); }
73+
};
74+
75+
#endif // QGSMAPREQUEST_H

‎src/core/qgsrendercontext.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ QgsRenderContext::QgsRenderContext()
2828
mScaleFactor( 1.0 ),
2929
mRasterScaleFactor( 1.0 ),
3030
mRendererScale( 1.0 ),
31-
mLabelingEngine( NULL )
31+
mLabelingEngine( NULL ),
32+
mMapToPixelTol( 1.0f )
3233
{
3334

3435
}
@@ -42,3 +43,7 @@ void QgsRenderContext::setCoordinateTransform( const QgsCoordinateTransform* t )
4243
mCoordTransform = t;
4344
}
4445

46+
void QgsRenderContext::setMapToPixelTol( float map2pixelTol )
47+
{
48+
mMapToPixelTol = map2pixelTol;
49+
}

‎src/core/qgsrendercontext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class CORE_EXPORT QgsRenderContext
9595
//! Added in QGIS v2.0
9696
void setSelectionColor( const QColor& color ) { mSelectionColor = color; }
9797

98+
float mapToPixelTol() const { return mMapToPixelTol; }
99+
void setMapToPixelTol( float map2pixelTol );
100+
98101
private:
99102

100103
/**Painter for rendering operations*/
@@ -115,6 +118,8 @@ class CORE_EXPORT QgsRenderContext
115118
bool mUseAdvancedEffects;
116119

117120
QgsMapToPixel mMapToPixel;
121+
/** Tolerance for simplify transformations between map coordinates and device coordinates*/
122+
float mMapToPixelTol;
118123

119124
/**True if the rendering has been canceled*/
120125
bool mRenderingStopped;

‎src/core/qgsvectordataprovider.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ QString QgsVectorDataProvider::capabilitiesString() const
194194
QgsDebugMsg( "Capability: Change Geometries" );
195195
}
196196

197+
if ( abilities & QgsVectorDataProvider::SimplifyGeometries )
198+
{
199+
abilitiesList += tr( "Simplify Geometries" );
200+
QgsDebugMsg( "Capability: Simplify Geometries before fetch the feature" );
201+
}
202+
197203
return abilitiesList.join( ", " );
198204

199205
}

‎src/core/qgsvectordataprovider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
8686
CreateAttributeIndex = 1 << 12,
8787
/** allows user to select encoding */
8888
SelectEncoding = 1 << 13,
89+
/** supports simplification of geometries before fetch the feature */
90+
SimplifyGeometries = 1 << 14,
8991
};
9092

9193
/** bitmask of all provider's editing capabilities */

‎src/core/qgsvectorlayer.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -687,12 +687,19 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
687687
//do startRender before getFeatures to give renderers the possibility of querying features in the startRender method
688688
mRendererV2->startRender( rendererContext, this );
689689

690-
QgsFeatureIterator fit = getFeatures( QgsFeatureRequest()
691-
.setFilterRect( rendererContext.extent() )
692-
.setSubsetOfAttributes( attributes ) );
690+
QgsFeatureRequest& featureRequest = QgsFeatureRequest()
691+
.setFilterRect( rendererContext.extent() )
692+
.setSubsetOfAttributes( attributes );
693+
694+
// Enable the simplification of the geometries before fetch the features using the current map2pixel context.
695+
featureRequest.setFlags( featureRequest.flags() | QgsFeatureRequest::SimplifyGeometries );
696+
featureRequest.setCoordinateTransform( rendererContext.coordinateTransform() );
697+
featureRequest.setMapToPixel( &rendererContext.mapToPixel() );
698+
featureRequest.setMapToPixelTol( rendererContext.mapToPixelTol() );
693699

694-
if (( mRendererV2->capabilities() & QgsFeatureRendererV2::SymbolLevels )
695-
&& mRendererV2->usingSymbolLevels() )
700+
QgsFeatureIterator fit = getFeatures( featureRequest );
701+
702+
if (( mRendererV2->capabilities() & QgsFeatureRendererV2::SymbolLevels ) && mRendererV2->usingSymbolLevels() )
696703
drawRendererV2Levels( fit, rendererContext, labeling );
697704
else
698705
drawRendererV2( fit, rendererContext, labeling );
@@ -1209,6 +1216,9 @@ QgsFeatureIterator QgsVectorLayer::getFeatures( const QgsFeatureRequest& request
12091216
if ( !mDataProvider )
12101217
return QgsFeatureIterator();
12111218

1219+
if ( request.flags() & QgsFeatureRequest::SimplifyGeometries )
1220+
return QgsFeatureIterator( new QgsSimplifiedVectorLayerFeatureIterator( this, request ) );
1221+
12121222
return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, request ) );
12131223
}
12141224

‎src/core/qgsvectorlayerfeatureiterator.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,3 +585,42 @@ void QgsVectorLayerFeatureIterator::updateFeatureGeometry( QgsFeature &f )
585585
if ( mChangedGeometries.contains( f.id() ) )
586586
f.setGeometry( mChangedGeometries[f.id()] );
587587
}
588+
589+
/***************************************************************************
590+
MapToPixel simplification classes
591+
----------------------
592+
begin : October 2013
593+
copyright : (C) 2013 by Alvaro Huarte
594+
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
595+
596+
***************************************************************************
597+
* *
598+
* This program is free software; you can redistribute it and/or modify *
599+
* it under the terms of the GNU General Public License as published by *
600+
* the Free Software Foundation; either version 2 of the License, or *
601+
* (at your option) any later version. *
602+
* *
603+
***************************************************************************/
604+
605+
QgsSimplifiedVectorLayerFeatureIterator::QgsSimplifiedVectorLayerFeatureIterator( QgsVectorLayer* layer, const QgsFeatureRequest& request )
606+
: QgsVectorLayerFeatureIterator( layer, request )
607+
{
608+
mSupportsPresimplify = layer->dataProvider()->capabilities() & QgsVectorDataProvider::SimplifyGeometries;
609+
}
610+
QgsSimplifiedVectorLayerFeatureIterator::~QgsSimplifiedVectorLayerFeatureIterator()
611+
{
612+
}
613+
614+
//! fetch next feature, return true on success
615+
bool QgsSimplifiedVectorLayerFeatureIterator::fetchFeature( QgsFeature& feature )
616+
{
617+
if (QgsVectorLayerFeatureIterator::fetchFeature( feature ))
618+
{
619+
const QgsMapToPixel* mtp = mRequest.mapToPixel();
620+
if ( mtp && !mSupportsPresimplify ) mRequest.simplifyGeometry( feature.geometry() );
621+
return true;
622+
}
623+
return false;
624+
}
625+
626+
/***************************************************************************/

‎src/core/qgsvectorlayerfeatureiterator.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,38 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
116116
QMap<QgsVectorLayer*, FetchJoinInfo> mFetchJoinInfo;
117117
};
118118

119+
/***************************************************************************
120+
MapToPixel simplification classes
121+
----------------------
122+
begin : October 2013
123+
copyright : (C) 2013 by Alvaro Huarte
124+
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
125+
126+
***************************************************************************
127+
* *
128+
* This program is free software; you can redistribute it and/or modify *
129+
* it under the terms of the GNU General Public License as published by *
130+
* the Free Software Foundation; either version 2 of the License, or *
131+
* (at your option) any later version. *
132+
* *
133+
***************************************************************************/
134+
135+
//! Provides a specialized VectorLayerFeatureIterator for enable map2pixel simplification of the geometries
136+
class CORE_EXPORT QgsSimplifiedVectorLayerFeatureIterator : public QgsVectorLayerFeatureIterator
137+
{
138+
public:
139+
QgsSimplifiedVectorLayerFeatureIterator( QgsVectorLayer* layer, const QgsFeatureRequest& request );
140+
~QgsSimplifiedVectorLayerFeatureIterator( );
141+
142+
protected:
143+
//! fetch next feature, return true on success
144+
virtual bool fetchFeature( QgsFeature& feature );
145+
146+
private:
147+
//! Indicates the related vector provider supports simplify the geometries before fecth the feature
148+
bool mSupportsPresimplify;
149+
};
150+
151+
/***************************************************************************/
152+
119153
#endif // QGSVECTORLAYERFEATUREITERATOR_H

‎src/core/symbology-ng/qgsfillsymbollayerv2.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ void QgsSimpleFillSymbolLayerV2::renderPolygon( const QPolygonF& points, QList<Q
182182
p->translate( offset );
183183
}
184184

185-
_renderPolygon( p, points, rings );
185+
_renderPolygon( p, points, rings, context );
186186

187187
if ( !mOffset.isNull() )
188188
{
@@ -313,7 +313,7 @@ void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPol
313313
//if ( ! selectionIsOpaque )
314314
// selColor.setAlphaF( context.alpha() );
315315
p->setBrush( QBrush( selColor ) );
316-
_renderPolygon( p, points, rings );
316+
_renderPolygon( p, points, rings, context );
317317
}
318318

319319
if ( qgsDoubleNear( mNextAngle, 0.0 ) )
@@ -328,7 +328,7 @@ void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPol
328328
rotatedBrush.setTransform( t );
329329
p->setBrush( rotatedBrush );
330330
}
331-
_renderPolygon( p, points, rings );
331+
_renderPolygon( p, points, rings, context );
332332
if ( mOutline )
333333
{
334334
mOutline->renderPolyline( points, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() );

‎src/core/symbology-ng/qgslinesymbollayerv2.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
180180

181181
p->setPen( context.selected() ? mSelPen : mPen );
182182

183+
// Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #2 points).
184+
if ( points.size()<=2 && QgsMapRequest::canbeGeneralizedByWndBoundingBox( points, context.renderContext().mapToPixelTol() ) && p->renderHints() & QPainter::Antialiasing )
185+
{
186+
p->setRenderHint( QPainter::Antialiasing, false );
187+
p->drawPolyline ( points );
188+
p->setRenderHint( QPainter::Antialiasing, true );
189+
return;
190+
}
191+
183192
if ( offset == 0 )
184193
{
185194
p->drawPolyline( points );

‎src/core/symbology-ng/qgsrendererv2.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRe
6767
wkb += sizeof( unsigned int );
6868

6969
bool hasZValue = ( wkbType == QGis::WKBLineString25D );
70+
71+
int sizeOfDoubleX = sizeof(double);
72+
int sizeOfDoubleY = hasZValue ? 2*sizeof(double) : sizeof(double);
73+
7074
double x, y;
7175
const QgsCoordinateTransform* ct = context.coordinateTransform();
7276
const QgsMapToPixel& mtp = context.mapToPixel();
@@ -86,13 +90,8 @@ const unsigned char* QgsFeatureRendererV2::_getLineString( QPolygonF& pts, QgsRe
8690
QPointF* ptr = pts.data();
8791
for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
8892
{
89-
x = *(( double * ) wkb );
90-
wkb += sizeof( double );
91-
y = *(( double * ) wkb );
92-
wkb += sizeof( double );
93-
94-
if ( hasZValue ) // ignore Z value
95-
wkb += sizeof( double );
93+
x = *(( double * ) wkb ); wkb += sizeOfDoubleX;
94+
y = *(( double * ) wkb ); wkb += sizeOfDoubleY;
9695

9796
*ptr = QPointF( x, y );
9897
}
@@ -126,6 +125,10 @@ const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QP
126125
return wkb;
127126

128127
bool hasZValue = ( wkbType == QGis::WKBPolygon25D );
128+
129+
int sizeOfDoubleX = sizeof(double);
130+
int sizeOfDoubleY = hasZValue ? 2*sizeof(double) : sizeof(double);
131+
129132
double x, y;
130133
holes.clear();
131134

@@ -146,20 +149,18 @@ const unsigned char* QgsFeatureRendererV2::_getPolygon( QPolygonF& pts, QList<QP
146149
QPointF* ptr = poly.data();
147150
for ( unsigned int jdx = 0; jdx < nPoints; ++jdx, ++ptr )
148151
{
149-
x = *(( double * ) wkb ); wkb += sizeof( double );
150-
y = *(( double * ) wkb ); wkb += sizeof( double );
152+
x = *(( double * ) wkb ); wkb += sizeOfDoubleX;
153+
y = *(( double * ) wkb ); wkb += sizeOfDoubleY;
151154

152155
*ptr = QPointF( x, y );
153-
154-
if ( hasZValue )
155-
wkb += sizeof( double );
156156
}
157157

158158
if ( nPoints < 1 )
159159
continue;
160160

161-
//clip close to view extent
162-
QgsClipper::trimPolygon( poly, clipRect );
161+
//clip close to view extent, if needed
162+
QRectF ptsRect = poly.boundingRect();
163+
if (!context.extent().contains( ptsRect )) QgsClipper::trimPolygon( poly, clipRect );
163164

164165
//transform the QPolygonF to screen coordinates
165166
if ( ct )

‎src/core/symbology-ng/qgssymbollayerv2.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,22 @@ void QgsFillSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, Q
324324
stopRender( context );
325325
}
326326

327-
void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings )
327+
void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
328328
{
329329
if ( !p )
330330
{
331331
return;
332332
}
333333

334+
// Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
335+
if ( points.size()<=5 && QgsMapRequest::canbeGeneralizedByWndBoundingBox( points, context.renderContext().mapToPixelTol() ) && p->renderHints() & QPainter::Antialiasing )
336+
{
337+
p->setRenderHint( QPainter::Antialiasing, false );
338+
p->drawPolygon( points );
339+
p->setRenderHint( QPainter::Antialiasing, true );
340+
return;
341+
}
342+
334343
if ( rings == NULL )
335344
{
336345
// simple polygon without holes

‎src/core/symbology-ng/qgssymbollayerv2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ class CORE_EXPORT QgsFillSymbolLayerV2 : public QgsSymbolLayerV2
231231
protected:
232232
QgsFillSymbolLayerV2( bool locked = false );
233233
/**Default method to render polygon*/
234-
void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings );
234+
void _renderPolygon( QPainter* p, const QPolygonF& points, const QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
235235

236236
double mAngle;
237237
};

‎src/providers/ogr/qgsogrfeatureiterator.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,15 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
233233

234234
if ( geom )
235235
{
236+
notifyReadedFeature( fet, geom, feature );
237+
236238
// get the wkb representation
237239
unsigned char *wkb = new unsigned char[OGR_G_WkbSize( geom )];
238240
OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );
239241

240242
feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) );
243+
244+
notifyLoadedFeature( fet, feature );
241245
}
242246
if (( useIntersect && ( !feature.geometry() || !feature.geometry()->intersects( mRequest.filterRect() ) ) )
243247
|| ( geometryTypeFilter && ( !feature.geometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry()->wkbType() ) != P->mOgrGeometryTypeFilter ) ) )
@@ -272,3 +276,54 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
272276

273277
return true;
274278
}
279+
280+
//! notify the OGRFeatureH was readed of the data provider
281+
void QgsOgrFeatureIterator::notifyReadedFeature( OGRFeatureH fet, OGRGeometryH geom, QgsFeature& feature )
282+
{
283+
}
284+
//! notify the OGRFeatureH was loaded to the QgsFeature object
285+
void QgsOgrFeatureIterator::notifyLoadedFeature( OGRFeatureH fet, QgsFeature& feature )
286+
{
287+
}
288+
289+
/***************************************************************************
290+
MapToPixel simplification classes
291+
----------------------
292+
begin : October 2013
293+
copyright : (C) 2013 by Alvaro Huarte
294+
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
295+
296+
***************************************************************************
297+
* *
298+
* This program is free software; you can redistribute it and/or modify *
299+
* it under the terms of the GNU General Public License as published by *
300+
* the Free Software Foundation; either version 2 of the License, or *
301+
* (at your option) any later version. *
302+
* *
303+
***************************************************************************/
304+
305+
//! Provides a specialized FeatureIterator for enable map2pixel simplification of the geometries
306+
QgsOgrSimplifiedFeatureIterator::QgsOgrSimplifiedFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request ) : QgsOgrFeatureIterator( p, request )
307+
{
308+
}
309+
QgsOgrSimplifiedFeatureIterator::~QgsOgrSimplifiedFeatureIterator( )
310+
{
311+
}
312+
313+
//! notify the OGRFeatureH was readed of the data provider
314+
void QgsOgrSimplifiedFeatureIterator::notifyReadedFeature( OGRFeatureH fet, OGRGeometryH geom, QgsFeature& feature )
315+
{
316+
/* TODO: ### ahuarte47!
317+
if ( mRequest.flags() & QgsFeatureRequest::SimplifyGeometries )
318+
{
319+
OGRwkbGeometryType wkbType = OGR_G_GetGeometryType( geom );
320+
OGRwkbGeometryType wkbGeometryType = QgsOgrProvider::ogrWkbSingleFlatten( wkbType );
321+
322+
if (wkbGeometryType==wkbLineString || wkbGeometryType==wkbPolygon)
323+
{
324+
}
325+
}*/
326+
QgsOgrFeatureIterator::notifyReadedFeature( fet, geom, feature );
327+
}
328+
329+
/***************************************************************************/

‎src/providers/ogr/qgsogrfeatureiterator.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIterator
4747
//! Get an attribute associated with a feature
4848
void getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex );
4949

50+
//! notify the OGRFeatureH was readed of the data provider
51+
virtual void notifyReadedFeature( OGRFeatureH fet, OGRGeometryH geom, QgsFeature& feature );
52+
//! notify the OGRFeatureH was loaded to the QgsFeature object
53+
virtual void notifyLoadedFeature( OGRFeatureH fet, QgsFeature& feature );
54+
5055
bool mFeatureFetched;
5156

5257
OGRDataSourceH ogrDataSource;
@@ -58,5 +63,34 @@ class QgsOgrFeatureIterator : public QgsAbstractFeatureIterator
5863
bool mFetchGeometry;
5964
};
6065

66+
/***************************************************************************
67+
MapToPixel simplification classes
68+
----------------------
69+
begin : October 2013
70+
copyright : (C) 2013 by Alvaro Huarte
71+
email : http://wiki.osgeo.org/wiki/Alvaro_Huarte
72+
73+
***************************************************************************
74+
* *
75+
* This program is free software; you can redistribute it and/or modify *
76+
* it under the terms of the GNU General Public License as published by *
77+
* the Free Software Foundation; either version 2 of the License, or *
78+
* (at your option) any later version. *
79+
* *
80+
***************************************************************************/
81+
82+
//! Provides a specialized FeatureIterator for enable map2pixel simplification of the geometries
83+
class QgsOgrSimplifiedFeatureIterator : public QgsOgrFeatureIterator
84+
{
85+
public:
86+
QgsOgrSimplifiedFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request );
87+
~QgsOgrSimplifiedFeatureIterator( );
88+
89+
protected:
90+
//! notify the OGRFeatureH was readed of the data provider
91+
virtual void notifyReadedFeature( OGRFeatureH fet, OGRGeometryH geom, QgsFeature& feature );
92+
};
93+
94+
/***************************************************************************/
6195

6296
#endif // QGSOGRFEATUREITERATOR_H

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,10 @@ void QgsOgrProvider::setRelevantFields( bool fetchGeometry, const QgsAttributeLi
749749

750750
QgsFeatureIterator QgsOgrProvider::getFeatures( const QgsFeatureRequest& request )
751751
{
752+
/* TODO: ### ahuarte47!
753+
if ( request.flags() & QgsFeatureRequest::SimplifyGeometries )
754+
return QgsFeatureIterator( new QgsOgrSimplifiedFeatureIterator( this, request ) );
755+
*/
752756
return QgsFeatureIterator( new QgsOgrFeatureIterator( this, request ) );
753757
}
754758

@@ -1484,6 +1488,10 @@ int QgsOgrProvider::capabilities() const
14841488
ability &= ~( AddAttributes | DeleteFeatures );
14851489
}
14861490
}
1491+
1492+
// TODO: ### ahuarte47!
1493+
// By default, supports simplification of geometries before fetch the OGR-feature.
1494+
// ability |= SimplifyGeometries;
14871495
}
14881496

14891497
return ability;

0 commit comments

Comments
 (0)
Please sign in to comment.