diff --git a/python/core/qgsvectorlayer.sip b/python/core/qgsvectorlayer.sip index 1bd1acf1a1b..557c2c3c096 100644 --- a/python/core/qgsvectorlayer.sip +++ b/python/core/qgsvectorlayer.sip @@ -1013,7 +1013,7 @@ class QgsVectorLayer : QgsMapLayer const QgsVectorSimplifyMethod& simplifyMethod() const; /** Returns whether the VectorLayer can apply the specified simplification hint */ - bool simplifyDrawingCanbeApplied( int simplifyHint ) const; + bool simplifyDrawingCanbeApplied( const QgsRenderContext& renderContext, int simplifyHint ) const; public slots: /** diff --git a/python/core/qgsvectorsimplifymethod.sip b/python/core/qgsvectorsimplifymethod.sip index 61a4ef665fa..7b9ed3167a6 100644 --- a/python/core/qgsvectorsimplifymethod.sip +++ b/python/core/qgsvectorsimplifymethod.sip @@ -26,4 +26,9 @@ class QgsVectorSimplifyMethod void setForceLocalOptimization( bool localOptimization ); /** Gets where the simplification executes, after fetch the geometries from provider, or when supported, in provider before fetch the geometries */ bool forceLocalOptimization(); + + /** Sets the maximum scale at which the layer should be simplified */ + void setMaximumScale( float maximumScale ); + /** Gets the maximum scale at which the layer should be simplified */ + float maximumScale() const; }; diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index b101bc324c6..2d72fbcf1d7 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -570,6 +570,11 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) : mSimplifyDrawingSpinBox->setValue( settings.value( "/qgis/simplifyDrawingTol", QGis::DEFAULT_MAPTOPIXEL_THRESHOLD ).toFloat() ); mSimplifyDrawingAtProvider->setChecked( !settings.value( "/qgis/simplifyLocal", true ).toBool() ); + QStringList myScalesList = PROJECT_SCALES.split( "," ); + myScalesList.append( "1:1" ); + mSimplifyMaximumScaleComboBox->updateScales( myScalesList ); + mSimplifyMaximumScaleComboBox->setScale( 1.0 / settings.value( "/qgis/simplifyMaxScale", 1 ).toFloat() ); + // Slightly awkard here at the settings value is true to use QImage, // but the checkbox is true to use QPixmap chkUseQPixmap->setChecked( !( settings.value( "/qgis/use_qimage_to_render", true ).toBool() ) ); @@ -1111,6 +1116,7 @@ void QgsOptions::saveOptions() settings.setValue( "/qgis/simplifyDrawingHints", simplifyHints ); settings.setValue( "/qgis/simplifyDrawingTol", mSimplifyDrawingSpinBox->value() ); settings.setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() ); + settings.setValue( "/qgis/simplifyMaxScale", 1.0 / mSimplifyMaximumScaleComboBox->scale() ); // project settings.setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() ); diff --git a/src/app/qgsvectorlayerproperties.cpp b/src/app/qgsvectorlayerproperties.cpp index e24e3011309..3af3c46ecaa 100644 --- a/src/app/qgsvectorlayerproperties.cpp +++ b/src/app/qgsvectorlayerproperties.cpp @@ -416,6 +416,11 @@ void QgsVectorLayerProperties::syncToLayer( void ) mSimplifyDrawingGroupBox->setChecked( false ); } + QStringList myScalesList = PROJECT_SCALES.split( "," ); + myScalesList.append( "1:1" ); + mSimplifyMaximumScaleComboBox->updateScales( myScalesList ); + mSimplifyMaximumScaleComboBox->setScale( 1.0 / simplifyMethod.maximumScale() ); + // load appropriate symbology page (V1 or V2) updateSymbologyPage(); @@ -564,6 +569,7 @@ void QgsVectorLayerProperties::apply() simplifyMethod.setSimplifyHints( simplifyHints ); simplifyMethod.setThreshold( mSimplifyDrawingSpinBox->value() ); simplifyMethod.setForceLocalOptimization( !mSimplifyDrawingAtProvider->isChecked() ); + simplifyMethod.setMaximumScale( 1.0 / mSimplifyMaximumScaleComboBox->scale() ); layer->setSimplifyMethod( simplifyMethod ); // update symbology diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index 9137119317c..2d6ffea47a7 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -187,6 +187,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath, mSimplifyMethod.setSimplifyHints( settings.value( "/qgis/simplifyDrawingHints", mSimplifyMethod.simplifyHints() ).toInt() ); mSimplifyMethod.setThreshold( settings.value( "/qgis/simplifyDrawingTol", mSimplifyMethod.threshold() ).toFloat() ); mSimplifyMethod.setForceLocalOptimization( settings.value( "/qgis/simplifyLocal", mSimplifyMethod.forceLocalOptimization() ).toBool() ); + mSimplifyMethod.setMaximumScale( settings.value( "/qgis/simplifyMaxScale", mSimplifyMethod.maximumScale() ).toFloat() ); } // QgsVectorLayer ctor @@ -701,7 +702,7 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext ) .setSubsetOfAttributes( attributes ); // enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine. - if ( simplifyDrawingCanbeApplied( QgsVectorLayer::GeometrySimplification ) ) + if ( simplifyDrawingCanbeApplied( rendererContext, QgsVectorLayer::GeometrySimplification ) ) { QPainter* p = rendererContext.painter(); double dpi = ( p->device()->logicalDpiX() + p->device()->logicalDpiY() ) / 2; @@ -1256,9 +1257,19 @@ bool QgsVectorLayer::setSubsetString( QString subset ) return res; } -bool QgsVectorLayer::simplifyDrawingCanbeApplied( int simplifyHint ) const +bool QgsVectorLayer::simplifyDrawingCanbeApplied( const QgsRenderContext& renderContext, int simplifyHint ) const { - return mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && ( !mCurrentRendererContext || mCurrentRendererContext->useRenderingOptimization() ); + if ( mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() ) + { + double maximumSimplificationScale = mSimplifyMethod.maximumScale(); + + // check maximum scale at which generalisation should be carried out + if ( maximumSimplificationScale > 1 && renderContext.rendererScale() <= maximumSimplificationScale ) + return false; + + return true; + } + return false; } QgsFeatureIterator QgsVectorLayer::getFeatures( const QgsFeatureRequest& request ) @@ -1873,6 +1884,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage mSimplifyMethod.setSimplifyHints( e.attribute( "simplifyDrawingHints", "1" ).toInt() ); mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() ); mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() ); + mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() ); //also restore custom properties (for labeling-ng) readCustomProperties( node, "labeling" ); @@ -2211,6 +2223,7 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) ); mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) ); mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 ); + mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) ); //save customproperties (for labeling ng) writeCustomProperties( node, doc ); diff --git a/src/core/qgsvectorlayer.h b/src/core/qgsvectorlayer.h index 27d55e38e32..eaa59eb25c8 100644 --- a/src/core/qgsvectorlayer.h +++ b/src/core/qgsvectorlayer.h @@ -1387,7 +1387,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer inline const QgsVectorSimplifyMethod& simplifyMethod() const { return mSimplifyMethod; } /** Returns whether the VectorLayer can apply the specified simplification hint */ - bool simplifyDrawingCanbeApplied( int simplifyHint ) const; + bool simplifyDrawingCanbeApplied( const QgsRenderContext& renderContext, int simplifyHint ) const; public slots: /** diff --git a/src/core/qgsvectorsimplifymethod.cpp b/src/core/qgsvectorsimplifymethod.cpp index b86f89b2c80..9119ce40a4b 100644 --- a/src/core/qgsvectorsimplifymethod.cpp +++ b/src/core/qgsvectorsimplifymethod.cpp @@ -21,6 +21,7 @@ QgsVectorSimplifyMethod::QgsVectorSimplifyMethod() : mSimplifyHints( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD > 1 ? QgsVectorLayer::FullSimplification : QgsVectorLayer::GeometrySimplification ) , mThreshold( QGis::DEFAULT_MAPTOPIXEL_THRESHOLD ) , mLocalOptimization( true ) + , mMaximumScale( 1 ) { } @@ -34,5 +35,6 @@ QgsVectorSimplifyMethod& QgsVectorSimplifyMethod::operator=( const QgsVectorSimp mSimplifyHints = rh.mSimplifyHints; mThreshold = rh.mThreshold; mLocalOptimization = rh.mLocalOptimization; + mMaximumScale = rh.mMaximumScale; return *this; } diff --git a/src/core/qgsvectorsimplifymethod.h b/src/core/qgsvectorsimplifymethod.h index 19673856d4a..6c754c7e5ea 100644 --- a/src/core/qgsvectorsimplifymethod.h +++ b/src/core/qgsvectorsimplifymethod.h @@ -42,6 +42,11 @@ class CORE_EXPORT QgsVectorSimplifyMethod /** Gets where the simplification executes, after fetch the geometries from provider, or when supported, in provider before fetch the geometries */ inline bool forceLocalOptimization() const { return mLocalOptimization; } + /** Sets the maximum scale at which the layer should be simplified */ + void setMaximumScale( float maximumScale ) { mMaximumScale = maximumScale; } + /** Gets the maximum scale at which the layer should be simplified */ + inline float maximumScale() const { return mMaximumScale; } + private: /** Simplification hints for fast rendering of features of the vector layer managed */ int mSimplifyHints; @@ -49,6 +54,8 @@ class CORE_EXPORT QgsVectorSimplifyMethod float mThreshold; /** Simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries */ bool mLocalOptimization; + /** Maximum scale at which the layer should be simplified (Maximum scale at which generalisation should be carried out) */ + float mMaximumScale; }; #endif // QGSVECTORSIMPLIFYMETHOD_H diff --git a/src/core/symbology-ng/qgslinesymbollayerv2.cpp b/src/core/symbology-ng/qgslinesymbollayerv2.cpp index 3eec4269f40..1ac0fce42f6 100644 --- a/src/core/symbology-ng/qgslinesymbollayerv2.cpp +++ b/src/core/symbology-ng/qgslinesymbollayerv2.cpp @@ -188,7 +188,7 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym p->setPen( context.selected() ? mSelPen : mPen ); // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #2 points). - if ( points.size() <= 2 && context.layer() && context.layer()->simplifyDrawingCanbeApplied( QgsVectorLayer::AntialiasingSimplification ) && QgsAbstractGeometrySimplifier::canbeGeneralizedByDeviceBoundingBox( points, context.layer()->simplifyMethod().threshold() ) && ( p->renderHints() & QPainter::Antialiasing ) ) + if ( points.size() <= 2 && context.layer() && context.layer()->simplifyDrawingCanbeApplied( context.renderContext(), QgsVectorLayer::AntialiasingSimplification ) && QgsAbstractGeometrySimplifier::canbeGeneralizedByDeviceBoundingBox( points, context.layer()->simplifyMethod().threshold() ) && ( p->renderHints() & QPainter::Antialiasing ) ) { p->setRenderHint( QPainter::Antialiasing, false ); p->drawPolyline( points ); diff --git a/src/core/symbology-ng/qgssymbollayerv2.cpp b/src/core/symbology-ng/qgssymbollayerv2.cpp index 096984abb10..49703325f32 100644 --- a/src/core/symbology-ng/qgssymbollayerv2.cpp +++ b/src/core/symbology-ng/qgssymbollayerv2.cpp @@ -388,7 +388,7 @@ void QgsFillSymbolLayerV2::_renderPolygon( QPainter* p, const QPolygonF& points, } // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points). - if ( points.size() <= 5 && context.layer() && context.layer()->simplifyDrawingCanbeApplied( QgsVectorLayer::AntialiasingSimplification ) && QgsAbstractGeometrySimplifier::canbeGeneralizedByDeviceBoundingBox( points, context.layer()->simplifyMethod().threshold() ) && ( p->renderHints() & QPainter::Antialiasing ) ) + if ( points.size() <= 5 && context.layer() && context.layer()->simplifyDrawingCanbeApplied( context.renderContext(), QgsVectorLayer::AntialiasingSimplification ) && QgsAbstractGeometrySimplifier::canbeGeneralizedByDeviceBoundingBox( points, context.layer()->simplifyMethod().threshold() ) && ( p->renderHints() & QPainter::Antialiasing ) ) { p->setRenderHint( QPainter::Antialiasing, false ); p->drawRect( points.boundingRect() ); diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui index 443392083fc..cf4716de62a 100644 --- a/src/ui/qgsoptionsbase.ui +++ b/src/ui/qgsoptionsbase.ui @@ -1710,6 +1710,26 @@ + + + + Maximum scale at which the layer should be simplified (1:1 always simplifies): + + + 2 + + + + + + + + 0 + 0 + + + + diff --git a/src/ui/qgsvectorlayerpropertiesbase.ui b/src/ui/qgsvectorlayerpropertiesbase.ui index 06da38f1966..b169960197d 100644 --- a/src/ui/qgsvectorlayerpropertiesbase.ui +++ b/src/ui/qgsvectorlayerpropertiesbase.ui @@ -958,6 +958,26 @@ + + + + Maximum scale at which the layer should be simplified (1:1 always simplifies): + + + 2 + + + + + + + + 0 + 0 + + + +