Skip to content

Commit c1661de

Browse files
committed
Fix invalid polygon rings created by map to pixel simplification
when a larger polygon contains a very small ring
1 parent 9811783 commit c1661de

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed

src/core/qgsmaptopixelgeometrysimplifier.cpp

+35-16
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ bool QgsMapToPixelSimplifier::equalSnapToGrid( double x1, double y1, double x2,
7171
static QgsGeometry generalizeWkbGeometryByBoundingBox(
7272
QgsWkbTypes::Type wkbType,
7373
const QgsAbstractGeometry &geometry,
74-
const QgsRectangle &envelope )
74+
const QgsRectangle &envelope,
75+
bool isRing )
7576
{
7677
unsigned int geometryType = QgsWkbTypes::singleType( QgsWkbTypes::flatType( wkbType ) );
7778

@@ -89,31 +90,48 @@ static QgsGeometry generalizeWkbGeometryByBoundingBox(
8990
const double y2 = envelope.yMaximum();
9091

9192
// Write the generalized geometry
92-
if ( geometryType == QgsWkbTypes::LineString )
93+
if ( geometryType == QgsWkbTypes::LineString && !isRing )
9394
{
9495
return QgsGeometry( qgis::make_unique< QgsLineString >( QVector<double>() << x1 << x2, QVector<double>() << y1 << y2 ) );
9596
}
9697
else
9798
{
98-
return QgsGeometry::fromRect( envelope );
99+
std::unique_ptr< QgsLineString > ext = qgis::make_unique< QgsLineString >(
100+
QVector< double >() << x1
101+
<< x2
102+
<< x2
103+
<< x1
104+
<< x1,
105+
QVector< double >() << y1
106+
<< y1
107+
<< y2
108+
<< y2
109+
<< y1 );
110+
if ( geometryType == QgsWkbTypes::LineString )
111+
return QgsGeometry( std::move( ext ) );
112+
else
113+
{
114+
std::unique_ptr< QgsPolygon > polygon = qgis::make_unique< QgsPolygon >();
115+
polygon->setExteriorRing( ext.release() );
116+
return QgsGeometry( std::move( polygon ) );
117+
}
99118
}
100119
}
101120

102-
QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
103-
int simplifyFlags,
104-
SimplifyAlgorithm simplifyAlgorithm,
105-
QgsWkbTypes::Type wkbType,
106-
const QgsAbstractGeometry &geometry,
107-
const QgsRectangle &envelope, double map2pixelTol,
108-
bool isaLinearRing )
121+
QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry( int simplifyFlags,
122+
SimplifyAlgorithm simplifyAlgorithm,
123+
const QgsAbstractGeometry &geometry, double map2pixelTol,
124+
bool isaLinearRing )
109125
{
110126
bool isGeneralizable = true;
127+
QgsWkbTypes::Type wkbType = geometry.wkbType();
111128

112129
// Can replace the geometry by its BBOX ?
130+
QgsRectangle envelope = geometry.boundingBox();
113131
if ( ( simplifyFlags & QgsMapToPixelSimplifier::SimplifyEnvelope ) &&
114132
isGeneralizableByMapBoundingBox( envelope, map2pixelTol ) )
115133
{
116-
return generalizeWkbGeometryByBoundingBox( wkbType, geometry, envelope );
134+
return generalizeWkbGeometryByBoundingBox( wkbType, geometry, envelope, isaLinearRing );
117135
}
118136

119137
if ( !( simplifyFlags & QgsMapToPixelSimplifier::SimplifyGeometry ) )
@@ -267,7 +285,7 @@ QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
267285
{
268286
// approximate the geometry's shape by its bounding box
269287
// (rect for linear ring / one segment for line string)
270-
return generalizeWkbGeometryByBoundingBox( wkbType, geometry, r );
288+
return generalizeWkbGeometryByBoundingBox( wkbType, geometry, r, isaLinearRing );
271289
}
272290
else
273291
{
@@ -293,11 +311,12 @@ QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
293311
{
294312
const QgsPolygon &srcPolygon = dynamic_cast<const QgsPolygon &>( geometry );
295313
std::unique_ptr<QgsPolygon> polygon( new QgsPolygon() );
296-
polygon->setExteriorRing( qgsgeometry_cast<QgsCurve *>( simplifyGeometry( simplifyFlags, simplifyAlgorithm, srcPolygon.exteriorRing()->wkbType(), *srcPolygon.exteriorRing(), envelope, map2pixelTol, true ).constGet()->clone() ) );
314+
polygon->setExteriorRing( qgsgeometry_cast<QgsCurve *>( simplifyGeometry( simplifyFlags, simplifyAlgorithm, *srcPolygon.exteriorRing(), map2pixelTol, true ).constGet()->clone() ) );
297315
for ( int i = 0; i < srcPolygon.numInteriorRings(); ++i )
298316
{
299317
const QgsCurve *sub = srcPolygon.interiorRing( i );
300-
polygon->addInteriorRing( qgsgeometry_cast<QgsCurve *>( simplifyGeometry( simplifyFlags, simplifyAlgorithm, sub->wkbType(), *sub, envelope, map2pixelTol, true ).constGet()->clone() ) );
318+
std::unique_ptr< QgsCurve > ring( qgsgeometry_cast<QgsCurve *>( simplifyGeometry( simplifyFlags, simplifyAlgorithm, *sub, map2pixelTol, true ).constGet()->clone() ) );
319+
polygon->addInteriorRing( ring.release() );
301320
}
302321
return QgsGeometry( polygon.release() );
303322
}
@@ -309,7 +328,7 @@ QgsGeometry QgsMapToPixelSimplifier::simplifyGeometry(
309328
for ( int i = 0; i < numGeoms; ++i )
310329
{
311330
const QgsAbstractGeometry *sub = srcCollection.geometryN( i );
312-
collection->addGeometry( simplifyGeometry( simplifyFlags, simplifyAlgorithm, sub->wkbType(), *sub, envelope, map2pixelTol, false ).constGet()->clone() );
331+
collection->addGeometry( simplifyGeometry( simplifyFlags, simplifyAlgorithm, *sub, map2pixelTol, false ).constGet()->clone() );
313332
}
314333
return QgsGeometry( collection.release() );
315334
}
@@ -359,5 +378,5 @@ QgsGeometry QgsMapToPixelSimplifier::simplify( const QgsGeometry &geometry ) con
359378
return geometry;
360379
}
361380

362-
return simplifyGeometry( mSimplifyFlags, mSimplifyAlgorithm, geometry.wkbType(), *geometry.constGet(), envelope, mTolerance, false );
381+
return simplifyGeometry( mSimplifyFlags, mSimplifyAlgorithm, *geometry.constGet(), mTolerance, false );
363382
}

src/core/qgsmaptopixelgeometrysimplifier.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class CORE_EXPORT QgsMapToPixelSimplifier : public QgsAbstractGeometrySimplifier
5858

5959
private:
6060
//! Simplify the geometry using the specified tolerance
61-
static QgsGeometry simplifyGeometry( int simplifyFlags, SimplifyAlgorithm simplifyAlgorithm, QgsWkbTypes::Type wkbType, const QgsAbstractGeometry &geometry, const QgsRectangle &envelope, double map2pixelTol, bool isaLinearRing );
61+
static QgsGeometry simplifyGeometry( int simplifyFlags, SimplifyAlgorithm simplifyAlgorithm, const QgsAbstractGeometry &geometry, double map2pixelTol, bool isaLinearRing );
6262

6363
protected:
6464
//! Current simplification flags

0 commit comments

Comments
 (0)