Skip to content

Commit 17cd09a

Browse files
committed
Merge pull request #980 from ahuarte47/Issue_8725-OGR
Feature #8725: Fast rendering of geometries
2 parents 052b2eb + 9195356 commit 17cd09a

40 files changed

+1814
-56
lines changed

i18n/qgis_es.ts

+20
Original file line numberDiff line numberDiff line change
@@ -49496,6 +49496,10 @@ Should the existing classes be deleted before classification?</source>
4949649496
<source>General</source>
4949749497
<translation>General</translation>
4949849498
</message>
49499+
<message>
49500+
<source>Rendering</source>
49501+
<translation>Representación</translation>
49502+
</message>
4949949503
<message>
4950049504
<source>Display name</source>
4950149505
<translation type="obsolete">Mostrar el nombre</translation>
@@ -49944,6 +49948,22 @@ Should the existing classes be deleted before classification?</source>
4994449948
<source>Type</source>
4994549949
<translation>Tipo</translation>
4994649950
</message>
49951+
<message>
49952+
<source>Fast drawing</source>
49953+
<translation>Pintado rápido</translation>
49954+
</message>
49955+
<message>
49956+
<source>&lt;b&gt;Note:&lt;/b&gt; This option enables geometry simplification drawing for fast rendering of the layer.</source>
49957+
<translation>&lt;b&gt;Nota:&lt;/b&gt; Esta opción activa el pintado simplificado de las geometrías para acelerar la representación de la capa.</translation>
49958+
</message>
49959+
<message>
49960+
<source>Simplification factor (Higher value draws more simplified geometries): </source>
49961+
<translation>Factor de simplificación (Cuanto mayor es el valor más se simplifica la geometría): </translation>
49962+
</message>
49963+
<message>
49964+
<source>Higher value draws more simplified geometries</source>
49965+
<translation>Cuanto mayor es el valor más se simplifica la geometría</translation>
49966+
</message>
4994749967
</context>
4994849968
<context>
4994949969
<name>QgsVectorLayerSaveAsDialog</name>

python/core/symbology-ng/qgssymbollayerv2.sip

+1-1
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/app/qgsoptions.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
560560
chkAntiAliasing->setChecked( settings.value( "/qgis/enable_anti_aliasing", true ).toBool() );
561561
chkUseRenderCaching->setChecked( settings.value( "/qgis/enable_render_caching", false ).toBool() );
562562

563+
// Default simplify drawing configuration
564+
mSimplifyDrawingGroupBox->setChecked( settings.value( "/qgis/simplifyDrawingHints", (int)QgsVectorLayer::DefaultSimplification ).toInt() != QgsVectorLayer::NoSimplification );
565+
mSimplifyDrawingSlider->setValue( (int)(5.0f * (settings.value( "/qgis/simplifyDrawingTol", QGis::DEFAULT_MAPTOPIXEL_THRESHOLD ).toFloat()-1)) );
566+
mSimplifyDrawingPanel->setVisible( mSimplifyDrawingSlider->value()>0 );
567+
563568
// Slightly awkard here at the settings value is true to use QImage,
564569
// but the checkbox is true to use QPixmap
565570
chkUseQPixmap->setChecked( !( settings.value( "/qgis/use_qimage_to_render", true ).toBool() ) );
@@ -1091,6 +1096,16 @@ void QgsOptions::saveOptions()
10911096
bool legendLayersCapitalise = settings.value( "/qgis/capitaliseLayerName", false ).toBool();
10921097
settings.setValue( "/qgis/capitaliseLayerName", capitaliseCheckBox->isChecked() );
10931098

1099+
// Default simplify drawing configuration
1100+
int simplifyDrawingHints = QgsVectorLayer::NoSimplification;
1101+
if ( mSimplifyDrawingGroupBox->isChecked() )
1102+
{
1103+
simplifyDrawingHints |= QgsVectorLayer::DefaultSimplification;
1104+
if ( mSimplifyDrawingSlider->value() > 0 ) simplifyDrawingHints |= QgsVectorLayer::AntialiasingSimplification;
1105+
}
1106+
settings.setValue( "/qgis/simplifyDrawingHints", simplifyDrawingHints );
1107+
settings.setValue( "/qgis/simplifyDrawingTol", 1.0f + 0.2f*mSimplifyDrawingSlider->value() );
1108+
10941109
// project
10951110
settings.setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() );
10961111
settings.setValue( "/qgis/projOpenAtLaunchPath", mProjectOnLaunchLineEdit->text() );
@@ -2063,3 +2078,8 @@ void QgsOptions::saveDefaultDatumTransformations()
20632078
s.endGroup();
20642079
}
20652080

2081+
void QgsOptions::on_mSimplifyDrawingSlider_valueChanged( int value )
2082+
{
2083+
mSimplifyDrawingPanel->setVisible( value>0 );
2084+
}
2085+

src/app/qgsoptions.h

+2
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
235235
void on_mRemoveDefaultTransformButton_clicked();
236236
void on_mAddDefaultTransformButton_clicked();
237237

238+
void on_mSimplifyDrawingSlider_valueChanged( int value );
239+
238240
private:
239241
QStringList i18nList();
240242
void initContrastEnhancement( QComboBox *cbox, QString name, QString defaultVal );

src/app/qgsvectorlayerproperties.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,11 @@ void QgsVectorLayerProperties::syncToLayer( void )
392392
cbMinimumScale->setScale( 1.0 / layer->minimumScale() );
393393
cbMaximumScale->setScale( 1.0 / layer->maximumScale() );
394394

395+
// get simplify drawing configuration
396+
mSimplifyDrawingGroupBox->setChecked( layer->simplifyDrawingHints() != QgsVectorLayer::NoSimplification );
397+
mSimplifyDrawingSlider->setValue( (int)(5.0f * (layer->simplifyDrawingTol()-1)) );
398+
mSimplifyDrawingPanel->setVisible( mSimplifyDrawingSlider->value()>0 );
399+
395400
// load appropriate symbology page (V1 or V2)
396401
updateSymbologyPage();
397402

@@ -529,6 +534,16 @@ void QgsVectorLayerProperties::apply()
529534
layer->setMetadataUrlType( mLayerMetadataUrlTypeComboBox->currentText() );
530535
layer->setMetadataUrlFormat( mLayerMetadataUrlFormatComboBox->currentText() );
531536

537+
//layer simplify drawing configuration
538+
int simplifyDrawingHints = QgsVectorLayer::NoSimplification;
539+
if ( mSimplifyDrawingGroupBox->isChecked() )
540+
{
541+
simplifyDrawingHints |= QgsVectorLayer::DefaultSimplification;
542+
if ( mSimplifyDrawingSlider->value() > 0 ) simplifyDrawingHints |= QgsVectorLayer::AntialiasingSimplification;
543+
}
544+
layer->setSimplifyDrawingHints( simplifyDrawingHints );
545+
layer->setSimplifyDrawingTol( 1.0f + 0.2f*mSimplifyDrawingSlider->value() );
546+
532547
// update symbology
533548
emit refreshLegend( layer->id(), QgsLegendItem::DontChange );
534549

@@ -1067,3 +1082,8 @@ void QgsVectorLayerProperties::on_mMaximumScaleSetCurrentPushButton_clicked()
10671082
{
10681083
cbMaximumScale->setScale( 1.0 / QgisApp::instance()->mapCanvas()->mapRenderer()->scale() );
10691084
}
1085+
1086+
void QgsVectorLayerProperties::on_mSimplifyDrawingSlider_valueChanged( int value )
1087+
{
1088+
mSimplifyDrawingPanel->setVisible( value>0 );
1089+
}

src/app/qgsvectorlayerproperties.h

+2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
119119
void on_mMinimumScaleSetCurrentPushButton_clicked();
120120
void on_mMaximumScaleSetCurrentPushButton_clicked();
121121

122+
void on_mSimplifyDrawingSlider_valueChanged( int value );
123+
122124
signals:
123125

124126
/** emitted when changes to layer were saved to update legend */

src/core/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ SET(QGIS_CORE_SRCS
7474
qgsgeometry.cpp
7575
qgsgeometrycache.cpp
7676
qgsgeometryvalidator.cpp
77+
qgsgeometrysimplifier.cpp
7778
qgsgml.cpp
7879
qgsgmlschema.cpp
7980
qgshttptransaction.cpp
@@ -85,6 +86,7 @@ SET(QGIS_CORE_SRCS
8586
qgsmaplayerregistry.cpp
8687
qgsmaprenderer.cpp
8788
qgsmaptopixel.cpp
89+
qgsmaptopixelgeometrysimplifier.cpp
8890
qgsmessageoutput.cpp
8991
qgsmimedatautils.cpp
9092
qgsmessagelog.cpp

src/core/composer/qgscomposermap.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -199,13 +199,14 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
199199
{
200200
theRendererContext->setDrawEditingInformation( false );
201201
theRendererContext->setRenderingStopped( false );
202-
}
202+
theRendererContext->setRenderingPrintComposition( true );
203203

204-
// force vector output (no caching of marker images etc.)
205-
theRendererContext->setForceVectorOutput( true );
204+
// force vector output (no caching of marker images etc.)
205+
theRendererContext->setForceVectorOutput( true );
206206

207-
// make the renderer respect the composition's useAdvancedEffects flag
208-
theRendererContext->setUseAdvancedEffects( mComposition->useAdvancedEffects() );
207+
// make the renderer respect the composition's useAdvancedEffects flag
208+
theRendererContext->setUseAdvancedEffects( mComposition->useAdvancedEffects() );
209+
}
209210

210211
//force composer map scale for scale dependent visibility
211212
double bk_scale = theMapRenderer.scale();

src/core/qgis.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ const CORE_EXPORT QString GEO_NONE = "NONE";
7373

7474
const double QGis::DEFAULT_IDENTIFY_RADIUS = 0.5;
7575

76+
//! Default threshold between map coordinates and device coordinates for map2pixel simplification
77+
const float QGis::DEFAULT_MAPTOPIXEL_THRESHOLD = 1.0f;
78+
7679
// description strings for units
7780
// Order must match enum indices
7881
const char* QGis::qgisUnitTypes[] =

src/core/qgis.h

+3
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ class CORE_EXPORT QGis
263263

264264
static const double DEFAULT_IDENTIFY_RADIUS;
265265

266+
//! Default threshold between map coordinates and device coordinates for map2pixel simplification
267+
static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
268+
266269
private:
267270
// String representation of unit types (set in qgis.cpp)
268271
static const char *qgisUnitTypes[];

src/core/qgsclipper.cpp

+8-16
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

+33
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ QgsFeatureRequest::QgsFeatureRequest()
2323
: mFilter( FilterNone )
2424
, mFilterExpression( 0 )
2525
, mFlags( 0 )
26+
, mMapCoordTransform( NULL )
27+
, mMapToPixel( NULL )
28+
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
2629
{
2730
}
2831

@@ -31,6 +34,9 @@ QgsFeatureRequest::QgsFeatureRequest( QgsFeatureId fid )
3134
, mFilterFid( fid )
3235
, mFilterExpression( 0 )
3336
, mFlags( 0 )
37+
, mMapCoordTransform( NULL )
38+
, mMapToPixel( NULL )
39+
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
3440
{
3541
}
3642

@@ -39,13 +45,19 @@ QgsFeatureRequest::QgsFeatureRequest( const QgsRectangle& rect )
3945
, mFilterRect( rect )
4046
, mFilterExpression( 0 )
4147
, mFlags( 0 )
48+
, mMapCoordTransform( NULL )
49+
, mMapToPixel( NULL )
50+
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
4251
{
4352
}
4453

4554
QgsFeatureRequest::QgsFeatureRequest( const QgsExpression& expr )
4655
: mFilter( FilterExpression )
4756
, mFilterExpression( new QgsExpression( expr.expression() ) )
4857
, mFlags( 0 )
58+
, mMapCoordTransform( NULL )
59+
, mMapToPixel( NULL )
60+
, mMapToPixelTol( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD )
4961
{
5062
}
5163

@@ -70,6 +82,9 @@ QgsFeatureRequest& QgsFeatureRequest::operator=( const QgsFeatureRequest & rh )
7082
mFilterExpression = 0;
7183
}
7284
mAttrs = rh.mAttrs;
85+
mMapCoordTransform = rh.mMapCoordTransform;
86+
mMapToPixel = rh.mMapToPixel;
87+
mMapToPixelTol = rh.mMapToPixelTol;
7388
return *this;
7489
}
7590

@@ -174,3 +189,21 @@ bool QgsFeatureRequest::acceptFeature( const QgsFeature& feature )
174189

175190
return true;
176191
}
192+
193+
QgsFeatureRequest& QgsFeatureRequest::setCoordinateTransform( const QgsCoordinateTransform* ct )
194+
{
195+
mMapCoordTransform = ct;
196+
return *this;
197+
}
198+
199+
QgsFeatureRequest& QgsFeatureRequest::setMapToPixel( const QgsMapToPixel* mtp )
200+
{
201+
mMapToPixel = mtp;
202+
return *this;
203+
}
204+
205+
QgsFeatureRequest& QgsFeatureRequest::setMapToPixelTol( float map2pixelTol )
206+
{
207+
mMapToPixelTol = map2pixelTol;
208+
return *this;
209+
}

src/core/qgsfeaturerequest.h

+22-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include "qgsrectangle.h"
2222
#include "qgsexpression.h"
2323

24+
#include "qgscoordinatetransform.h"
25+
#include "qgsmaptopixel.h"
26+
2427
#include <QList>
2528
typedef QList<int> QgsAttributeList;
2629

@@ -61,7 +64,9 @@ class CORE_EXPORT QgsFeatureRequest
6164
NoFlags = 0,
6265
NoGeometry = 1, //!< Geometry is not required. It may still be returned if e.g. required for a filter condition.
6366
SubsetOfAttributes = 2, //!< Fetch only a subset of attributes (setSubsetOfAttributes sets this flag)
64-
ExactIntersect = 4 //!< Use exact geometry intersection (slower) instead of bounding boxes
67+
ExactIntersect = 4, //!< Use exact geometry intersection (slower) instead of bounding boxes
68+
SimplifyGeometry = 8, //!< The geometries can be simplified using the current map2pixel context state (e.g. for fast rendering...)
69+
SimplifyEnvelope = 16 //!< The geometries can be fully simplified by its BoundingBox (e.g. for fast rendering...)
6570
};
6671
Q_DECLARE_FLAGS( Flags, Flag )
6772

@@ -135,6 +140,15 @@ class CORE_EXPORT QgsFeatureRequest
135140
// void setFilterNativeExpression(con QString& expr); // using provider's SQL (if supported)
136141
// void setLimit(int limit);
137142

143+
const QgsCoordinateTransform* coordinateTransform() const { return mMapCoordTransform; }
144+
QgsFeatureRequest& setCoordinateTransform( const QgsCoordinateTransform* ct );
145+
146+
const QgsMapToPixel* mapToPixel() const { return mMapToPixel; }
147+
QgsFeatureRequest& setMapToPixel( const QgsMapToPixel* mtp );
148+
149+
float mapToPixelTol() const { return mMapToPixelTol; }
150+
QgsFeatureRequest& setMapToPixelTol( float map2pixelTol );
151+
138152
protected:
139153
FilterType mFilter;
140154
QgsRectangle mFilterRect;
@@ -143,6 +157,13 @@ class CORE_EXPORT QgsFeatureRequest
143157
QgsExpression* mFilterExpression;
144158
Flags mFlags;
145159
QgsAttributeList mAttrs;
160+
161+
//! For transformation between coordinate systems from current layer to map target. Can be 0 if on-the-fly reprojection is not used
162+
const QgsCoordinateTransform* mMapCoordTransform;
163+
//! For transformation between map coordinates and device coordinates
164+
const QgsMapToPixel* mMapToPixel;
165+
//! Factor tolterance to apply in transformation between map coordinates and device coordinates
166+
float mMapToPixelTol;
146167
};
147168

148169
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureRequest::Flags )

0 commit comments

Comments
 (0)