Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 34dc314
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 4 deletions.
8 changes: 8 additions & 0 deletions python/core/geometry/qgsgeometrycollectionv2.sip
Expand Up @@ -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;

};
4 changes: 4 additions & 0 deletions python/core/geometry/qgsmultilinestringv2.sip
Expand Up @@ -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;
};
4 changes: 4 additions & 0 deletions python/core/geometry/qgsmultipointv2.sip
Expand Up @@ -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;
};
4 changes: 4 additions & 0 deletions python/core/geometry/qgsmultipolygonv2.sip
Expand Up @@ -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;
};
5 changes: 1 addition & 4 deletions src/core/geometry/qgsgeometrycollectionv2.cpp
Expand Up @@ -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 + ",";
Expand Down
5 changes: 5 additions & 0 deletions src/core/geometry/qgsgeometrycollectionv2.h
Expand Up @@ -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() );
Expand Down
4 changes: 4 additions & 0 deletions src/core/geometry/qgsmultilinestringv2.h
Expand Up @@ -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
5 changes: 5 additions & 0 deletions src/core/geometry/qgsmultipointv2.h
Expand Up @@ -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
4 changes: 4 additions & 0 deletions src/core/geometry/qgsmultipolygonv2.h
Expand Up @@ -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
30 changes: 30 additions & 0 deletions tests/src/python/test_qgsgeometry.py
Expand Up @@ -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),
Expand Down

0 comments on commit 34dc314

Please sign in to comment.