Skip to content

Commit 3d5f33a

Browse files
committedDec 3, 2015
Merge pull request #2410 from mdouchin/postgis_2_2_server_simplification
Postgresql provider - Use ST_RemoveRepeatedPoints instead of ST_SnapToGrid
2 parents 4dafbc0 + 706e651 commit 3d5f33a

File tree

5 files changed

+83
-10
lines changed

5 files changed

+83
-10
lines changed
 

‎python/core/qgssimplifymethod.sip

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ class QgsSimplifyMethod
2626
//! Gets the simplification type
2727
MethodType methodType() const;
2828

29-
//! Sets the tolerance of simplification. Represents the maximum distance between two coordinates which can be considered equal
29+
//! Sets the tolerance of simplification in map units. Represents the maximum distance between two coordinates which can be considered equal
3030
void setTolerance( double tolerance );
31-
//! Gets the tolerance of simplification
31+
//! Gets the tolerance of simplification in map units
3232
double tolerance() const;
3333

34+
//! Sets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
35+
void setThreshold( float threshold );
36+
//! Gets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
37+
float threshold() const;
38+
3439
//! Sets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries
3540
void setForceLocalOptimization( bool localOptimization );
3641
//! Gets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries

‎src/core/qgssimplifymethod.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
QgsSimplifyMethod::QgsSimplifyMethod()
2222
: mMethodType( QgsSimplifyMethod::NoSimplification )
2323
, mTolerance( 1 )
24+
, mThreshold( 1 )
2425
, mForceLocalOptimization( true )
2526
{
2627
}
@@ -34,6 +35,7 @@ QgsSimplifyMethod& QgsSimplifyMethod::operator=( const QgsSimplifyMethod & rh )
3435
{
3536
mMethodType = rh.mMethodType;
3637
mTolerance = rh.mTolerance;
38+
mThreshold = rh.mThreshold;
3739
mForceLocalOptimization = rh.mForceLocalOptimization;
3840

3941
return *this;

‎src/core/qgssimplifymethod.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,16 @@ class CORE_EXPORT QgsSimplifyMethod
4444
//! Gets the simplification type
4545
inline MethodType methodType() const { return mMethodType; }
4646

47-
//! Sets the tolerance of simplification. Represents the maximum distance between two coordinates which can be considered equal
47+
//! Sets the tolerance of simplification in map units. Represents the maximum distance in map units between two coordinates which can be considered equal.
4848
void setTolerance( double tolerance );
49-
//! Gets the tolerance of simplification
49+
//! Gets the tolerance of simplification in map units . Represents the maximum distance in map units between two coordinates which can be considered equal.
5050
inline double tolerance() const { return mTolerance; }
5151

52+
//! Sets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
53+
void setThreshold( float threshold ) { mThreshold = threshold; }
54+
//! Gets the simplification threshold in pixels. Represents the maximum distance in pixels between two coordinates which can be considered equal.
55+
inline float threshold() const { return mThreshold; }
56+
5257
//! Sets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries
5358
void setForceLocalOptimization( bool localOptimization );
5459
//! 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
6267
MethodType mMethodType;
6368
//! Tolerance of simplification, it represents the maximum distance between two coordinates which can be considered equal
6469
double mTolerance;
70+
/** Simplification threshold */
71+
float mThreshold;
6572
//! Simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries
6673
bool mForceLocalOptimization;
6774
};

‎src/core/qgsvectorlayerrenderer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ bool QgsVectorLayerRenderer::render()
218218
QgsSimplifyMethod simplifyMethod;
219219
simplifyMethod.setMethodType( QgsSimplifyMethod::OptimizeForRendering );
220220
simplifyMethod.setTolerance( map2pixelTol );
221+
simplifyMethod.setThreshold( mSimplifyMethod.threshold() );
222+
221223
simplifyMethod.setForceLocalOptimization( mSimplifyMethod.forceLocalOptimization() );
222224

223225
featureRequest.setSimplifyMethod( simplifyMethod );

‎src/providers/postgres/qgspostgresfeatureiterator.cpp

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,69 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
364364
? mSource->mRequestedGeomType
365365
: mSource->mDetectedGeomType ) ) != QGis::WKBPoint )
366366
{
367+
// PostGIS simplification method to use
368+
QString simplifyPostgisMethod;
369+
370+
// Simplify again with st_simplify after first simplification ?
371+
bool postSimplification;
372+
postSimplification = false; // default to false. Set to true only for postgis >= 2.2 when using st_removerepeatedpoints
373+
374+
if ( mRequest.simplifyMethod().methodType() == QgsSimplifyMethod::OptimizeForRendering )
375+
{
376+
// Optimize simplification for rendering
377+
if ( mConn->majorVersion() < 2 )
378+
{
379+
simplifyPostgisMethod = "snaptogrid";
380+
}
381+
else
382+
{
383+
384+
// Default to st_snaptogrid
385+
simplifyPostgisMethod = "st_snaptogrid";
386+
387+
if (( mConn->majorVersion() == 2 && mConn->minorVersion() >= 2 ) ||
388+
mConn->majorVersion() > 2 )
389+
{
390+
// For postgis >= 2.2 Use ST_RemoveRepeatedPoints instead
391+
// Do it only if threshold is <= 1 pixel to avoid holes in adjacent polygons
392+
// We should perhaps use it always for Linestrings, even if threshold > 1 ?
393+
if ( mRequest.simplifyMethod().threshold() <= 1.0 )
394+
{
395+
simplifyPostgisMethod = "st_removerepeatedpoints";
396+
postSimplification = true; // Ask to apply a post-filtering simplification
397+
}
398+
}
399+
}
400+
}
401+
else
402+
{
403+
// preserve topology
404+
if ( mConn->majorVersion() < 2 )
405+
{
406+
simplifyPostgisMethod = "simplifypreservetopology";
407+
}
408+
else
409+
{
410+
simplifyPostgisMethod = "st_simplifypreservetopology";
411+
}
412+
}
413+
QgsDebugMsg(
414+
QString( "PostGIS Server side simplification : threshold %1 pixels - method %2" )
415+
.arg( mRequest.simplifyMethod().threshold() )
416+
.arg( simplifyPostgisMethod )
417+
);
418+
367419
geom = QString( "%1(%2,%3)" )
368-
.arg( mRequest.simplifyMethod().methodType() == QgsSimplifyMethod::OptimizeForRendering
369-
? ( mConn->majorVersion() < 2 ? "snaptogrid" : "st_snaptogrid" )
370-
: ( mConn->majorVersion() < 2 ? "simplifypreservetopology" : "st_simplifypreservetopology" ),
371-
geom )
372-
.arg( mRequest.simplifyMethod().tolerance() * 0.8 ); //-> Default factor for the maximum displacement distance for simplification, similar as GeoServer does
420+
.arg( simplifyPostgisMethod, geom )
421+
.arg( mRequest.simplifyMethod().tolerance() * 0.8 ); //-> Default factor for the maximum displacement distance for simplification, similar as GeoServer does
422+
423+
// Post-simplification
424+
if ( postSimplification )
425+
{
426+
geom = QString( "st_simplify( %1, %2, true )" )
427+
.arg( geom )
428+
.arg( mRequest.simplifyMethod().tolerance() * 0.7 ); //-> We use a smaller tolerance than pre-filtering to be on the safe side
429+
}
373430
}
374431

375432
geom = QString( "%1(%2,'%3')" )
@@ -382,7 +439,7 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
382439
}
383440

384441
switch ( mSource->mPrimaryKeyType )
385-
{
442+
{
386443
case pktOid:
387444
query += delim + "oid";
388445
delim = ',';

0 commit comments

Comments
 (0)
Please sign in to comment.