Navigation Menu

Skip to content

Commit

Permalink
Postgresql provider - Use postgis 2.2 ST_RemoveRepeatedPoints for sim…
Browse files Browse the repository at this point in the history
…plification
  • Loading branch information
mdouchin committed Dec 1, 2015
1 parent 71fc457 commit 706e651
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 10 deletions.
9 changes: 7 additions & 2 deletions python/core/qgssimplifymethod.sip
Expand Up @@ -26,11 +26,16 @@ class QgsSimplifyMethod
//! Gets the simplification type
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 );
//! Gets the tolerance of simplification
//! Gets the tolerance of simplification in map units
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
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
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgssimplifymethod.cpp
Expand Up @@ -21,6 +21,7 @@
QgsSimplifyMethod::QgsSimplifyMethod()
: mMethodType( QgsSimplifyMethod::NoSimplification )
, mTolerance( 1 )
, mThreshold( 1 )
, mForceLocalOptimization( true )
{
}
Expand All @@ -34,6 +35,7 @@ QgsSimplifyMethod& QgsSimplifyMethod::operator=( const QgsSimplifyMethod & rh )
{
mMethodType = rh.mMethodType;
mTolerance = rh.mTolerance;
mThreshold = rh.mThreshold;
mForceLocalOptimization = rh.mForceLocalOptimization;

return *this;
Expand Down
11 changes: 9 additions & 2 deletions src/core/qgssimplifymethod.h
Expand Up @@ -44,11 +44,16 @@ class CORE_EXPORT QgsSimplifyMethod
//! Gets the simplification type
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 );
//! 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; }

//! 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
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
Expand All @@ -62,6 +67,8 @@ class CORE_EXPORT QgsSimplifyMethod
MethodType mMethodType;
//! Tolerance of simplification, it represents the maximum distance between two coordinates which can be considered equal
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
bool mForceLocalOptimization;
};
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsvectorlayerrenderer.cpp
Expand Up @@ -218,6 +218,8 @@ bool QgsVectorLayerRenderer::render()
QgsSimplifyMethod simplifyMethod;
simplifyMethod.setMethodType( QgsSimplifyMethod::OptimizeForRendering );
simplifyMethod.setTolerance( map2pixelTol );
simplifyMethod.setThreshold( mSimplifyMethod.threshold() );

simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() );

featureRequest.setSimplifyMethod( simplifyMethod );
Expand Down
69 changes: 63 additions & 6 deletions src/providers/postgres/qgspostgresfeatureiterator.cpp
Expand Up @@ -364,12 +364,69 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
? mSource->mRequestedGeomType
: 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)" )
.arg( mRequest.simplifyMethod().methodType() == QgsSimplifyMethod::OptimizeForRendering
? ( mConn->majorVersion() < 2 ? "snaptogrid" : "st_snaptogrid" )
: ( mConn->majorVersion() < 2 ? "simplifypreservetopology" : "st_simplifypreservetopology" ),
geom )
.arg( mRequest.simplifyMethod().tolerance() * 0.8 ); //-> Default factor for the maximum displacement distance for simplification, similar as GeoServer does
.arg( simplifyPostgisMethod, geom )
.arg( mRequest.simplifyMethod().tolerance() * 0.8 ); //-> Default factor for the maximum displacement distance for simplification, similar as GeoServer does

// Post-simplification
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')" )
Expand All @@ -382,7 +439,7 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
}

switch ( mSource->mPrimaryKeyType )
{
{
case pktOid:
query += delim + "oid";
delim = ',';
Expand Down

0 comments on commit 706e651

Please sign in to comment.