Skip to content

Commit 12a463d

Browse files
committed
Merge pull request #1087 from ahuarte47/Issue_9360R
Fix bug #9360-revival: fix whole layer not rendered (when simplify geometry activated; followup 3305a6c; fixes #9360)
2 parents f2d0100 + f79dfa1 commit 12a463d

4 files changed

+136
-51
lines changed

src/providers/ogr/qgsogrfeatureiterator.cpp

+20-6
Original file line numberDiff line numberDiff line change
@@ -109,31 +109,45 @@ bool QgsOgrFeatureIterator::prepareSimplification( const QgsSimplifyMethod& simp
109109
if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) && simplifyMethod.methodType() != QgsSimplifyMethod::NoSimplification && !simplifyMethod.forceLocalOptimization() )
110110
{
111111
QgsSimplifyMethod::MethodType methodType = simplifyMethod.methodType();
112+
Q_UNUSED( methodType);
112113

114+
#if defined(GDAL_VERSION_NUM) && defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)
113115
if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
114116
{
115117
int simplifyFlags = QgsMapToPixelSimplifier::SimplifyGeometry | QgsMapToPixelSimplifier::SimplifyEnvelope;
116118
mGeometrySimplifier = new QgsOgrMapToPixelSimplifier( simplifyFlags, simplifyMethod.tolerance() );
117119
return true;
118120
}
121+
#endif
119122
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
120-
else if ( methodType == QgsSimplifyMethod::PreserveTopology )
123+
if ( methodType == QgsSimplifyMethod::PreserveTopology )
121124
{
122125
mGeometrySimplifier = new QgsOgrTopologyPreservingSimplifier( simplifyMethod.tolerance() );
123126
return true;
124127
}
125128
#endif
126-
else
127-
{
128-
QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by OgrFeatureIterator class" ).arg( methodType ) );
129-
}
129+
130+
QgsDebugMsg( QString( "Simplification method type (%1) is not recognised by OgrFeatureIterator class" ).arg( methodType ) );
130131
}
131132
return QgsAbstractFeatureIterator::prepareSimplification( simplifyMethod );
132133
}
133134

134135
bool QgsOgrFeatureIterator::providerCanSimplify( QgsSimplifyMethod::MethodType methodType ) const
135136
{
136-
return methodType == QgsSimplifyMethod::OptimizeForRendering || methodType == QgsSimplifyMethod::PreserveTopology;
137+
#if defined(GDAL_VERSION_NUM) && defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)
138+
if ( methodType == QgsSimplifyMethod::OptimizeForRendering )
139+
{
140+
return true;
141+
}
142+
#endif
143+
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
144+
if ( methodType == QgsSimplifyMethod::PreserveTopology )
145+
{
146+
return true;
147+
}
148+
#endif
149+
150+
return false;
137151
}
138152

139153
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )

src/providers/ogr/qgsogrgeometrysimplifier.cpp

+92-43
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ QgsOgrAbstractGeometrySimplifier::~QgsOgrAbstractGeometrySimplifier()
2525
/***************************************************************************/
2626

2727
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
28+
2829
QgsOgrTopologyPreservingSimplifier::QgsOgrTopologyPreservingSimplifier( double tolerance )
2930
: QgsTopologyPreservingSimplifier( tolerance )
3031
{
@@ -59,22 +60,76 @@ bool QgsOgrTopologyPreservingSimplifier::simplifyGeometry( OGRGeometryH geometry
5960

6061
/***************************************************************************/
6162

63+
#if defined(GDAL_VERSION_NUM) && defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)
64+
6265
QgsOgrMapToPixelSimplifier::QgsOgrMapToPixelSimplifier( int simplifyFlags, double map2pixelTol )
6366
: QgsMapToPixelSimplifier( simplifyFlags, map2pixelTol )
67+
, mPointBufferPtr( NULL )
68+
, mPointBufferCount( 0 )
6469
{
6570
}
6671

6772
QgsOgrMapToPixelSimplifier::~QgsOgrMapToPixelSimplifier()
6873
{
74+
if ( mPointBufferPtr )
75+
{
76+
OGRFree( mPointBufferPtr );
77+
mPointBufferPtr = NULL;
78+
}
79+
}
80+
81+
//! Returns a point buffer of the specified size
82+
QgsPoint* QgsOgrMapToPixelSimplifier::mallocPoints( int numPoints )
83+
{
84+
if ( mPointBufferPtr && mPointBufferCount < numPoints )
85+
{
86+
OGRFree( mPointBufferPtr );
87+
mPointBufferPtr = NULL;
88+
}
89+
if ( !mPointBufferPtr )
90+
{
91+
mPointBufferCount = numPoints;
92+
mPointBufferPtr = ( QgsPoint* )OGRMalloc( mPointBufferCount * sizeof( QgsPoint ) );
93+
}
94+
return mPointBufferPtr;
95+
}
96+
97+
//! Returns a point buffer of the specified envelope
98+
QgsPoint* QgsOgrMapToPixelSimplifier::getEnvelopePoints( const QgsRectangle& envelope, int& numPoints, bool isaLinearRing )
99+
{
100+
QgsPoint* points = NULL;
101+
102+
double x1 = envelope.xMinimum();
103+
double y1 = envelope.yMinimum();
104+
double x2 = envelope.xMaximum();
105+
double y2 = envelope.yMaximum();
106+
107+
if ( isaLinearRing )
108+
{
109+
numPoints = 5;
110+
points = mallocPoints( numPoints );
111+
points[0].set( x1, y1 );
112+
points[1].set( x2, y1 );
113+
points[2].set( x2, y2 );
114+
points[3].set( x1, y2 );
115+
points[4].set( x1, y1 );
116+
}
117+
else
118+
{
119+
numPoints = 2;
120+
points = mallocPoints( numPoints );
121+
points[0].set( x1, y1 );
122+
points[1].set( x2, y2 );
123+
}
124+
return points;
69125
}
70126

71127
//////////////////////////////////////////////////////////////////////////////////////////////
72128
// Helper simplification methods
73129

74130
//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
75-
bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( QGis::GeometryType geometryType, const QgsRectangle& envelope, double *xptr, double *yptr, int pointCount, int& pointSimplifiedCount )
131+
bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( QGis::GeometryType geometryType, double* xptr, int xStride, double* yptr, int yStride, int pointCount, int& pointSimplifiedCount )
76132
{
77-
Q_UNUSED( envelope )
78133
bool canbeGeneralizable = ( mSimplifyFlags & QgsMapToPixelSimplifier::SimplifyGeometry );
79134

80135
pointSimplifiedCount = pointCount;
@@ -84,20 +139,20 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( QGis::GeometryType geometr
84139
double map2pixelTol = mMapToPixelTol * mMapToPixelTol; //-> Use mappixelTol for 'LengthSquare' calculations.
85140
double x, y, lastX = 0, lastY = 0;
86141

87-
double *xsourcePtr = xptr;
88-
double *ysourcePtr = yptr;
89-
double *xtargetPtr = xptr;
90-
double *ytargetPtr = yptr;
142+
char* xsourcePtr = ( char* )xptr;
143+
char* ysourcePtr = ( char* )yptr;
144+
char* xtargetPtr = ( char* )xptr;
145+
char* ytargetPtr = ( char* )yptr;
91146

92147
for ( int i = 0, numPoints = geometryType == QGis::Polygon ? pointCount - 1 : pointCount; i < numPoints; ++i )
93148
{
94-
memcpy( &x, xsourcePtr++, sizeof( double ) );
95-
memcpy( &y, ysourcePtr++, sizeof( double ) );
149+
memcpy( &x, xsourcePtr, sizeof( double ) ); xsourcePtr += xStride;
150+
memcpy( &y, ysourcePtr, sizeof( double ) ); ysourcePtr += yStride;
96151

97152
if ( i == 0 || !canbeGeneralizable || QgsMapToPixelSimplifier::calculateLengthSquared2D( x, y, lastX, lastY ) > map2pixelTol || ( geometryType == QGis::Line && ( i == 1 || i >= numPoints - 2 ) ) )
98153
{
99-
memcpy( xtargetPtr++, &x, sizeof( double ) ); lastX = x;
100-
memcpy( ytargetPtr++, &y, sizeof( double ) ); lastY = y;
154+
memcpy( xtargetPtr, &x, sizeof( double ) ); lastX = x; xtargetPtr += xStride;
155+
memcpy( ytargetPtr, &y, sizeof( double ) ); lastY = y; ytargetPtr += yStride;
101156
pointSimplifiedCount++;
102157
}
103158
}
@@ -107,7 +162,6 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( QGis::GeometryType geometr
107162
memcpy( ytargetPtr, yptr, sizeof( double ) );
108163
pointSimplifiedCount++;
109164
}
110-
111165
return pointSimplifiedCount != pointCount;
112166
}
113167

@@ -120,7 +174,8 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
120174
if ( wkbGeometryType == wkbLineString )
121175
{
122176
int numPoints = OGR_G_GetPointCount( geometry );
123-
if (( isaLinearRing && numPoints <= 5 ) || ( !isaLinearRing && numPoints <= 4 ) )
177+
178+
if (( isaLinearRing && numPoints <= 5 ) || ( !isaLinearRing && numPoints <= 4 ) )
124179
return false;
125180

126181
OGREnvelope env;
@@ -130,25 +185,9 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
130185
// Can replace the geometry by its BBOX ?
131186
if (( mSimplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) && canbeGeneralizedByMapBoundingBox( envelope ) )
132187
{
133-
double x1 = envelope.xMinimum();
134-
double y1 = envelope.yMinimum();
135-
double x2 = envelope.xMaximum();
136-
double y2 = envelope.yMaximum();
137-
138-
if ( isaLinearRing )
139-
{
140-
OGR_G_SetPoint( geometry, 0, x1, y1, 0.0 );
141-
OGR_G_SetPoint( geometry, 1, x2, y1, 0.0 );
142-
OGR_G_SetPoint( geometry, 2, x2, y2, 0.0 );
143-
OGR_G_SetPoint( geometry, 3, x1, y2, 0.0 );
144-
OGR_G_SetPoint( geometry, 4, x1, y1, 0.0 );
145-
}
146-
else
147-
{
148-
OGR_G_SetPoint( geometry, 0, x1, y1, 0.0 );
149-
OGR_G_SetPoint( geometry, 1, x2, y2, 0.0 );
150-
}
188+
QgsPoint* points = getEnvelopePoints( envelope, numPoints, isaLinearRing );
151189

190+
setGeometryPoints( geometry, points, numPoints );
152191
OGR_G_FlattenTo2D( geometry );
153192

154193
return true;
@@ -158,22 +197,19 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
158197
QGis::GeometryType geometryType = isaLinearRing ? QGis::Polygon : QGis::Line;
159198
int numSimplifiedPoints = 0;
160199

161-
QVector<double> x( numPoints ), y( numPoints );
162-
for ( int i = 0; i < numPoints; i++ )
163-
{
164-
double z;
165-
OGR_G_GetPoint( geometry, i, &x[i], &y[i], &z );
166-
}
200+
QgsPoint* points = mallocPoints( numPoints );
201+
double* xptr = ( double* )points;
202+
double* yptr = xptr + 1;
203+
OGR_G_GetPoints( geometry, xptr, 16, yptr, 16, NULL, 0 );
167204

168-
if ( simplifyOgrGeometry( geometryType, envelope, x.data(), y.data(), numPoints, numSimplifiedPoints ) )
205+
if ( simplifyOgrGeometry( geometryType, xptr, 16, yptr, 16, numPoints, numSimplifiedPoints ) )
169206
{
170-
for ( int i = 0; i < numSimplifiedPoints; i++ )
171-
{
172-
OGR_G_SetPoint( geometry, i, x[i], y[i], 0.0 );
173-
}
207+
if (( isaLinearRing && numSimplifiedPoints <= 4 ) || ( !isaLinearRing && numSimplifiedPoints <= 1 ) )
208+
points = getEnvelopePoints( envelope, numSimplifiedPoints, isaLinearRing );
209+
210+
setGeometryPoints( geometry, points, numSimplifiedPoints );
174211
OGR_G_FlattenTo2D( geometry );
175212
}
176-
177213
return numSimplifiedPoints != numPoints;
178214
}
179215
}
@@ -195,18 +231,29 @@ bool QgsOgrMapToPixelSimplifier::simplifyOgrGeometry( OGRGeometryH geometry, boo
195231
{
196232
bool result = false;
197233

198-
for ( int i = 1, numGeometries = OGR_G_GetGeometryCount( geometry ); i < numGeometries; ++i )
234+
for ( int i = 0, numGeometries = OGR_G_GetGeometryCount( geometry ); i < numGeometries; ++i )
199235
{
200236
result |= simplifyOgrGeometry( OGR_G_GetGeometryRef( geometry, i ), wkbGeometryType == wkbMultiPolygon );
201237
}
238+
202239
if ( result )
203240
OGR_G_FlattenTo2D( geometry );
241+
204242
return result;
205243
}
206244

207245
return false;
208246
}
209247

248+
//! Load a point array to the specified LineString geometry
249+
void QgsOgrMapToPixelSimplifier::setGeometryPoints( OGRGeometryH geometry, QgsPoint* points, int numPoints )
250+
{
251+
double* xptr = ( double* )points;
252+
double* yptr = xptr + 1;
253+
254+
OGR_G_SetPoints( geometry, numPoints, xptr, 16, yptr, 16, NULL, 0 );
255+
}
256+
210257
//////////////////////////////////////////////////////////////////////////////////////////////
211258

212259
//! Simplifies the specified geometry
@@ -221,3 +268,5 @@ bool QgsOgrMapToPixelSimplifier::simplifyGeometry( OGRGeometryH geometry )
221268

222269
return false;
223270
}
271+
272+
#endif

src/providers/ogr/qgsogrgeometrysimplifier.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define QGSOGRGEOMETRYSIMPLIFIER_H
1919

2020
#include "qgsmaptopixelgeometrysimplifier.h"
21+
#include "qgspoint.h"
22+
2123
#include <ogr_api.h>
2224

2325
/**
@@ -50,6 +52,7 @@ class QgsOgrTopologyPreservingSimplifier : public QgsOgrAbstractGeometrySimplifi
5052
};
5153
#endif
5254

55+
#if defined(GDAL_VERSION_NUM) && defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)
5356
/**
5457
* OGR implementation of GeometrySimplifier using the "MapToPixel" algorithm
5558
*
@@ -63,14 +66,28 @@ class QgsOgrMapToPixelSimplifier : public QgsOgrAbstractGeometrySimplifier, QgsM
6366
virtual ~QgsOgrMapToPixelSimplifier();
6467

6568
private:
69+
//! Point memory buffer for optimize the simplification process
70+
QgsPoint* mPointBufferPtr;
71+
//! Current Point memory buffer size
72+
int mPointBufferCount;
73+
6674
//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
67-
bool simplifyOgrGeometry( QGis::GeometryType geometryType, const QgsRectangle& envelope, double *xptr, double *yptr, int pointCount, int &pointSimplifiedCount );
75+
bool simplifyOgrGeometry( QGis::GeometryType geometryType, double* xptr, int xStride, double* yptr, int yStride, int pointCount, int& pointSimplifiedCount );
6876
//! Simplifies the OGR-geometry (Removing duplicated points) when is applied the specified map2pixel context
6977
bool simplifyOgrGeometry( OGRGeometryH geometry, bool isaLinearRing );
7078

79+
//! Returns a point buffer of the specified size
80+
QgsPoint* mallocPoints( int numPoints );
81+
//! Returns a point buffer of the specified envelope
82+
QgsPoint* getEnvelopePoints( const QgsRectangle& envelope, int& numPoints, bool isaLinearRing );
83+
84+
//! Load a point array to the specified LineString geometry
85+
static void setGeometryPoints( OGRGeometryH geometry, QgsPoint* points, int numPoints );
86+
7187
public:
7288
//! Simplifies the specified geometry
7389
virtual bool simplifyGeometry( OGRGeometryH geometry );
7490
};
91+
#endif
7592

7693
#endif // QGSOGRGEOMETRYSIMPLIFIER_H

src/providers/ogr/qgsogrprovider.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,12 @@ int QgsOgrProvider::capabilities() const
14951495
}
14961496

14971497
// supports geometry simplification on provider side
1498-
ability |= ( QgsVectorDataProvider::SimplifyGeometries | QgsVectorDataProvider::SimplifyGeometriesWithTopologicalValidation );
1498+
#if defined(GDAL_VERSION_NUM) && defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)
1499+
ability |= QgsVectorDataProvider::SimplifyGeometries;
1500+
#endif
1501+
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900
1502+
ability |= QgsVectorDataProvider::SimplifyGeometriesWithTopologicalValidation;
1503+
#endif
14991504
}
15001505

15011506
return ability;

0 commit comments

Comments
 (0)