Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #8725-revival: Fast rendering of geometries with provider simplification support #1053

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
128727d
#8725-R: define UseRenderingOptimization
ahuarte47 Dec 18, 2013
4caed1c
#8725-R: show map2pixel threshold in panels
ahuarte47 Dec 18, 2013
2a6f88c
#8725-R: simplifier execute in rendering loop
ahuarte47 Dec 20, 2013
ffa2e33
#8725-R: define QgsSimplifyMethod
ahuarte47 Dec 24, 2013
cf9e0db
#8725-R: VectorLayer use SimplifyMethod
ahuarte47 Dec 24, 2013
96f96ef
#8725-R: FeatureIterator use SimplifyMethod
ahuarte47 Dec 24, 2013
c91eeab
#8725-R: move VectorSimplifyMethod to other file
ahuarte47 Dec 24, 2013
e9eb476
#8725-R: FeatureIterator and other minor changes
ahuarte47 Dec 26, 2013
40c14c9
#8725-R: OgrProvider simplifies on provider side
ahuarte47 Dec 26, 2013
9f229a8
#8725-R: PostgresProvider simplifies on provider side
ahuarte47 Dec 27, 2013
2fa5c12
#8725-R: New vector provider capability for topological simplification
ahuarte47 Dec 28, 2013
9d70f8c
#8725-R: no simplify point layers in postgres provider
ahuarte47 Dec 28, 2013
aad7589
#8725-R: never simplifying the first two or last two vertices in a line
ahuarte47 Dec 28, 2013
da36461
#8725-R: include qgsvectorsimplifymethod.sip
ahuarte47 Jan 6, 2014
500dfcf
#8725-R: add "Advanced settings" panel
ahuarte47 Jan 7, 2014
c07e7cf
#8725-R: fix old API in testqgsblendmodes.cpp
ahuarte47 Jan 7, 2014
bc6c77a
#8725-R: fix old API in other test cpp files
ahuarte47 Jan 7, 2014
e22279f
#8725-R: refactoring of simplification API in FeatureIterators
ahuarte47 Jan 8, 2014
972a758
#8725-R: simplify edited geometries in QgsVectorLayerFeatureIterator
ahuarte47 Jan 11, 2014
e1f6040
#8725-R: no check 0-pointers to delete
ahuarte47 Jan 13, 2014
1164438
#8725-R: no check geometry pointer twice
ahuarte47 Jan 13, 2014
89c1fea
#8275-R: simplification on a per-iterator basis
ahuarte47 Jan 14, 2014
39225b4
#8725-R: minor changes and UI update
ahuarte47 Jan 14, 2014
c79cafc
#8725-R: minor changes
ahuarte47 Jan 15, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions python/core/core.sip
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
%Include qgsfield.sip
%Include qgsgeometry.sip
%Include qgsgeometryvalidator.sip
%Include qgsgeometrysimplifier.sip
%Include qgsgml.sip
%Include qgsgmlschema.sip
%Include qgshttptransaction.sip
Expand Down Expand Up @@ -75,6 +76,7 @@
%Include qgsrunprocess.sip
%Include qgsscalecalculator.sip
%Include qgsscaleutils.sip
%Include qgssimplifymethod.sip
%Include qgssnapper.sip
%Include qgsspatialindex.sip
%Include qgstolerance.sip
Expand All @@ -86,6 +88,7 @@
%Include qgsvectorlayerimport.sip
%Include qgsvectorlayerjoinbuffer.sip
%Include qgsvectorlayerundocommand.sip
%Include qgsvectorsimplifymethod.sip
%Include qgsfontutils.sip

%Include qgscachedfeatureiterator.sip
Expand Down
23 changes: 23 additions & 0 deletions python/core/qgsgeometrysimplifier.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

/** Abstract base class for simplify geometries using a specific algorithm */
class QgsAbstractGeometrySimplifier
{
%TypeHeaderCode
#include "qgsgeometrysimplifier.h"
%End

public:
virtual ~QgsAbstractGeometrySimplifier();

/** Returns a simplified version the specified geometry */
virtual QgsGeometry* simplify( QgsGeometry* geometry ) const = 0;
/** Simplifies the specified geometry */
virtual bool simplifyGeometry( QgsGeometry* geometry ) const = 0;

// MapToPixel simplification helper methods
public:
/** Returns whether the device-envelope can be replaced by its BBOX when is applied the specified tolerance */
static bool canbeGeneralizedByDeviceBoundingBox( const QgsRectangle& envelope, float mapToPixelTol = 1.0f );
/** Returns whether the device-geometry can be replaced by its BBOX when is applied the specified tolerance */
static bool canbeGeneralizedByDeviceBoundingBox( const QVector<QPointF>& points, float mapToPixelTol = 1.0f );
};
42 changes: 42 additions & 0 deletions python/core/qgssimplifymethod.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

/** This class contains information about how to simplify geometries fetched from a QgsFeatureIterator */
class QgsSimplifyMethod
{
%TypeHeaderCode
#include "qgssimplifymethod.h"
%End

public:
enum MethodType
{
NoSimplification, //!< No simplification is applied
OptimizeForRendering, //!< Simplify using the map2pixel data to optimize the rendering of geometries
PreserveTopology //!< Simplify using the Douglas-Peucker algorithm ensuring that the result is a valid geometry
};

//! construct a default method
QgsSimplifyMethod();
//! copy constructor
QgsSimplifyMethod( const QgsSimplifyMethod& rh );

/** Sets the simplification type */
void setMethodType( MethodType methodType );
/** Gets the simplification type */
MethodType methodType() const;

/** Sets the tolerance of simplification. Represents the maximum distance between two coordinates which can be considered equal */
void setTolerance( double tolerance );
/** Gets the tolerance of simplification */
double tolerance() const;

/** Returns the optimal tolerance for Douglas-Peucker simplification algorithms */
double toleranceForDouglasPeuckerAlgorithms() const;

/** Sets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries */
void setForceLocalOptimization( bool localOptimization );
/** Gets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries */
bool forceLocalOptimization() const;

/** Creates a geometry simplifier according to specified method */
static QgsAbstractGeometrySimplifier* createGeometrySimplifier( const QgsSimplifyMethod& simplifyMethod );
};
19 changes: 6 additions & 13 deletions python/core/qgsvectorlayer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -999,25 +999,18 @@ class QgsVectorLayer : QgsMapLayer
/** @note not available in python bindings */
// inline QgsGeometryCache* cache();

/** Set the Map2pixel simplification threshold for fast rendering of features */
void setSimplifyDrawingTol( float simplifyDrawingTol );
/** Returns the Map2pixel simplification threshold for fast rendering of features */
float simplifyDrawingTol() const;

/** Simplification flags for fast rendering of features */
enum SimplifyHint
{
NoSimplification = 0, //!< No simplification can be applied
GeometrySimplification = 1, //!< The geometries can be simplified using the current map2pixel context state
EnvelopeSimplification = 2, //!< The geometries can be fully simplified by its BoundingBox using the current map2pixel context state
AntialiasingSimplification = 4, //!< The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'
DefaultSimplification = 3, //!< Default simplification hints can be applied ( Geometry + Envelope )
FullSimplification = 7, //!< All simplification hints can be applied ( Geometry + Envelope + AA-disabling )
AntialiasingSimplification = 2, //!< The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'
FullSimplification = 3, //!< All simplification hints can be applied ( Geometry + AA-disabling )
};
/** Set the Map2pixel simplification hints for fast rendering of features */
void setSimplifyDrawingHints( int simplifyDrawingHints );
/** Returns the Map2pixel simplification hints for fast rendering of features */
int simplifyDrawingHints() const;
/** Set the simplification settings for fast rendering of features */
void setSimplifyMethod( const QgsVectorSimplifyMethod& simplifyMethod );
/** Returns the simplification settings for fast rendering of features */
const QgsVectorSimplifyMethod& simplifyMethod() const;

/** Returns whether the VectorLayer can apply the specified simplification hint */
bool simplifyDrawingCanbeApplied( int simplifyHint ) const;
Expand Down
29 changes: 29 additions & 0 deletions python/core/qgsvectorsimplifymethod.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

/** This class contains information how to simplify geometries fetched from a vector layer */
class QgsVectorSimplifyMethod
{
%TypeHeaderCode
#include "qgsvectorsimplifymethod.h"
%End

public:
//! construct a default object
QgsVectorSimplifyMethod();
//! copy constructor
QgsVectorSimplifyMethod( const QgsVectorSimplifyMethod& rh );

/** Sets the simplification hints of the vector layer managed */
void setSimplifyHints( int simplifyHints );
/** Gets the simplification hints of the vector layer managed */
int simplifyHints() const;

/** Sets the simplification threshold of the vector layer managed */
void setThreshold( float threshold );
/** Gets the simplification threshold of the vector layer managed */
float threshold() const;

/** Sets where the simplification executes, after fetch the geometries from provider, or when supported, in provider before fetch the geometries */
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();
};
23 changes: 9 additions & 14 deletions src/app/qgsoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
chkUseRenderCaching->setChecked( settings.value( "/qgis/enable_render_caching", false ).toBool() );

// Default simplify drawing configuration
mSimplifyDrawingGroupBox->setChecked( settings.value( "/qgis/simplifyDrawingHints", ( int )QgsVectorLayer::DefaultSimplification ).toInt() != QgsVectorLayer::NoSimplification );
mSimplifyDrawingSlider->setValue(( int )( 5.0f * ( settings.value( "/qgis/simplifyDrawingTol", QGis::DEFAULT_MAPTOPIXEL_THRESHOLD ).toFloat() - 1 ) ) );
mSimplifyDrawingPanel->setVisible( mSimplifyDrawingSlider->value() > 0 );
mSimplifyDrawingGroupBox->setChecked( settings.value( "/qgis/simplifyDrawingHints", ( int )QgsVectorLayer::GeometrySimplification ).toInt() != QgsVectorLayer::NoSimplification );
mSimplifyDrawingSpinBox->setValue( settings.value( "/qgis/simplifyDrawingTol", QGis::DEFAULT_MAPTOPIXEL_THRESHOLD ).toFloat() );
mSimplifyDrawingAtProvider->setChecked( !settings.value( "/qgis/simplifyLocal", true ).toBool() );

// Slightly awkard here at the settings value is true to use QImage,
// but the checkbox is true to use QPixmap
Expand Down Expand Up @@ -1098,14 +1098,15 @@ void QgsOptions::saveOptions()
settings.setValue( "/qgis/capitaliseLayerName", capitaliseCheckBox->isChecked() );

// Default simplify drawing configuration
int simplifyDrawingHints = QgsVectorLayer::NoSimplification;
int simplifyHints = QgsVectorLayer::NoSimplification;
if ( mSimplifyDrawingGroupBox->isChecked() )
{
simplifyDrawingHints |= QgsVectorLayer::DefaultSimplification;
if ( mSimplifyDrawingSlider->value() > 0 ) simplifyDrawingHints |= QgsVectorLayer::AntialiasingSimplification;
simplifyHints |= QgsVectorLayer::GeometrySimplification;
if ( mSimplifyDrawingSpinBox->value() > 1 ) simplifyHints |= QgsVectorLayer::AntialiasingSimplification;
}
settings.setValue( "/qgis/simplifyDrawingHints", simplifyDrawingHints );
settings.setValue( "/qgis/simplifyDrawingTol", 1.0f + 0.2f*mSimplifyDrawingSlider->value() );
settings.setValue( "/qgis/simplifyDrawingHints", simplifyHints );
settings.setValue( "/qgis/simplifyDrawingTol", mSimplifyDrawingSpinBox->value() );
settings.setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() );

// project
settings.setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() );
Expand Down Expand Up @@ -2084,9 +2085,3 @@ void QgsOptions::saveDefaultDatumTransformations()

s.endGroup();
}

void QgsOptions::on_mSimplifyDrawingSlider_valueChanged( int value )
{
mSimplifyDrawingPanel->setVisible( value > 0 );
}

2 changes: 0 additions & 2 deletions src/app/qgsoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,6 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption
void on_mRemoveDefaultTransformButton_clicked();
void on_mAddDefaultTransformButton_clicked();

void on_mSimplifyDrawingSlider_valueChanged( int value );

private:
QStringList i18nList();
void initContrastEnhancement( QComboBox *cbox, QString name, QString defaultVal );
Expand Down
42 changes: 32 additions & 10 deletions src/app/qgsvectorlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,21 @@ void QgsVectorLayerProperties::syncToLayer( void )
cbMaximumScale->setScale( 1.0 / layer->maximumScale() );

// get simplify drawing configuration
mSimplifyDrawingGroupBox->setChecked( layer->simplifyDrawingHints() != QgsVectorLayer::NoSimplification );
mSimplifyDrawingSlider->setValue(( int )( 5.0f * ( layer->simplifyDrawingTol() - 1 ) ) );
mSimplifyDrawingPanel->setVisible( mSimplifyDrawingSlider->value() > 0 );
const QgsVectorSimplifyMethod& simplifyMethod = layer->simplifyMethod();
mSimplifyDrawingGroupBox->setChecked( simplifyMethod.simplifyHints() != QgsVectorLayer::NoSimplification );
mSimplifyDrawingSpinBox->setValue( simplifyMethod.threshold() );

if ( !( layer->dataProvider()->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) )
{
mSimplifyDrawingAtProvider->setChecked( false );
mSimplifyDrawingAtProvider->setEnabled( false );
mSimplifyDrawingAtProvider->setText( QString( "%1 (%2)" ).arg( mSimplifyDrawingAtProvider->text(), tr( "Not supported" ) ) );
}
else
{
mSimplifyDrawingAtProvider->setChecked( !simplifyMethod.forceLocalOptimization() );
mSimplifyDrawingAtProvider->setEnabled( mSimplifyDrawingGroupBox->isChecked() );
}

// load appropriate symbology page (V1 or V2)
updateSymbologyPage();
Expand Down Expand Up @@ -535,14 +547,17 @@ void QgsVectorLayerProperties::apply()
layer->setMetadataUrlFormat( mLayerMetadataUrlFormatComboBox->currentText() );

//layer simplify drawing configuration
int simplifyDrawingHints = QgsVectorLayer::NoSimplification;
int simplifyHints = QgsVectorLayer::NoSimplification;
if ( mSimplifyDrawingGroupBox->isChecked() )
{
simplifyDrawingHints |= QgsVectorLayer::DefaultSimplification;
if ( mSimplifyDrawingSlider->value() > 0 ) simplifyDrawingHints |= QgsVectorLayer::AntialiasingSimplification;
simplifyHints |= QgsVectorLayer::GeometrySimplification;
if ( mSimplifyDrawingSpinBox->value() > 1 ) simplifyHints |= QgsVectorLayer::AntialiasingSimplification;
}
layer->setSimplifyDrawingHints( simplifyDrawingHints );
layer->setSimplifyDrawingTol( 1.0f + 0.2f*mSimplifyDrawingSlider->value() );
QgsVectorSimplifyMethod simplifyMethod = layer->simplifyMethod();
simplifyMethod.setSimplifyHints( simplifyHints );
simplifyMethod.setThreshold( mSimplifyDrawingSpinBox->value() );
simplifyMethod.setForceLocalOptimization( !mSimplifyDrawingAtProvider->isChecked() );
layer->setSimplifyMethod( simplifyMethod );

// update symbology
emit refreshLegend( layer->id(), QgsLegendItem::DontChange );
Expand Down Expand Up @@ -1083,7 +1098,14 @@ void QgsVectorLayerProperties::on_mMaximumScaleSetCurrentPushButton_clicked()
cbMaximumScale->setScale( 1.0 / QgisApp::instance()->mapCanvas()->mapRenderer()->scale() );
}

void QgsVectorLayerProperties::on_mSimplifyDrawingSlider_valueChanged( int value )
void QgsVectorLayerProperties::on_mSimplifyDrawingGroupBox_toggled( bool checked )
{
mSimplifyDrawingPanel->setVisible( value > 0 );
if ( !( layer->dataProvider()->capabilities() & QgsVectorDataProvider::SimplifyGeometries ) )
{
mSimplifyDrawingAtProvider->setEnabled( false );
}
else
{
mSimplifyDrawingAtProvider->setEnabled( mSimplifyDrawingGroupBox->isChecked() );
}
}
2 changes: 1 addition & 1 deletion src/app/qgsvectorlayerproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
void on_mMinimumScaleSetCurrentPushButton_clicked();
void on_mMaximumScaleSetCurrentPushButton_clicked();

void on_mSimplifyDrawingSlider_valueChanged( int value );
void on_mSimplifyDrawingGroupBox_toggled( bool checked );

signals:

Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ SET(QGIS_CORE_SRCS
qgsgeometrycache.cpp
qgsgeometryvalidator.cpp
qgsgeometrysimplifier.cpp
qgssimplifymethod.cpp
qgsgml.cpp
qgsgmlschema.cpp
qgshttptransaction.cpp
Expand Down Expand Up @@ -129,6 +130,7 @@ SET(QGIS_CORE_SRCS
qgsvectorlayerimport.cpp
qgsvectorlayerjoinbuffer.cpp
qgsvectorlayerundocommand.cpp
qgsvectorsimplifymethod.cpp

qgsnetworkaccessmanager.cpp

Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgscomposermap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
mComposition->plotStyle() == QgsComposition::Postscript )
{
//if outputing composer, disable optimisations like layer simplification
theRendererContext->setRenderingPrintComposition( true );
theRendererContext->setUseRenderingOptimization( false );
}

// force vector output (no caching of marker images etc.)
Expand Down
Loading