Fix exporting geometry collections to WKT

Child types were incorrectly being dropped when the collection
consisted of mixed geometry types (eg line & polygon) (refs #13608)
This commit is contained in:
Nyall Dawson 2015-10-16 07:48:42 +11:00
parent d70a0adc2a
commit 34dc314345
10 changed files with 69 additions and 4 deletions

View File

@ -73,4 +73,12 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
virtual bool addZValue( double zValue = 0 );
virtual bool addMValue( double mValue = 0 );
protected:
/** Returns whether child type names are omitted from Wkt representations of the collection
* @note added in QGIS 2.12
*/
virtual bool wktOmitChildType() const;
};

View File

@ -17,4 +17,8 @@ class QgsMultiLineStringV2: public QgsMultiCurveV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
protected:
virtual bool wktOmitChildType() const;
};

View File

@ -19,4 +19,8 @@ public:
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
protected:
virtual bool wktOmitChildType() const;
};

View File

@ -19,4 +19,8 @@ class QgsMultiPolygonV2: public QgsMultiSurfaceV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
protected:
virtual bool wktOmitChildType() const;
};

View File

@ -259,11 +259,8 @@ QString QgsGeometryCollectionV2::asWkt( int precision ) const
Q_FOREACH ( const QgsAbstractGeometryV2 *geom, mGeometries )
{
QString childWkt = geom->asWkt( precision );
if ( dynamic_cast<const QgsPointV2*>( geom ) ||
dynamic_cast<const QgsLineStringV2*>( geom ) ||
dynamic_cast<const QgsPolygonV2*>( geom ) )
if ( wktOmitChildType() )
{
// Type names of linear geometries are omitted
childWkt = childWkt.mid( childWkt.indexOf( "(" ) );
}
wkt += childWkt + ",";

View File

@ -125,6 +125,11 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
protected:
QVector< QgsAbstractGeometryV2* > mGeometries;
/** Returns whether child type names are omitted from Wkt representations of the collection
* @note added in QGIS 2.12
*/
virtual bool wktOmitChildType() const { return false; }
/** Reads a collection from a WKT string.
*/
bool fromCollectionWkt( const QString &wkt, const QList<QgsAbstractGeometryV2*>& subtypes, const QString& defaultChildWkbType = QString() );

View File

@ -42,6 +42,10 @@ class CORE_EXPORT QgsMultiLineStringV2: public QgsMultiCurveV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
protected:
virtual bool wktOmitChildType() const override { return true; }
};
#endif // QGSMULTILINESTRINGV2_H

View File

@ -42,6 +42,11 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollectionV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
protected:
virtual bool wktOmitChildType() const override { return true; }
};
#endif // QGSMULTIPOINTV2_H

View File

@ -42,6 +42,10 @@ class CORE_EXPORT QgsMultiPolygonV2: public QgsMultiSurfaceV2
/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
protected:
virtual bool wktOmitChildType() const override { return true; }
};
#endif // QGSMULTIPOLYGONV2_H

View File

@ -94,6 +94,36 @@ class TestQgsGeometry(TestCase):
(QGis.WKBMultiPolygon, myMultiPolygon.type()))
assert myMultiPolygon.wkbType() == QGis.WKBMultiPolygon, myMessage
def testExportToWkt(self):
# test exporting collections to wkt. MultiPolygon, MultiLineString and MultiPoint should omit child types
wkt = "MultiPolygon (((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)),((4 0, 5 0, 5 2, 3 2, 3 1, 4 1, 4 0)))"
g = QgsGeometry.fromWkt(wkt)
res = g.exportToWkt()
assert compareWkt(res, wkt), "Expected:\n%s\nGot:\n%s\n" % (wkt, res)
wkt = "MultiLineString ((0 0, 1 0, 1 1, 2 1, 2 0), (3 1, 5 1, 5 0, 6 0))"
g = QgsGeometry.fromWkt(wkt)
res = g.exportToWkt()
assert compareWkt(res, wkt), "Expected:\n%s\nGot:\n%s\n" % (wkt, res)
wkt = "MultiPoint ((10 30),(40 20),(30 10),(20 10))"
g = QgsGeometry.fromWkt(wkt)
res = g.exportToWkt()
assert compareWkt(res, wkt), "Expected:\n%s\nGot:\n%s\n" % (wkt, res)
#mixed GeometryCollection should keep child types
wkt = "GeometryCollection (Point (10 10),Point (30 30),LineString (15 15, 20 20))"
g = QgsGeometry.fromWkt(wkt)
res = g.exportToWkt()
assert compareWkt(res, wkt), "Expected:\n%s\nGot:\n%s\n" % (wkt, res)
#Multicurve should keep child type
wkt = "MultiCurve (CircularString (90 232, 95 230, 100 232),CircularString (90 232, 95 234, 100 232))"
g = QgsGeometry.fromWkt(wkt)
res = g.exportToWkt()
assert compareWkt(res, wkt), "Expected:\n%s\nGot:\n%s\n" % (wkt, res)
def testIntersection(self):
myLine = QgsGeometry.fromPolyline([
QgsPoint(0, 0),