Postgresql provider - Use postgis 2.2 ST_RemoveRepeatedPoints for simplification

This commit is contained in:
Michael Douchin 2015-10-30 11:31:07 +01:00
parent 71fc4576c9
commit 706e651484
5 changed files with 83 additions and 10 deletions

View File

@ -26,11 +26,16 @@ class QgsSimplifyMethod
//! Gets the simplification type //! Gets the simplification type
MethodType methodType() const; MethodType methodType() const;
//! Sets the tolerance of simplification. Represents the maximum distance between two coordinates which can be considered equal //! Sets the tolerance of simplification in map units. Represents the maximum distance between two coordinates which can be considered equal
void setTolerance( double tolerance ); void setTolerance( double tolerance );
//! Gets the tolerance of simplification //! Gets the tolerance of simplification in map units
double tolerance() const; double tolerance() const;
//! Sets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
void setThreshold( float threshold );
//! Gets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
float threshold() const;
//! Sets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries //! 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 ); 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 //! Gets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries

View File

@ -21,6 +21,7 @@
QgsSimplifyMethod::QgsSimplifyMethod() QgsSimplifyMethod::QgsSimplifyMethod()
: mMethodType( QgsSimplifyMethod::NoSimplification ) : mMethodType( QgsSimplifyMethod::NoSimplification )
, mTolerance( 1 ) , mTolerance( 1 )
, mThreshold( 1 )
, mForceLocalOptimization( true ) , mForceLocalOptimization( true )
{ {
} }
@ -34,6 +35,7 @@ QgsSimplifyMethod& QgsSimplifyMethod::operator=( const QgsSimplifyMethod & rh )
{ {
mMethodType = rh.mMethodType; mMethodType = rh.mMethodType;
mTolerance = rh.mTolerance; mTolerance = rh.mTolerance;
mThreshold = rh.mThreshold;
mForceLocalOptimization = rh.mForceLocalOptimization; mForceLocalOptimization = rh.mForceLocalOptimization;
return *this; return *this;

View File

@ -44,11 +44,16 @@ class CORE_EXPORT QgsSimplifyMethod
//! Gets the simplification type //! Gets the simplification type
inline MethodType methodType() const { return mMethodType; } inline MethodType methodType() const { return mMethodType; }
//! Sets the tolerance of simplification. Represents the maximum distance between two coordinates which can be considered equal //! Sets the tolerance of simplification in map units. Represents the maximum distance in map units between two coordinates which can be considered equal.
void setTolerance( double tolerance ); void setTolerance( double tolerance );
//! Gets the tolerance of simplification //! Gets the tolerance of simplification in map units . Represents the maximum distance in map units between two coordinates which can be considered equal.
inline double tolerance() const { return mTolerance; } inline double tolerance() const { return mTolerance; }
//! Sets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
void setThreshold( float threshold ) { mThreshold = threshold; }
//! Gets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
inline float threshold() const { return mThreshold; }
//! Sets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries //! 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 ); 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 //! Gets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries
@ -62,6 +67,8 @@ class CORE_EXPORT QgsSimplifyMethod
MethodType mMethodType; MethodType mMethodType;
//! Tolerance of simplification, it represents the maximum distance between two coordinates which can be considered equal //! Tolerance of simplification, it represents the maximum distance between two coordinates which can be considered equal
double mTolerance; double mTolerance;
/** Simplification threshold */
float mThreshold;
//! Simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries //! Simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries
bool mForceLocalOptimization; bool mForceLocalOptimization;
}; };

View File

@ -218,6 +218,8 @@ bool QgsVectorLayerRenderer::render()
QgsSimplifyMethod simplifyMethod; QgsSimplifyMethod simplifyMethod;
simplifyMethod.setMethodType( QgsSimplifyMethod::OptimizeForRendering ); simplifyMethod.setMethodType( QgsSimplifyMethod::OptimizeForRendering );
simplifyMethod.setTolerance( map2pixelTol ); simplifyMethod.setTolerance( map2pixelTol );
simplifyMethod.setThreshold( mSimplifyMethod.threshold() );
simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() ); simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() );
featureRequest.setSimplifyMethod( simplifyMethod ); featureRequest.setSimplifyMethod( simplifyMethod );

View File

@ -364,12 +364,69 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
? mSource->mRequestedGeomType ? mSource->mRequestedGeomType
: mSource->mDetectedGeomType ) ) != QGis::WKBPoint ) : mSource->mDetectedGeomType ) ) != QGis::WKBPoint )
{ {
// PostGIS simplification method to use
QString simplifyPostgisMethod;
// Simplify again with st_simplify after first simplification ?
bool postSimplification;
postSimplification = false; // default to false. Set to true only for postgis >= 2.2 when using st_removerepeatedpoints
if ( mRequest.simplifyMethod().methodType() == QgsSimplifyMethod::OptimizeForRendering )
{
// Optimize simplification for rendering
if ( mConn->majorVersion() < 2 )
{
simplifyPostgisMethod = "snaptogrid";
}
else
{
// Default to st_snaptogrid
simplifyPostgisMethod = "st_snaptogrid";
if (( mConn->majorVersion() == 2 && mConn->minorVersion() >= 2 ) ||
mConn->majorVersion() > 2 )
{
// For postgis >= 2.2 Use ST_RemoveRepeatedPoints instead
// Do it only if threshold is <= 1 pixel to avoid holes in adjacent polygons
// We should perhaps use it always for Linestrings, even if threshold > 1 ?
if ( mRequest.simplifyMethod().threshold() <= 1.0 )
{
simplifyPostgisMethod = "st_removerepeatedpoints";
postSimplification = true; // Ask to apply a post-filtering simplification
}
}
}
}
else
{
// preserve topology
if ( mConn->majorVersion() < 2 )
{
simplifyPostgisMethod = "simplifypreservetopology";
}
else
{
simplifyPostgisMethod = "st_simplifypreservetopology";
}
}
QgsDebugMsg(
QString( "PostGIS Server side simplification : threshold %1 pixels - method %2" )
.arg( mRequest.simplifyMethod().threshold() )
.arg( simplifyPostgisMethod )
);
geom = QString( "%1(%2,%3)" ) geom = QString( "%1(%2,%3)" )
.arg( mRequest.simplifyMethod().methodType() == QgsSimplifyMethod::OptimizeForRendering .arg( simplifyPostgisMethod, geom )
? ( mConn->majorVersion() < 2 ? "snaptogrid" : "st_snaptogrid" ) .arg( mRequest.simplifyMethod().tolerance() * 0.8 ); //-> Default factor for the maximum displacement distance for simplification, similar as GeoServer does
: ( mConn->majorVersion() < 2 ? "simplifypreservetopology" : "st_simplifypreservetopology" ),
geom ) // Post-simplification
.arg( mRequest.simplifyMethod().tolerance() * 0.8 ); //-> Default factor for the maximum displacement distance for simplification, similar as GeoServer does if ( postSimplification )
{
geom = QString( "st_simplify( %1, %2, true )" )
.arg( geom )
.arg( mRequest.simplifyMethod().tolerance() * 0.7 ); //-> We use a smaller tolerance than pre-filtering to be on the safe side
}
} }
geom = QString( "%1(%2,'%3')" ) geom = QString( "%1(%2,'%3')" )
@ -382,7 +439,7 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
} }
switch ( mSource->mPrimaryKeyType ) switch ( mSource->mPrimaryKeyType )
{ {
case pktOid: case pktOid:
query += delim + "oid"; query += delim + "oid";
delim = ','; delim = ',';