14
14
***************************************************************************/
15
15
#include " qgspostgresfeatureiterator.h"
16
16
#include " qgspostgresprovider.h"
17
+ #include " qgsgeometry.h"
17
18
18
19
#include " qgslogger.h"
19
20
#include " qgsmessagelog.h"
@@ -292,6 +293,7 @@ QString QgsPostgresFeatureIterator::whereClauseRect()
292
293
bool QgsPostgresFeatureIterator::declareCursor ( const QString& whereClause )
293
294
{
294
295
mFetchGeometry = !( mRequest .flags () & QgsFeatureRequest::NoGeometry ) && !P->mGeometryColumn .isNull ();
296
+ bool simplifyGeometry = false ;
295
297
296
298
try
297
299
{
@@ -305,7 +307,8 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
305
307
? ( P->mConnectionRO ->majorVersion () < 2 ? " simplify" : " st_simplify" )
306
308
: ( P->mConnectionRO ->majorVersion () < 2 ? " simplifypreservetopology" : " st_simplifypreservetopology" );
307
309
308
- double tolerance = simplifyMethod.tolerance ();
310
+ double tolerance = simplifyMethod.tolerance () * 0.8 ; // -> Default factor for the maximum displacement distance for simplification, similar as GeoServer does
311
+ simplifyGeometry = simplifyMethod.methodType () == QgsSimplifyMethod::OptimizeForRendering;
309
312
310
313
query += QString ( " %1(%5(%2%3,%6),'%4')" )
311
314
.arg ( P->mConnectionRO ->majorVersion () < 2 ? " asbinary" : " st_asbinary" )
@@ -366,6 +369,17 @@ bool QgsPostgresFeatureIterator::declareCursor( const QString& whereClause )
366
369
query += delim + P->mConnectionRO ->fieldExpression ( P->field ( idx ) );
367
370
}
368
371
372
+ // query BBOX of geometries to redefine the geometries collapsed by ST_Simplify()
373
+ if ( simplifyGeometry && !( P->mConnectionRO ->majorVersion () >= 2 && P->mConnectionRO ->minorVersion () >= 1 ) && QGis::flatType ( QGis::singleType ( P->geometryType () ) ) == QGis::WKBPolygon )
374
+ {
375
+ query += QString ( " ,%1(%5(%2)%3,'%4')" )
376
+ .arg ( P->mConnectionRO ->majorVersion () < 2 ? " asbinary" : " st_asbinary" )
377
+ .arg ( P->quotedIdentifier ( P->mGeometryColumn ) )
378
+ .arg ( P->mSpatialColType == sctGeography ? " ::geometry" : " " )
379
+ .arg ( P->endianString () )
380
+ .arg ( P->mConnectionRO ->majorVersion () < 2 ? " envelope" : " st_envelope" );
381
+ }
382
+
369
383
query += " FROM " + P->mQuery ;
370
384
371
385
if ( !whereClause.isEmpty () )
@@ -589,6 +603,29 @@ bool QgsPostgresFeatureIterator::getFeature( QgsPostgresResult &queryResult, int
589
603
getFeatureAttribute ( idx, queryResult, row, col, feature );
590
604
}
591
605
606
+ // fix collapsed geometries by ST_Simplify() using the BBOX fetched from the current query
607
+ const QgsSimplifyMethod& simplifyMethod = mRequest .simplifyMethod ();
608
+ if ( mFetchGeometry && !simplifyMethod.forceLocalOptimization () && simplifyMethod.methodType () == QgsSimplifyMethod::OptimizeForRendering && QGis::flatType ( QGis::singleType ( P->geometryType () ) ) == QGis::WKBPolygon )
609
+ {
610
+ QgsGeometry* geometry = feature.geometry ();
611
+
612
+ if ( !( P->mConnectionRO ->majorVersion () >= 2 && P->mConnectionRO ->minorVersion () >= 1 ) && ( !geometry || geometry->length () == 0 ) )
613
+ {
614
+ int returnedLength = ::PQgetlength ( queryResult.result (), row, col );
615
+
616
+ if ( returnedLength > 0 )
617
+ {
618
+ unsigned char *featureGeom = new unsigned char [returnedLength + 1 ];
619
+ memcpy ( featureGeom, PQgetvalue ( queryResult.result (), row, col ), returnedLength );
620
+ memset ( featureGeom + returnedLength, 0 , 1 );
621
+
622
+ QgsGeometry *envelope = new QgsGeometry ();
623
+ envelope->fromWkb ( featureGeom, returnedLength + 1 );
624
+ feature.setGeometry ( envelope );
625
+ }
626
+ }
627
+ }
628
+
592
629
return true ;
593
630
}
594
631
catch ( QgsPostgresProvider::PGFieldNotFound )
0 commit comments