Skip to content
Permalink
Browse files

[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
  • Loading branch information
rouault committed Jun 20, 2016
1 parent dabc3b1 commit 6ea03ea4e21a176559082ed6731215efae7fe4ad
@@ -110,17 +110,16 @@ bool QgsCurvePolygonV2::fromWkb( QgsConstWkbPtr wkbPtr )
{
QgsWKBTypes::Type curveType = wkbPtr.readHeader();
wkbPtr -= 1 + sizeof( int );
if ( curveType == QgsWKBTypes::LineString || curveType == QgsWKBTypes::LineStringZ || curveType == QgsWKBTypes::LineStringM ||
curveType == QgsWKBTypes::LineStringZM || curveType == QgsWKBTypes::LineString25D )
QgsWKBTypes::Type flatCurveType = QgsWKBTypes::flatType( curveType );
if ( flatCurveType == QgsWKBTypes::LineString )
{
currentCurve = new QgsLineStringV2();
}
else if ( curveType == QgsWKBTypes::CircularString || curveType == QgsWKBTypes::CircularStringZ || curveType == QgsWKBTypes::CircularStringZM ||
curveType == QgsWKBTypes::CircularStringM )
else if ( flatCurveType == QgsWKBTypes::CircularString )
{
currentCurve = new QgsCircularStringV2();
}
else if ( curveType == QgsWKBTypes::CompoundCurve || curveType == QgsWKBTypes::CompoundCurveZ || curveType == QgsWKBTypes::CompoundCurveZM )
else if ( flatCurveType == QgsWKBTypes::CompoundCurve )
{
currentCurve = new QgsCompoundCurveV2();
}
@@ -192,22 +192,24 @@ bool QgsGeometryCollectionV2::fromWkb( QgsConstWkbPtr wkbPtr )
int nGeometries = 0;
wkbPtr >> nGeometries;

QList<QgsAbstractGeometryV2*> geometryList;
QVector<QgsAbstractGeometryV2*> geometryListBackup = mGeometries;
mGeometries.clear();
for ( int i = 0; i < nGeometries; ++i )
{
QgsAbstractGeometryV2* geom = QgsGeometryFactory::geomFromWkb( wkbPtr );
if ( geom )
{
geometryList.append( geom );
if ( !addGeometry( geom ) )
{
qDeleteAll( mGeometries );
mGeometries = geometryListBackup;
return false;
}
wkbPtr += geom->wkbSize();
}
}
qDeleteAll( geometryListBackup );

mGeometries.resize( geometryList.size() );
for ( int i = 0; i < geometryList.size(); ++i )
{
mGeometries[i] = geometryList.at( i );
}
clearCache(); //set bounding box invalid

return true;
@@ -217,8 +219,10 @@ bool QgsGeometryCollectionV2::fromWkt( const QString& wkt )
{
return fromCollectionWkt( wkt, QList<QgsAbstractGeometryV2*>() << new QgsPointV2 << new QgsLineStringV2 << new QgsPolygonV2
<< new QgsCircularStringV2 << new QgsCompoundCurveV2
<< new QgsCurvePolygonV2
<< new QgsMultiPointV2 << new QgsMultiLineStringV2
<< new QgsMultiPolygonV2 << new QgsGeometryCollectionV2, "GeometryCollection" );
<< new QgsMultiPolygonV2 << new QgsGeometryCollectionV2
<< new QgsMultiCurveV2 << new QgsMultiSurfaceV2, "GeometryCollection" );
}

int QgsGeometryCollectionV2::wkbSize() const
@@ -114,7 +114,7 @@ QString QgsMultiPolygonV2::asJSON( int precision ) const

bool QgsMultiPolygonV2::addGeometry( QgsAbstractGeometryV2* g )
{
if ( !dynamic_cast<QgsCurvePolygonV2*>( g ) )
if ( !dynamic_cast<QgsPolygonV2*>( g ) )
{
delete g;
return false;
@@ -3304,6 +3304,62 @@ def testDeleteVertexCurvePolygon(self):
expected_wkt = "CurvePolygon (CompoundCurve (CircularString (0 0, 1 1, 2 0),(2 0, 0 0)))"
self.assertEqual(geom.exportToWkt(), QgsGeometry.fromWkt(expected_wkt).exportToWkt())

def testMisc(self):

# Test that we cannot add a CurvePolygon in a MultiPolygon
multipolygon = QgsMultiPolygonV2()
cp = QgsCurvePolygonV2()
cp.fromWkt("CurvePolygon ((0 0,0 1,1 1,0 0))")
assert not multipolygon.addGeometry( cp )

# Test that importing an invalid WKB (a MultiPolygon with a CurvePolygon) fails
geom = QgsGeometry.fromWkt('MultiSurface(((0 0,0 1,1 1,0 0)), CurvePolygon ((0 0,0 1,1 1,0 0)))')
wkb = geom.asWkb()
wkb = bytearray(wkb)
if wkb[1] == QgsWKBTypes.MultiSurface:
wkb[1] = QgsWKBTypes.MultiPolygon
elif wkb[1+4] == QgsWKBTypes.MultiSurface:
wkb[1+4] = QgsWKBTypes.MultiPolygon
else:
self.assertTrue(False)
geom = QgsGeometry()
geom.fromWkb(wkb)
self.assertEqual(geom.exportToWkt(), QgsMultiPolygonV2().asWkt())

# Test that fromWkt() on a GeometryCollection works with all possible geometries
wkt = "GeometryCollection( "
wkt += "Point(0 1)"
wkt += ","
wkt += "LineString(0 0,0 1)"
wkt += ","
wkt += "Polygon ((0 0,1 1,1 0,0 0))"
wkt += ","
wkt += "CurvePolygon ((0 0,1 1,1 0,0 0))"
wkt += ","
wkt += "CircularString (0 0,1 1,2 0)"
wkt += ","
wkt += "CompoundCurve ((0 0,0 1))"
wkt += ","
wkt += "MultiPoint ((0 0))"
wkt += ","
wkt += "MultiLineString((0 0,0 1))"
wkt += ","
wkt += "MultiCurve((0 0,0 1))"
wkt += ","
wkt += "MultiPolygon (((0 0,1 1,1 0,0 0)))"
wkt += ","
wkt += "MultiSurface (((0 0,1 1,1 0,0 0)))"
wkt += ","
wkt += "GeometryCollection (Point(0 0))"
wkt += ")"
geom = QgsGeometry.fromWkt(wkt)
assert geom is not None
wkb1 = geom.asWkb()
geom = QgsGeometry()
geom.fromWkb(wkb1)
wkb2 = geom.asWkb()
self.assertEqual(wkb1, wkb2)


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

0 comments on commit 6ea03ea

Please sign in to comment.
You can’t perform that action at this time.