Skip to content

Commit 5d3382a

Browse files
committedAug 4, 2015
Fix geometry simplification for rendering altering feature geometry
I noticed this when using memory layers - zooming out and then in would result in the features getting more and more generalised. Possibly it would affect other areas of the codebase too. The geometry simplifier was unhelpfully casting away the const from the pointer to the geometry's wkb, and was happily overwriting the wkb for its own purposes. With QgsGeometry now implicitly sharing this wkb pointer the non-const cast meant that the geometry was not getting correctly detached and the original geometry was being modified. (cherry-picked from f00c52d)
1 parent 3865ccd commit 5d3382a

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed
 

‎src/core/qgsmaptopixelgeometrysimplifier.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ float QgsMapToPixelSimplifier::calculateLengthSquared2D( double x1, double y1, d
4141
}
4242

4343
//! Returns the BBOX of the specified WKB-point stream
44-
inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, unsigned char* wkb, size_t numPoints )
44+
inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, const unsigned char* wkb, size_t numPoints )
4545
{
4646
double x, y;
4747
QgsRectangle r;
@@ -63,7 +63,7 @@ inline static QgsRectangle calculateBoundingBox( QGis::WkbType wkbType, unsigned
6363
//! Generalize the WKB-geometry using the BBOX of the original geometry
6464
static bool generalizeWkbGeometryByBoundingBox(
6565
QGis::WkbType wkbType,
66-
unsigned char* sourceWkb, size_t sourceWkbSize,
66+
const unsigned char* sourceWkb, size_t sourceWkbSize,
6767
unsigned char* targetWkb, size_t& targetWkbSize,
6868
const QgsRectangle& envelope, bool writeHeader )
6969
{
@@ -151,7 +151,7 @@ static bool generalizeWkbGeometryByBoundingBox(
151151
//! Simplify the WKB-geometry using the specified tolerance
152152
bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
153153
int simplifyFlags, QGis::WkbType wkbType,
154-
unsigned char* sourceWkb, size_t sourceWkbSize,
154+
const unsigned char* sourceWkb, size_t sourceWkbSize,
155155
unsigned char* targetWkb, size_t& targetWkbSize,
156156
const QgsRectangle& envelope, double map2pixelTol,
157157
bool writeHeader, bool isaLinearRing )
@@ -161,7 +161,7 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
161161
bool result = false;
162162

163163
// Save initial WKB settings to use when the simplification creates invalid geometries
164-
unsigned char* sourcePrevWkb = sourceWkb;
164+
const unsigned char* sourcePrevWkb = sourceWkb;
165165
unsigned char* targetPrevWkb = targetWkb;
166166
size_t targetWkbPrevSize = targetWkbSize;
167167

@@ -194,7 +194,7 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
194194
targetWkbSize += 5;
195195
}
196196

197-
unsigned char* wkb1 = sourceWkb;
197+
const unsigned char* wkb1 = sourceWkb;
198198
unsigned char* wkb2 = targetWkb;
199199
unsigned int flatType = QGis::flatType( wkbType );
200200

@@ -230,10 +230,10 @@ bool QgsMapToPixelSimplifier::simplifyWkbGeometry(
230230
{
231231
double x1, y1, x2, y2;
232232

233-
unsigned char* startWkbX = sourceWkb;
234-
unsigned char* startWkbY = startWkbX + sizeOfDoubleX;
235-
unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
236-
unsigned char* finalWkbY = finalWkbX + sizeOfDoubleX;
233+
const unsigned char* startWkbX = sourceWkb;
234+
const unsigned char* startWkbY = startWkbX + sizeOfDoubleX;
235+
const unsigned char* finalWkbX = sourceWkb + ( numPoints - 1 ) * ( sizeOfDoubleX + sizeOfDoubleY );
236+
const unsigned char* finalWkbY = finalWkbX + sizeOfDoubleX;
237237

238238
memcpy( &x1, startWkbX, sizeof( double ) );
239239
memcpy( &y1, startWkbY, sizeof( double ) );
@@ -418,7 +418,7 @@ QgsGeometry* QgsMapToPixelSimplifier::simplify( QgsGeometry* geometry ) const
418418
//! Simplifies the geometry (Removing duplicated points) when is applied the specified map2pixel context
419419
bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simplifyFlags, double tolerance )
420420
{
421-
size_t targetWkbSize = 0;
421+
size_t finalWkbSize = 0;
422422

423423
// Check whether the geometry can be simplified using the map2pixel context
424424
QGis::GeometryType geometryType = geometry->type();
@@ -428,17 +428,21 @@ bool QgsMapToPixelSimplifier::simplifyGeometry( QgsGeometry* geometry, int simpl
428428
QgsRectangle envelope = geometry->boundingBox();
429429
QGis::WkbType wkbType = geometry->wkbType();
430430

431-
unsigned char* wkb = ( unsigned char* )geometry->asWkb();
431+
const unsigned char* wkb = geometry->asWkb();
432432
size_t wkbSize = geometry->wkbSize();
433433

434-
// Simplify the geometry rewriting temporally its WKB-stream for saving calloc's.
435-
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, wkb, targetWkbSize, envelope, tolerance ) )
434+
unsigned char* targetWkb = new unsigned char[wkbSize];
435+
memcpy( targetWkb, wkb, wkbSize );
436+
437+
if ( simplifyWkbGeometry( simplifyFlags, wkbType, wkb, wkbSize, targetWkb, finalWkbSize, envelope, tolerance ) )
436438
{
437-
unsigned char* targetWkb = new unsigned char[targetWkbSize];
438-
memcpy( targetWkb, wkb, targetWkbSize );
439-
geometry->fromWkb( targetWkb, targetWkbSize );
439+
unsigned char* finalWkb = new unsigned char[finalWkbSize];
440+
memcpy( finalWkb, targetWkb, finalWkbSize );
441+
geometry->fromWkb( finalWkb, finalWkbSize );
442+
delete [] targetWkb;
440443
return true;
441444
}
445+
delete [] targetWkb;
442446
return false;
443447
}
444448

‎src/core/qgsmaptopixelgeometrysimplifier.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
4545

4646
private:
4747
//! Simplify the WKB-geometry using the specified tolerance
48-
static bool simplifyWkbGeometry( int simplifyFlags, QGis::WkbType wkbType, unsigned char* sourceWkb, size_t sourceWkbSize, unsigned char* targetWkb, size_t& targetWkbSize, const QgsRectangle& envelope, double map2pixelTol, bool writeHeader = true, bool isaLinearRing = false );
48+
static bool simplifyWkbGeometry( int simplifyFlags, QGis::WkbType wkbType, const unsigned char* sourceWkb, size_t sourceWkbSize, unsigned char* targetWkb, size_t& targetWkbSize, const QgsRectangle& envelope, double map2pixelTol, bool writeHeader = true, bool isaLinearRing = false );
4949

5050
protected:
5151
//! Current simplification flags

0 commit comments

Comments
 (0)
Please sign in to comment.