Skip to content
Permalink
Browse files

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)
  • Loading branch information
nyalldawson committed Oct 15, 2015
1 parent d70a0ad commit 34dc314345997ae0a969c0b203294d9972b6e2dc
@@ -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;

};
@@ -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;
};
@@ -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;
};
@@ -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;
};
@@ -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 + ",";
@@ -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() );
@@ -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
@@ -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
@@ -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
@@ -94,6 +94,36 @@ def testFromMultiPolygon(self):
(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),

0 comments on commit 34dc314

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