From a333fc8248495b3d8d110cd29e78b20ff392efa3 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 14 Oct 2015 08:21:54 +1100 Subject: [PATCH] Add method to geometries for adding z/m dimension, initialized to a specified value --- .../core/geometry/qgsabstractgeometryv2.sip | 16 +++ python/core/geometry/qgscircularstringv2.sip | 3 + python/core/geometry/qgscompoundcurvev2.sip | 3 + python/core/geometry/qgscurvepolygonv2.sip | 3 + .../core/geometry/qgsgeometrycollectionv2.sip | 3 + python/core/geometry/qgslinestringv2.sip | 3 + python/core/geometry/qgspointv2.sip | 3 + src/core/geometry/qgsabstractgeometryv2.h | 16 +++ src/core/geometry/qgscircularstringv2.cpp | 34 ++++++ src/core/geometry/qgscircularstringv2.h | 3 + src/core/geometry/qgscompoundcurvev2.cpp | 28 +++++ src/core/geometry/qgscompoundcurvev2.h | 3 + src/core/geometry/qgscurvepolygonv2.cpp | 32 ++++++ src/core/geometry/qgscurvepolygonv2.h | 3 + src/core/geometry/qgsgeometrycollectionv2.cpp | 28 +++++ src/core/geometry/qgsgeometrycollectionv2.h | 3 + src/core/geometry/qgslinestringv2.cpp | 34 ++++++ src/core/geometry/qgslinestringv2.h | 3 + src/core/geometry/qgspointv2.cpp | 20 ++++ src/core/geometry/qgspointv2.h | 3 + tests/src/python/test_qgsgeometry.py | 102 ++++++++++++++++++ 21 files changed, 346 insertions(+) diff --git a/python/core/geometry/qgsabstractgeometryv2.sip b/python/core/geometry/qgsabstractgeometryv2.sip index 6fdcaf779e9..d9bef9ac690 100644 --- a/python/core/geometry/qgsabstractgeometryv2.sip +++ b/python/core/geometry/qgsabstractgeometryv2.sip @@ -134,4 +134,20 @@ class QgsAbstractGeometryV2 virtual int vertexCount(int part = 0, int ring = 0) const = 0; virtual int ringCount(int part = 0) const = 0; virtual int partCount() const = 0; + + /** Adds a z-dimension to the geometry, initialized to a preset value. + * @param zValue initial z-value for all nodes + * @returns true on success + * @note added in QGIS 2.12 + * @see addMValue + */ + virtual bool addZValue( double zValue = 0 ) = 0; + + /** Adds a measure to the geometry, initialized to a preset value. + * @param mValue initial m-value for all nodes + * @returns true on success + * @note added in QGIS 2.12 + * @see addZValue + */ + virtual bool addMValue( double mValue = 0 ) = 0; }; diff --git a/python/core/geometry/qgscircularstringv2.sip b/python/core/geometry/qgscircularstringv2.sip index 3e3e466db73..0bb0353980b 100644 --- a/python/core/geometry/qgscircularstringv2.sip +++ b/python/core/geometry/qgscircularstringv2.sip @@ -60,6 +60,9 @@ class QgsCircularStringV2: public QgsCurveV2 @return rotation in radians, clockwise from north*/ double vertexAngle( const QgsVertexId& vertex ) const; + virtual bool addZValue( double zValue = 0 ); + virtual bool addMValue( double mValue = 0 ); + private: void segmentize( const QgsPointV2& p1, const QgsPointV2& p2, const QgsPointV2& p3, QList& points ) const; }; diff --git a/python/core/geometry/qgscompoundcurvev2.sip b/python/core/geometry/qgscompoundcurvev2.sip index 2dd19548a08..a58d8fa3656 100644 --- a/python/core/geometry/qgscompoundcurvev2.sip +++ b/python/core/geometry/qgscompoundcurvev2.sip @@ -65,4 +65,7 @@ class QgsCompoundCurveV2: public QgsCurveV2 @param vertex the vertex id @return rotation in radians, clockwise from north*/ double vertexAngle( const QgsVertexId& vertex ) const; + + virtual bool addZValue( double zValue = 0 ); + virtual bool addMValue( double mValue = 0 ); }; diff --git a/python/core/geometry/qgscurvepolygonv2.sip b/python/core/geometry/qgscurvepolygonv2.sip index 4bd559999be..2bd8e8dba32 100644 --- a/python/core/geometry/qgscurvepolygonv2.sip +++ b/python/core/geometry/qgscurvepolygonv2.sip @@ -70,4 +70,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2 virtual int vertexCount(int part = 0, int ring = 0) const; virtual int ringCount(int part = 0) const; virtual int partCount() const; + + virtual bool addZValue( double zValue = 0 ); + virtual bool addMValue( double mValue = 0 ); }; diff --git a/python/core/geometry/qgsgeometrycollectionv2.sip b/python/core/geometry/qgsgeometrycollectionv2.sip index 8cec6a1b6a7..bc4407c891d 100644 --- a/python/core/geometry/qgsgeometrycollectionv2.sip +++ b/python/core/geometry/qgsgeometrycollectionv2.sip @@ -70,4 +70,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2 virtual int ringCount(int part = 0) const; virtual int partCount() const; virtual QgsPointV2 vertexAt( const QgsVertexId& id ) const; + + virtual bool addZValue( double zValue = 0 ); + virtual bool addMValue( double mValue = 0 ); }; diff --git a/python/core/geometry/qgslinestringv2.sip b/python/core/geometry/qgslinestringv2.sip index 7b006320e40..aba911e5716 100644 --- a/python/core/geometry/qgslinestringv2.sip +++ b/python/core/geometry/qgslinestringv2.sip @@ -60,4 +60,7 @@ class QgsLineStringV2: public QgsCurveV2 @param vertex the vertex id @return rotation in radians, clockwise from north*/ double vertexAngle( const QgsVertexId& vertex ) const; + + virtual bool addZValue( double zValue = 0 ); + virtual bool addMValue( double mValue = 0 ); }; diff --git a/python/core/geometry/qgspointv2.sip b/python/core/geometry/qgspointv2.sip index 2417ce1ac5d..6335e3caa36 100644 --- a/python/core/geometry/qgspointv2.sip +++ b/python/core/geometry/qgspointv2.sip @@ -66,4 +66,7 @@ class QgsPointV2: public QgsAbstractGeometryV2 virtual int ringCount(int part = 0) const; virtual int partCount() const; virtual QgsPointV2 vertexAt( const QgsVertexId& id ) const; + + virtual bool addZValue( double zValue = 0 ); + virtual bool addMValue( double mValue = 0 ); }; diff --git a/src/core/geometry/qgsabstractgeometryv2.h b/src/core/geometry/qgsabstractgeometryv2.h index d681d9e5102..1ec59658eb7 100644 --- a/src/core/geometry/qgsabstractgeometryv2.h +++ b/src/core/geometry/qgsabstractgeometryv2.h @@ -294,6 +294,22 @@ class CORE_EXPORT QgsAbstractGeometryV2 virtual int ringCount( int part = 0 ) const = 0; virtual int partCount() const = 0; + /** Adds a z-dimension to the geometry, initialized to a preset value. + * @param zValue initial z-value for all nodes + * @returns true on success + * @note added in QGIS 2.12 + * @see addMValue + */ + virtual bool addZValue( double zValue = 0 ) = 0; + + /** Adds a measure to the geometry, initialized to a preset value. + * @param mValue initial m-value for all nodes + * @returns true on success + * @note added in QGIS 2.12 + * @see addZValue + */ + virtual bool addMValue( double mValue = 0 ) = 0; + protected: QgsWKBTypes::Type mWkbType; mutable QgsRectangle mBoundingBox; diff --git a/src/core/geometry/qgscircularstringv2.cpp b/src/core/geometry/qgscircularstringv2.cpp index 1d29db4181f..80ca6d20cce 100644 --- a/src/core/geometry/qgscircularstringv2.cpp +++ b/src/core/geometry/qgscircularstringv2.cpp @@ -1008,3 +1008,37 @@ double QgsCircularStringV2::vertexAngle( const QgsVertexId& vId ) const } return 0.0; } + +bool QgsCircularStringV2::addZValue( double zValue ) +{ + if ( QgsWKBTypes::hasZ( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addZ( mWkbType ); + + int nPoints = numPoints(); + mZ.clear(); + mZ.reserve( nPoints ); + for ( int i = 0; i < nPoints; ++i ) + { + mZ << zValue; + } + return true; +} + +bool QgsCircularStringV2::addMValue( double mValue ) +{ + if ( QgsWKBTypes::hasM( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addM( mWkbType ); + + int nPoints = numPoints(); + mM.clear(); + mM.reserve( nPoints ); + for ( int i = 0; i < nPoints; ++i ) + { + mM << mValue; + } + return true; +} diff --git a/src/core/geometry/qgscircularstringv2.h b/src/core/geometry/qgscircularstringv2.h index e4540df2e5c..99de2a4d203 100644 --- a/src/core/geometry/qgscircularstringv2.h +++ b/src/core/geometry/qgscircularstringv2.h @@ -125,6 +125,9 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2 @return rotation in radians, clockwise from north*/ double vertexAngle( const QgsVertexId& vertex ) const override; + virtual bool addZValue( double zValue = 0 ) override; + virtual bool addMValue( double mValue = 0 ) override; + private: QVector mX; QVector mY; diff --git a/src/core/geometry/qgscompoundcurvev2.cpp b/src/core/geometry/qgscompoundcurvev2.cpp index f95a6c0d982..d174d8a3144 100644 --- a/src/core/geometry/qgscompoundcurvev2.cpp +++ b/src/core/geometry/qgscompoundcurvev2.cpp @@ -608,3 +608,31 @@ double QgsCompoundCurveV2::vertexAngle( const QgsVertexId& vertex ) const } } +bool QgsCompoundCurveV2::addZValue( double zValue ) +{ + if ( QgsWKBTypes::hasZ( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addZ( mWkbType ); + + Q_FOREACH ( QgsCurveV2* curve, mCurves ) + { + curve->addZValue( zValue ); + } + return true; +} + +bool QgsCompoundCurveV2::addMValue( double mValue ) +{ + if ( QgsWKBTypes::hasM( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addM( mWkbType ); + + Q_FOREACH ( QgsCurveV2* curve, mCurves ) + { + curve->addMValue( mValue ); + } + return true; +} + diff --git a/src/core/geometry/qgscompoundcurvev2.h b/src/core/geometry/qgscompoundcurvev2.h index 6e6baee6a60..e215608a935 100644 --- a/src/core/geometry/qgscompoundcurvev2.h +++ b/src/core/geometry/qgscompoundcurvev2.h @@ -109,6 +109,9 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2 @return rotation in radians, clockwise from north*/ double vertexAngle( const QgsVertexId& vertex ) const override; + virtual bool addZValue( double zValue = 0 ) override; + virtual bool addMValue( double mValue = 0 ) override; + private: QList< QgsCurveV2* > mCurves; /** Turns a vertex id for the compound curve into one or more ids for the subcurves diff --git a/src/core/geometry/qgscurvepolygonv2.cpp b/src/core/geometry/qgscurvepolygonv2.cpp index 9a15e6fb3d1..e5550b539b7 100644 --- a/src/core/geometry/qgscurvepolygonv2.cpp +++ b/src/core/geometry/qgscurvepolygonv2.cpp @@ -700,3 +700,35 @@ QgsPointV2 QgsCurvePolygonV2::vertexAt( const QgsVertexId& id ) const { return id.ring == 0 ? mExteriorRing->vertexAt( id ) : mInteriorRings[id.ring - 1]->vertexAt( id ); } + +bool QgsCurvePolygonV2::addZValue( double zValue ) +{ + if ( QgsWKBTypes::hasZ( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addZ( mWkbType ); + + if ( mExteriorRing ) + mExteriorRing->addZValue( zValue ); + Q_FOREACH ( QgsCurveV2* curve, mInteriorRings ) + { + curve->addZValue( zValue ); + } + return true; +} + +bool QgsCurvePolygonV2::addMValue( double mValue ) +{ + if ( QgsWKBTypes::hasM( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addM( mWkbType ); + + if ( mExteriorRing ) + mExteriorRing->addMValue( mValue ); + Q_FOREACH ( QgsCurveV2* curve, mInteriorRings ) + { + curve->addMValue( mValue ); + } + return true; +} diff --git a/src/core/geometry/qgscurvepolygonv2.h b/src/core/geometry/qgscurvepolygonv2.h index a350faef9d7..f6d6ed745fa 100644 --- a/src/core/geometry/qgscurvepolygonv2.h +++ b/src/core/geometry/qgscurvepolygonv2.h @@ -103,6 +103,9 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2 virtual int partCount() const override { return ringCount() > 0 ? 1 : 0; } virtual QgsPointV2 vertexAt( const QgsVertexId& id ) const override; + virtual bool addZValue( double zValue = 0 ) override; + virtual bool addMValue( double mValue = 0 ) override; + protected: QgsCurveV2* mExteriorRing; diff --git a/src/core/geometry/qgsgeometrycollectionv2.cpp b/src/core/geometry/qgsgeometrycollectionv2.cpp index 0903bce2f0f..8cfc30358a3 100644 --- a/src/core/geometry/qgsgeometrycollectionv2.cpp +++ b/src/core/geometry/qgsgeometrycollectionv2.cpp @@ -537,3 +537,31 @@ double QgsGeometryCollectionV2::vertexAngle( const QgsVertexId& vertex ) const return geom->vertexAngle( vertex ); } + +bool QgsGeometryCollectionV2::addZValue( double zValue ) +{ + if ( QgsWKBTypes::hasZ( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addZ( mWkbType ); + + Q_FOREACH ( QgsAbstractGeometryV2* geom, mGeometries ) + { + geom->addZValue( zValue ); + } + return true; +} + +bool QgsGeometryCollectionV2::addMValue( double mValue ) +{ + if ( QgsWKBTypes::hasM( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addM( mWkbType ); + + Q_FOREACH ( QgsAbstractGeometryV2* geom, mGeometries ) + { + geom->addMValue( mValue ); + } + return true; +} diff --git a/src/core/geometry/qgsgeometrycollectionv2.h b/src/core/geometry/qgsgeometrycollectionv2.h index e5317f468c0..f17a580179b 100644 --- a/src/core/geometry/qgsgeometrycollectionv2.h +++ b/src/core/geometry/qgsgeometrycollectionv2.h @@ -119,6 +119,9 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2 virtual int partCount() const override { return mGeometries.size(); } virtual QgsPointV2 vertexAt( const QgsVertexId& id ) const override { return mGeometries[id.part]->vertexAt( id ); } + virtual bool addZValue( double zValue = 0 ) override; + virtual bool addMValue( double mValue = 0 ) override; + protected: QVector< QgsAbstractGeometryV2* > mGeometries; diff --git a/src/core/geometry/qgslinestringv2.cpp b/src/core/geometry/qgslinestringv2.cpp index 024f976d499..67eb6e373da 100644 --- a/src/core/geometry/qgslinestringv2.cpp +++ b/src/core/geometry/qgslinestringv2.cpp @@ -531,3 +531,37 @@ double QgsLineStringV2::vertexAngle( const QgsVertexId& vertex ) const return QgsGeometryUtils::averageAngle( previous.x(), previous.y(), current.x(), current.y(), after.x(), after.y() ); } } + +bool QgsLineStringV2::addZValue( double zValue ) +{ + if ( QgsWKBTypes::hasZ( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addZ( mWkbType ); + + mZ.clear(); + int nPoints = numPoints(); + mZ.reserve( nPoints ); + for ( int i = 0; i < nPoints; ++i ) + { + mZ << zValue; + } + return true; +} + +bool QgsLineStringV2::addMValue( double mValue ) +{ + if ( QgsWKBTypes::hasM( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addM( mWkbType ); + + mM.clear(); + int nPoints = numPoints(); + mM.reserve( nPoints ); + for ( int i = 0; i < nPoints; ++i ) + { + mM << mValue; + } + return true; +} diff --git a/src/core/geometry/qgslinestringv2.h b/src/core/geometry/qgslinestringv2.h index a5cad5acb57..cf5295b80bf 100644 --- a/src/core/geometry/qgslinestringv2.h +++ b/src/core/geometry/qgslinestringv2.h @@ -95,6 +95,9 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2 @return rotation in radians, clockwise from north*/ double vertexAngle( const QgsVertexId& vertex ) const override; + virtual bool addZValue( double zValue = 0 ) override; + virtual bool addMValue( double mValue = 0 ) override; + private: QPolygonF mCoords; QVector mZ; diff --git a/src/core/geometry/qgspointv2.cpp b/src/core/geometry/qgspointv2.cpp index 2b57cecf29e..c6e170d1637 100644 --- a/src/core/geometry/qgspointv2.cpp +++ b/src/core/geometry/qgspointv2.cpp @@ -244,6 +244,26 @@ bool QgsPointV2::nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const } } +bool QgsPointV2::addZValue( double zValue ) +{ + if ( QgsWKBTypes::hasZ( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addZ( mWkbType ); + mZ = zValue; + return true; +} + +bool QgsPointV2::addMValue( double mValue ) +{ + if ( QgsWKBTypes::hasM( mWkbType ) ) + return false; + + mWkbType = QgsWKBTypes::addM( mWkbType ); + mM = mValue; + return true; +} + void QgsPointV2::transform( const QTransform& t ) { qreal x, y; diff --git a/src/core/geometry/qgspointv2.h b/src/core/geometry/qgspointv2.h index fe7e4fc3a9e..01a61e49107 100644 --- a/src/core/geometry/qgspointv2.h +++ b/src/core/geometry/qgspointv2.h @@ -96,6 +96,9 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2 virtual int partCount() const override { return 1; } virtual QgsPointV2 vertexAt( const QgsVertexId& /*id*/ ) const override { return *this; } + virtual bool addZValue( double zValue = 0 ) override; + virtual bool addMValue( double mValue = 0 ) override; + private: double mX; double mY; diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index 8397c1b4988..363fe447151 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -1488,6 +1488,108 @@ class TestQgsGeometry(TestCase): assert poly.convertToSingleType() assert compareWkt(expWkt, wkt), "testConvertToSingleType failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + def testAddZValue(self): + """ Test adding z dimension to geometries """ + + #circular string + geom = QgsGeometry.fromWkt('CircularString (1 5, 6 2, 7 3)') + assert geom.geometry().addZValue(2) + assert geom.geometry().wkbType() == QgsWKBTypes.CircularStringZ + expWkt = 'CircularStringZ (1 5 2, 6 2 2, 7 3 2)' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addZValue to CircularString failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #compound curve + geom = QgsGeometry.fromWkt('CompoundCurve ((5 3, 5 13),CircularString (5 13, 7 15, 9 13),(9 13, 9 3),CircularString (9 3, 7 1, 5 3))') + assert geom.geometry().addZValue(2) + assert geom.geometry().wkbType() == QgsWKBTypes.CompoundCurveZ + expWkt = 'CompoundCurveZ ((5 3 2, 5 13 2),CircularStringZ (5 13 2, 7 15 2, 9 13 2),(9 13 2, 9 3 2),CircularStringZ (9 3 2, 7 1 2, 5 3 2))' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addZValue to CompoundCurve failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #curve polygon + geom = QgsGeometry.fromWkt('Polygon ((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0))') + assert geom.geometry().addZValue(3) + assert geom.geometry().wkbType() == QgsWKBTypes.PolygonZ + expWkt = 'PolygonZ ((0 0 3, 1 0 3, 1 1 3, 2 1 3, 2 2 3, 0 2 3, 0 0 3))' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addZValue to CurvePolygon failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #geometry collection + geom = QgsGeometry.fromWkt('MultiPoint ((1 2),(2 3))') + assert geom.geometry().addZValue(4) + assert geom.geometry().wkbType() == QgsWKBTypes.MultiPointZ + expWkt = 'MultiPointZ ((1 2 4),(2 3 4))' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addZValue to GeometryCollection failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #LineString + geom = QgsGeometry.fromWkt('LineString (1 2, 2 3)') + assert geom.geometry().addZValue(4) + assert geom.geometry().wkbType() == QgsWKBTypes.LineStringZ + expWkt = 'LineStringZ (1 2 4, 2 3 4)' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addZValue to LineString failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #Point + geom = QgsGeometry.fromWkt('Point (1 2)') + assert geom.geometry().addZValue(4) + assert geom.geometry().wkbType() == QgsWKBTypes.PointZ + expWkt = 'PointZ (1 2 4)' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addZValue to Point failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + def testAddMValue(self): + """ Test adding m dimension to geometries """ + + #circular string + geom = QgsGeometry.fromWkt('CircularString (1 5, 6 2, 7 3)') + assert geom.geometry().addMValue(2) + assert geom.geometry().wkbType() == QgsWKBTypes.CircularStringM + expWkt = 'CircularStringM (1 5 2, 6 2 2, 7 3 2)' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addMValue to CircularString failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #compound curve + geom = QgsGeometry.fromWkt('CompoundCurve ((5 3, 5 13),CircularString (5 13, 7 15, 9 13),(9 13, 9 3),CircularString (9 3, 7 1, 5 3))') + assert geom.geometry().addMValue(2) + assert geom.geometry().wkbType() == QgsWKBTypes.CompoundCurveM + expWkt = 'CompoundCurveM ((5 3 2, 5 13 2),CircularStringM (5 13 2, 7 15 2, 9 13 2),(9 13 2, 9 3 2),CircularStringM (9 3 2, 7 1 2, 5 3 2))' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addMValue to CompoundCurve failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #curve polygon + geom = QgsGeometry.fromWkt('Polygon ((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0))') + assert geom.geometry().addMValue(3) + assert geom.geometry().wkbType() == QgsWKBTypes.PolygonM + expWkt = 'PolygonM ((0 0 3, 1 0 3, 1 1 3, 2 1 3, 2 2 3, 0 2 3, 0 0 3))' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addMValue to CurvePolygon failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #geometry collection + geom = QgsGeometry.fromWkt('MultiPoint ((1 2),(2 3))') + assert geom.geometry().addMValue(4) + assert geom.geometry().wkbType() == QgsWKBTypes.MultiPointM + expWkt = 'MultiPointM ((1 2 4),(2 3 4))' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addMValue to GeometryCollection failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #LineString + geom = QgsGeometry.fromWkt('LineString (1 2, 2 3)') + assert geom.geometry().addMValue(4) + assert geom.geometry().wkbType() == QgsWKBTypes.LineStringM + expWkt = 'LineStringM (1 2 4, 2 3 4)' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addMValue to LineString failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + + #Point + geom = QgsGeometry.fromWkt('Point (1 2)') + assert geom.geometry().addMValue(4) + assert geom.geometry().wkbType() == QgsWKBTypes.PointM + expWkt = 'PointM (1 2 4)' + wkt = geom.exportToWkt() + assert compareWkt(expWkt, wkt), "addMValue to Point failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt) + def testWkbTypes(self): """ Test QgsWKBTypes methods """