Skip to content

Commit 6ea03ea

Browse files
committed
[Geometry] Fix various issues related to Wkb/Wkt import
- Make QgsCurvePolygonV2::fromWkb() accept CompoundCurveM sub-geometries - Make QgsGeometryCollectionV2::fromWkb() validate the sub-geometry type, so that QgsGeometryCollectionV2 subclasses do not import incompatible sub-geometries - Make QgsGeometryCollectionV2::fromWkt() accept curve sub-geometries - Make QgsMultiPolygonV2::addGeometry() accept only Polygon and not CurvePolygon - Add tests
1 parent dabc3b1 commit 6ea03ea

File tree

4 files changed

+73
-14
lines changed

4 files changed

+73
-14
lines changed

src/core/geometry/qgscurvepolygonv2.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,16 @@ bool QgsCurvePolygonV2::fromWkb( QgsConstWkbPtr wkbPtr )
110110
{
111111
QgsWKBTypes::Type curveType = wkbPtr.readHeader();
112112
wkbPtr -= 1 + sizeof( int );
113-
if ( curveType == QgsWKBTypes::LineString || curveType == QgsWKBTypes::LineStringZ || curveType == QgsWKBTypes::LineStringM ||
114-
curveType == QgsWKBTypes::LineStringZM || curveType == QgsWKBTypes::LineString25D )
113+
QgsWKBTypes::Type flatCurveType = QgsWKBTypes::flatType( curveType );
114+
if ( flatCurveType == QgsWKBTypes::LineString )
115115
{
116116
currentCurve = new QgsLineStringV2();
117117
}
118-
else if ( curveType == QgsWKBTypes::CircularString || curveType == QgsWKBTypes::CircularStringZ || curveType == QgsWKBTypes::CircularStringZM ||
119-
curveType == QgsWKBTypes::CircularStringM )
118+
else if ( flatCurveType == QgsWKBTypes::CircularString )
120119
{
121120
currentCurve = new QgsCircularStringV2();
122121
}
123-
else if ( curveType == QgsWKBTypes::CompoundCurve || curveType == QgsWKBTypes::CompoundCurveZ || curveType == QgsWKBTypes::CompoundCurveZM )
122+
else if ( flatCurveType == QgsWKBTypes::CompoundCurve )
124123
{
125124
currentCurve = new QgsCompoundCurveV2();
126125
}

src/core/geometry/qgsgeometrycollectionv2.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,22 +192,24 @@ bool QgsGeometryCollectionV2::fromWkb( QgsConstWkbPtr wkbPtr )
192192
int nGeometries = 0;
193193
wkbPtr >> nGeometries;
194194

195-
QList<QgsAbstractGeometryV2*> geometryList;
195+
QVector<QgsAbstractGeometryV2*> geometryListBackup = mGeometries;
196+
mGeometries.clear();
196197
for ( int i = 0; i < nGeometries; ++i )
197198
{
198199
QgsAbstractGeometryV2* geom = QgsGeometryFactory::geomFromWkb( wkbPtr );
199200
if ( geom )
200201
{
201-
geometryList.append( geom );
202+
if ( !addGeometry( geom ) )
203+
{
204+
qDeleteAll( mGeometries );
205+
mGeometries = geometryListBackup;
206+
return false;
207+
}
202208
wkbPtr += geom->wkbSize();
203209
}
204210
}
211+
qDeleteAll( geometryListBackup );
205212

206-
mGeometries.resize( geometryList.size() );
207-
for ( int i = 0; i < geometryList.size(); ++i )
208-
{
209-
mGeometries[i] = geometryList.at( i );
210-
}
211213
clearCache(); //set bounding box invalid
212214

213215
return true;
@@ -217,8 +219,10 @@ bool QgsGeometryCollectionV2::fromWkt( const QString& wkt )
217219
{
218220
return fromCollectionWkt( wkt, QList<QgsAbstractGeometryV2*>() << new QgsPointV2 << new QgsLineStringV2 << new QgsPolygonV2
219221
<< new QgsCircularStringV2 << new QgsCompoundCurveV2
222+
<< new QgsCurvePolygonV2
220223
<< new QgsMultiPointV2 << new QgsMultiLineStringV2
221-
<< new QgsMultiPolygonV2 << new QgsGeometryCollectionV2, "GeometryCollection" );
224+
<< new QgsMultiPolygonV2 << new QgsGeometryCollectionV2
225+
<< new QgsMultiCurveV2 << new QgsMultiSurfaceV2, "GeometryCollection" );
222226
}
223227

224228
int QgsGeometryCollectionV2::wkbSize() const

src/core/geometry/qgsmultipolygonv2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ QString QgsMultiPolygonV2::asJSON( int precision ) const
114114

115115
bool QgsMultiPolygonV2::addGeometry( QgsAbstractGeometryV2* g )
116116
{
117-
if ( !dynamic_cast<QgsCurvePolygonV2*>( g ) )
117+
if ( !dynamic_cast<QgsPolygonV2*>( g ) )
118118
{
119119
delete g;
120120
return false;

tests/src/python/test_qgsgeometry.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,6 +3304,62 @@ def testDeleteVertexCurvePolygon(self):
33043304
expected_wkt = "CurvePolygon (CompoundCurve (CircularString (0 0, 1 1, 2 0),(2 0, 0 0)))"
33053305
self.assertEqual(geom.exportToWkt(), QgsGeometry.fromWkt(expected_wkt).exportToWkt())
33063306

3307+
def testMisc(self):
3308+
3309+
# Test that we cannot add a CurvePolygon in a MultiPolygon
3310+
multipolygon = QgsMultiPolygonV2()
3311+
cp = QgsCurvePolygonV2()
3312+
cp.fromWkt("CurvePolygon ((0 0,0 1,1 1,0 0))")
3313+
assert not multipolygon.addGeometry( cp )
3314+
3315+
# Test that importing an invalid WKB (a MultiPolygon with a CurvePolygon) fails
3316+
geom = QgsGeometry.fromWkt('MultiSurface(((0 0,0 1,1 1,0 0)), CurvePolygon ((0 0,0 1,1 1,0 0)))')
3317+
wkb = geom.asWkb()
3318+
wkb = bytearray(wkb)
3319+
if wkb[1] == QgsWKBTypes.MultiSurface:
3320+
wkb[1] = QgsWKBTypes.MultiPolygon
3321+
elif wkb[1+4] == QgsWKBTypes.MultiSurface:
3322+
wkb[1+4] = QgsWKBTypes.MultiPolygon
3323+
else:
3324+
self.assertTrue(False)
3325+
geom = QgsGeometry()
3326+
geom.fromWkb(wkb)
3327+
self.assertEqual(geom.exportToWkt(), QgsMultiPolygonV2().asWkt())
3328+
3329+
# Test that fromWkt() on a GeometryCollection works with all possible geometries
3330+
wkt = "GeometryCollection( "
3331+
wkt += "Point(0 1)"
3332+
wkt += ","
3333+
wkt += "LineString(0 0,0 1)"
3334+
wkt += ","
3335+
wkt += "Polygon ((0 0,1 1,1 0,0 0))"
3336+
wkt += ","
3337+
wkt += "CurvePolygon ((0 0,1 1,1 0,0 0))"
3338+
wkt += ","
3339+
wkt += "CircularString (0 0,1 1,2 0)"
3340+
wkt += ","
3341+
wkt += "CompoundCurve ((0 0,0 1))"
3342+
wkt += ","
3343+
wkt += "MultiPoint ((0 0))"
3344+
wkt += ","
3345+
wkt += "MultiLineString((0 0,0 1))"
3346+
wkt += ","
3347+
wkt += "MultiCurve((0 0,0 1))"
3348+
wkt += ","
3349+
wkt += "MultiPolygon (((0 0,1 1,1 0,0 0)))"
3350+
wkt += ","
3351+
wkt += "MultiSurface (((0 0,1 1,1 0,0 0)))"
3352+
wkt += ","
3353+
wkt += "GeometryCollection (Point(0 0))"
3354+
wkt += ")"
3355+
geom = QgsGeometry.fromWkt(wkt)
3356+
assert geom is not None
3357+
wkb1 = geom.asWkb()
3358+
geom = QgsGeometry()
3359+
geom.fromWkb(wkb1)
3360+
wkb2 = geom.asWkb()
3361+
self.assertEqual(wkb1, wkb2)
3362+
33073363

33083364
if __name__ == '__main__':
33093365
unittest.main()

0 commit comments

Comments
 (0)