diff --git a/python/core/qgsgeometry.sip b/python/core/qgsgeometry.sip index ccde3aa0342..35edf58fa6f 100644 --- a/python/core/qgsgeometry.sip +++ b/python/core/qgsgeometry.sip @@ -356,6 +356,14 @@ class QgsGeometry */ QString exportToGeoJSON() const; + /** try to convert the geometry to the requested type + * @param destType the geometry type to be converted to + * @param destMultipart determines if the output geometry will be multipart or not + * @return the converted geometry or NULL pointer if the conversion fails. + * @note added in 2.2 + */ + QgsGeometry* convertToType( QGis::GeometryType destType, bool destMultipart = false ) /Factory/; + /* Accessor functions for getting geometry data */ /** return contents of the geometry as a point diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 24d79405403..a8eced3c62d 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -5580,6 +5580,7 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer ) { features = clipboard()->copyOf( pasteVectorLayer->pendingFields() ); } + int nTotalFeatures = features.count(); QHash remap; const QgsFields &fields = clipboard()->fields(); @@ -5594,10 +5595,11 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer ) } int dstAttrCount = pasteVectorLayer->pendingFields().count(); - for ( int i = 0; i < features.size(); i++ ) + + QgsFeatureList::iterator featureIt = features.begin(); + while ( featureIt != features.end() ) { - QgsFeature &f = features[i]; - const QgsAttributes &srcAttr = f.attributes(); + const QgsAttributes &srcAttr = featureIt->attributes(); QgsAttributes dstAttr( dstAttrCount ); for ( int src = 0; src < srcAttr.count(); ++src ) @@ -5617,17 +5619,54 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer ) dstAttr[ dst ] = srcAttr[ src ]; } - f.setAttributes( dstAttr ); + featureIt->setAttributes( dstAttr ); - //avoid intersection if enabled in digitize settings - if ( f.geometry() ) + if ( featureIt->geometry() ) { - f.geometry()->avoidIntersections(); + // convert geometry to match destination layer + QGis::GeometryType destType = pasteVectorLayer->geometryType(); + bool destIsMulti = QGis::isMultiType( pasteVectorLayer->wkbType() ); + if ( destType != QGis::UnknownGeometry ) + { + QgsGeometry* newGeometry = featureIt->geometry()->convertToType( destType, destIsMulti ); + if ( !newGeometry ) + { + featureIt = features.erase( featureIt ); + continue; + } + featureIt->setGeometry( newGeometry ); + } + // avoid intersection if enabled in digitize settings + featureIt->geometry()->avoidIntersections(); } + + ++featureIt; } pasteVectorLayer->addFeatures( features ); pasteVectorLayer->endEditCommand(); + + int nCopiedFeatures = features.count(); + if ( nCopiedFeatures == 0 ) + { + messageBar()->pushMessage( tr( "Paste features" ), + tr( "no features could be successfully pasted." ), + QgsMessageBar::WARNING , messageTimeout() ); + + } + else if ( nCopiedFeatures == nTotalFeatures ) + { + messageBar()->pushMessage( tr( "Paste features" ), + tr( "%1 features were successfully pasted." ).arg( nCopiedFeatures ), + QgsMessageBar::INFO , messageTimeout() ); + } + else + { + messageBar()->pushMessage( tr( "Paste features" ), + tr( "%1 of %2 features could be successfully pasted." ).arg( nCopiedFeatures ).arg( nTotalFeatures ), + QgsMessageBar::WARNING , messageTimeout() ); + } + mMapCanvas->refresh(); } diff --git a/src/core/qgsgeometry.cpp b/src/core/qgsgeometry.cpp index 99bb5248c58..2162ba4f34a 100644 --- a/src/core/qgsgeometry.cpp +++ b/src/core/qgsgeometry.cpp @@ -4423,6 +4423,24 @@ bool QgsGeometry::exportGeosToWkb() const return false; } +QgsGeometry* QgsGeometry::convertToType( QGis::GeometryType destType, bool destMultipart ) +{ + switch ( destType ) + { + case QGis::Point: + return convertToPoint( destMultipart ); + + case QGis::Line: + return convertToLine( destMultipart ); + + case QGis::Polygon: + return convertToPolygon( destMultipart ); + + default: + return 0; + } +} + bool QgsGeometry::convertToMultiType() { // TODO: implement with GEOS @@ -5976,3 +5994,321 @@ double QgsGeometry::leftOf( double x, double y, double& x1, double& y1, double& double f4 = x2 - x1; return f1*f2 - f3*f4; } + +QgsGeometry* QgsGeometry::convertToPoint( bool destMultipart ) +{ + switch ( type() ) + { + case QGis::Point: + { + bool srcIsMultipart = isMultipart(); + + if (( destMultipart && srcIsMultipart ) || + ( !destMultipart && !srcIsMultipart ) ) + { + // return a copy of the same geom + return new QgsGeometry( *this ); + } + if ( destMultipart ) + { + // layer is multipart => make a multipoint with a single point + return fromMultiPoint( QgsMultiPoint() << asPoint() ); + } + else + { + // destination is singlepart => make a single part if possible + QgsMultiPoint multiPoint = asMultiPoint(); + if ( multiPoint.count() == 1 ) + { + return fromPoint( multiPoint[0] ); + } + } + return 0; + } + + case QGis::Line: + { + // only possible if destination is multipart + if ( !destMultipart ) + return 0; + + // input geometry is multipart + if ( isMultipart() ) + { + QgsMultiPolyline multiLine = asMultiPolyline(); + QgsMultiPoint multiPoint; + for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt ) + for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt ) + multiPoint << *lineIt; + return fromMultiPoint( multiPoint ); + } + // input geometry is not multipart: copy directly the line into a multipoint + else + { + QgsPolyline line = asPolyline(); + if ( !line.isEmpty() ) + return fromMultiPoint( line ); + } + return 0; + } + + case QGis::Polygon: + { + // can only transfrom if destination is multipoint + if ( !destMultipart ) + return 0; + + // input geometry is multipart: make a multipoint from multipolygon + if ( isMultipart() ) + { + QgsMultiPolygon multiPolygon = asMultiPolygon(); + QgsMultiPoint multiPoint; + for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt ) + for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt ) + for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt ) + multiPoint << *lineIt; + return fromMultiPoint( multiPoint ); + } + // input geometry is not multipart: make a multipoint from polygon + else + { + QgsPolygon polygon = asPolygon(); + QgsMultiPoint multiPoint; + for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt ) + for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt ) + multiPoint << *lineIt; + return fromMultiPoint( multiPoint ); + } + return 0; + } + + default: + return 0; + } +} + +QgsGeometry* QgsGeometry::convertToLine( bool destMultipart ) +{ + switch ( type() ) + { + case QGis::Point: + { + if ( !isMultipart() ) + return 0; + + QgsMultiPoint multiPoint = asMultiPoint(); + if ( multiPoint.count() < 2 ) + return 0; + + if ( destMultipart ) + return fromMultiPolyline( QgsMultiPolyline() << multiPoint ); + else + return fromPolyline( multiPoint ); + } + + case QGis::Line: + { + bool srcIsMultipart = isMultipart(); + + if (( destMultipart && srcIsMultipart ) || + ( !destMultipart && ! srcIsMultipart ) ) + { + // return a copy of the same geom + return new QgsGeometry( *this ); + } + if ( destMultipart ) + { + // destination is multipart => makes a multipoint with a single line + QgsPolyline line = asPolyline(); + if ( !line.isEmpty() ) + return fromMultiPolyline( QgsMultiPolyline() << line ); + } + else + { + // destination is singlepart => make a single part if possible + QgsMultiPolyline multiLine = asMultiPolyline(); + if ( multiLine.count() == 1 ) + return fromPolyline( multiLine[0] ); + } + return 0; + } + + case QGis::Polygon: + { + // input geometry is multipolygon + if ( isMultipart() ) + { + QgsMultiPolygon multiPolygon = asMultiPolygon(); + QgsMultiPolyline multiLine; + for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt ) + for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt ) + multiLine << *multiLineIt; + + if ( destMultipart ) + { + // destination is multipart + return fromMultiPolyline( multiLine ); + } + else if ( multiLine.count() == 1 ) + { + // destination is singlepart => make a single part if possible + return fromPolyline( multiLine[0] ); + } + } + // input geometry is single polygon + else + { + QgsPolygon polygon = asPolygon(); + // if polygon has rings + if ( polygon.count() > 1 ) + { + // cannot fit a polygon with rings in a single line layer + // TODO: would it be better to remove rings? + if ( destMultipart ) + { + QgsPolygon polygon = asPolygon(); + QgsMultiPolyline multiLine; + for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt ) + multiLine << *multiLineIt; + return fromMultiPolyline( multiLine ); + } + } + // no rings + else if ( polygon.count() == 1 ) + { + if ( destMultipart ) + { + return fromMultiPolyline( polygon ); + } + else + { + return fromPolyline( polygon[0] ); + } + } + } + return 0; + } + + default: + return 0; + } +} + +QgsGeometry* QgsGeometry::convertToPolygon( bool destMultipart ) +{ + switch ( type() ) + { + case QGis::Point: + { + if ( !isMultipart() ) + return 0; + + QgsMultiPoint multiPoint = asMultiPoint(); + if ( multiPoint.count() < 3 ) + return 0; + + if ( multiPoint.last() != multiPoint.first() ) + multiPoint << multiPoint.first(); + + QgsPolygon polygon = QgsPolygon() << multiPoint; + if ( destMultipart ) + return fromMultiPolygon( QgsMultiPolygon() << polygon ); + else + return fromPolygon( polygon ); + } + + case QGis::Line: + { + // input geometry is multiline + if ( isMultipart() ) + { + QgsMultiPolyline multiLine = asMultiPolyline(); + QgsMultiPolygon multiPolygon; + for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt ) + { + // do not create polygon for a 1 segment line + if (( *multiLineIt ).count() < 3 ) + return 0; + if (( *multiLineIt ).count() == 3 && ( *multiLineIt ).first() == ( *multiLineIt ).last() ) + return 0; + + // add closing node + if (( *multiLineIt ).first() != ( *multiLineIt ).last() ) + *multiLineIt << ( *multiLineIt ).first(); + multiPolygon << ( QgsPolygon() << *multiLineIt ); + } + // check that polygons were inserted + if ( !multiPolygon.isEmpty() ) + { + if ( destMultipart ) + { + return fromMultiPolygon( multiPolygon ); + } + else if ( multiPolygon.count() == 1 ) + { + // destination is singlepart => make a single part if possible + return fromPolygon( multiPolygon[0] ); + } + } + } + // input geometry is single line + else + { + QgsPolyline line = asPolyline(); + + // do not create polygon for a 1 segment line + if ( line.count() < 3 ) + return 0; + if ( line.count() == 3 && line.first() == line.last() ) + return 0; + + // add closing node + if ( line.first() != line.last() ) + line << line.first(); + + // destination is multipart + if ( destMultipart ) + { + return fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << line ) ); + } + else + { + return fromPolygon( QgsPolygon() << line ); + } + } + return 0; + } + + case QGis::Polygon: + { + bool srcIsMultipart = isMultipart(); + + if (( destMultipart && srcIsMultipart ) || + ( !destMultipart && ! srcIsMultipart ) ) + { + // return a copy of the same geom + return new QgsGeometry( *this ); + } + if ( destMultipart ) + { + // destination is multipart => makes a multipoint with a single polygon + QgsPolygon polygon = asPolygon(); + if ( !polygon.isEmpty() ) + return fromMultiPolygon( QgsMultiPolygon() << polygon ); + } + else + { + QgsMultiPolygon multiPolygon = asMultiPolygon(); + if ( multiPolygon.count() == 1 ) + { + // destination is singlepart => make a single part if possible + return fromPolygon( multiPolygon[0] ); + } + } + return 0; + } + + default: + return 0; + } +} diff --git a/src/core/qgsgeometry.h b/src/core/qgsgeometry.h index a1fc1dee4bf..8b254475abb 100644 --- a/src/core/qgsgeometry.h +++ b/src/core/qgsgeometry.h @@ -397,6 +397,15 @@ class CORE_EXPORT QgsGeometry */ QString exportToGeoJSON() const; + /** try to convert the geometry to the requested type + * @param destType the geometry type to be converted to + * @param destMultipart determines if the output geometry will be multipart or not + * @return the converted geometry or NULL pointer if the conversion fails. + * @note added in 2.2 + */ + QgsGeometry* convertToType( QGis::GeometryType destType, bool destMultipart = false ); + + /* Accessor functions for getting geometry data */ /** return contents of the geometry as a point @@ -611,6 +620,13 @@ class CORE_EXPORT QgsGeometry static inline bool moveVertex( QgsWkbPtr &wkbPtr, const double &x, const double &y, int atVertex, bool hasZValue, int &pointIndex, bool isRing ); static inline bool deleteVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int atVertex, bool hasZValue, int &pointIndex, bool isRing, bool lastItem ); static inline bool insertVertex( QgsConstWkbPtr &srcPtr, QgsWkbPtr &dstPtr, int beforeVertex, const double &x, const double &y, bool hasZValue, int &pointIndex, bool isRing ); + + /** try to convert the geometry to a point */ + QgsGeometry* convertToPoint( bool destMultipart ); + /** try to convert the geometry to a line */ + QgsGeometry* convertToLine( bool destMultipart ); + /** try to convert the geometry to a polygon */ + QgsGeometry* convertToPolygon( bool destMultipart ); }; // class QgsGeometry Q_DECLARE_METATYPE( QgsGeometry ); diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index 36cab2012c3..3044fc01bf8 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -1145,5 +1145,150 @@ class TestQgsGeometry(TestCase): wkt = polygon.exportToWkt() assert compareWkt( expwkt, wkt ), "Expected:\n%s\nGot:\n%s\n" % (expwkt, wkt ) + def testConvertToType(self): + # 5-+-4 0-+-9 13-+-+-12 + # | | | | | | + # | 2-3 1-2 | + 18-17 + + # | | | | | | | | + # 0-1 7-8 + 15-16 + + # | | + # 10-+-+-11 + points = [ + [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0) ], ], + [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0) ], ], + [ [ QgsPoint(10,0), QgsPoint(13,0), QgsPoint(13,3), QgsPoint(10,3), QgsPoint(10,0) ], [ QgsPoint(11,1), QgsPoint(12,1), QgsPoint(12,2), QgsPoint(11,2), QgsPoint(11,1) ] ] + ] + ######## TO POINT ######## + # POINT TO POINT + point = QgsGeometry.fromPoint(QgsPoint(1,1)) + wkt = point.convertToType(QGis.Point, False).exportToWkt() + expWkt = "POINT(1 1)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from point to point. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # POINT TO MULTIPOINT + point = QgsGeometry.fromPoint(QgsPoint(1,1)) + wkt = point.convertToType(QGis.Point, True).exportToWkt() + expWkt = "MULTIPOINT(1 1)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from point to multipoint. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # LINE TO MULTIPOINT + line = QgsGeometry.fromPolyline(points[0][0]) + wkt = line.convertToType(QGis.Point, True).exportToWkt() + expWkt = "MULTIPOINT(0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from line to multipoint. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTILINE TO MULTIPOINT + multiLine = QgsGeometry.fromMultiPolyline(points[2]) + wkt = multiLine.convertToType(QGis.Point, True).exportToWkt() + expWkt = "MULTIPOINT(10 0, 13 0, 13 3, 10 3, 10 0, 11 1, 12 1, 12 2, 11 2, 11 1)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multiline to multipoint. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # POLYGON TO MULTIPOINT + polygon = QgsGeometry.fromPolygon(points[0]) + wkt = polygon.convertToType(QGis.Point, True).exportToWkt() + expWkt = "MULTIPOINT(0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from poylgon to multipoint. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTIPOLYGON TO MULTIPOINT + multiPolygon = QgsGeometry.fromMultiPolygon(points) + wkt = multiPolygon.convertToType(QGis.Point, True).exportToWkt() + expWkt = "MULTIPOINT(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, 10 0, 13 0, 13 3, 10 3, 10 0, 11 1, 12 1, 12 2, 11 2, 11 1)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipoylgon to multipoint. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + + + ######## TO LINE ######## + # POINT TO LINE + point = QgsGeometry.fromPoint(QgsPoint(1,1)) + assert point.convertToType(QGis.Line, False) is None , "convertToType with a point should return a null geometry" + # MULTIPOINT TO LINE + multipoint = QgsGeometry.fromMultiPoint(points[0][0]) + wkt = multipoint.convertToType(QGis.Line, False).exportToWkt() + expWkt = "LINESTRING(0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipoint to line. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTIPOINT TO MULTILINE + multipoint = QgsGeometry.fromMultiPoint(points[0][0]) + wkt = multipoint.convertToType(QGis.Line, True).exportToWkt() + expWkt = "MULTILINESTRING((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipoint to multiline. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTILINE (which has a single part) TO LINE + multiLine = QgsGeometry.fromMultiPolyline(points[0]) + wkt = multiLine.convertToType(QGis.Line, False).exportToWkt() + expWkt = "LINESTRING(0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multiline to line. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # LINE TO MULTILINE + line = QgsGeometry.fromPolyline(points[0][0]) + wkt = line.convertToType(QGis.Line, True).exportToWkt() + expWkt = "MULTILINESTRING((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from line to multiline. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # POLYGON TO LINE + polygon = QgsGeometry.fromPolygon(points[0]) + wkt = polygon.convertToType(QGis.Line, False).exportToWkt() + expWkt = "LINESTRING(0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from polygon to line. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # POLYGON TO MULTILINE + polygon = QgsGeometry.fromPolygon(points[0]) + wkt = polygon.convertToType(QGis.Line, True).exportToWkt() + expWkt = "MULTILINESTRING((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from polygon to multiline. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # POLYGON with ring TO MULTILINE + polygon = QgsGeometry.fromPolygon(points[2]) + wkt = polygon.convertToType(QGis.Line, True).exportToWkt() + expWkt = "MULTILINESTRING((10 0, 13 0, 13 3, 10 3, 10 0), (11 1, 12 1, 12 2, 11 2, 11 1))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from polygon with ring to multiline. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTIPOLYGON (which has a single part) TO LINE + multiPolygon = QgsGeometry.fromMultiPolygon([points[0]]) + wkt = multiPolygon.convertToType(QGis.Line, False).exportToWkt() + expWkt = "LINESTRING(0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipolygon to multiline. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTIPOLYGON TO MULTILINE + multiPolygon = QgsGeometry.fromMultiPolygon(points) + wkt = multiPolygon.convertToType(QGis.Line, True).exportToWkt() + expWkt = "MULTILINESTRING((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), (10 0, 13 0, 13 3, 10 3, 10 0), (11 1, 12 1, 12 2, 11 2, 11 1))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipolygon to multiline. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + + + ######## TO POLYGON ######## + # MULTIPOINT TO POLYGON + multipoint = QgsGeometry.fromMultiPoint(points[0][0]) + wkt = multipoint.convertToType(QGis.Polygon, False).exportToWkt() + expWkt = "POLYGON((0 0,1 0,1 1,2 1,2 2,0 2,0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipoint to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTIPOINT TO MULTIPOLYGON + multipoint = QgsGeometry.fromMultiPoint(points[0][0]) + wkt = multipoint.convertToType(QGis.Polygon, True).exportToWkt() + expWkt = "MULTIPOLYGON(((0 0,1 0,1 1,2 1,2 2,0 2,0 0)))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multipoint to multipolygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # LINE TO POLYGON + line = QgsGeometry.fromPolyline(points[0][0]) + wkt = line.convertToType(QGis.Polygon, False).exportToWkt() + expWkt = "POLYGON((0 0,1 0,1 1,2 1,2 2,0 2,0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from line to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # LINE ( 3 vertices, with first = last ) TO POLYGON + line = QgsGeometry.fromPolyline([QgsPoint(1,1),QgsPoint(0,0),QgsPoint(1,1)]) + assert line.convertToType(QGis.Polygon, False) is None , "convertToType to polygon of a 3 vertices lines with first and last vertex identical should return a null geometry" + # MULTILINE ( with a part of 3 vertices, with first = last ) TO MULTIPOLYGON + multiline = QgsGeometry.fromMultiPolyline([points[0][0],[QgsPoint(1,1),QgsPoint(0,0),QgsPoint(1,1)]]) + assert multiline.convertToType(QGis.Polygon, True) is None , "convertToType to polygon of a 3 vertices lines with first and last vertex identical should return a null geometry" + # LINE TO MULTIPOLYGON + line = QgsGeometry.fromPolyline(points[0][0]) + wkt = line.convertToType(QGis.Polygon, True).exportToWkt() + expWkt = "MULTIPOLYGON(((0 0,1 0,1 1,2 1,2 2,0 2,0 0)))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from line to multipolygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTILINE (which has a single part) TO POLYGON + multiLine = QgsGeometry.fromMultiPolyline(points[0]) + wkt = multiLine.convertToType(QGis.Polygon, False).exportToWkt() + expWkt = "POLYGON((0 0,1 0,1 1,2 1,2 2,0 2,0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multiline to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTILINE TO MULTIPOLYGON + multiLine = QgsGeometry.fromMultiPolyline([points[0][0],points[1][0]]) + wkt = multiLine.convertToType(QGis.Polygon, True).exportToWkt() + expWkt = "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)))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multiline to multipolygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # POLYGON TO MULTIPOLYGON + polygon = QgsGeometry.fromPolygon(points[0]) + wkt = polygon.convertToType(QGis.Polygon, True).exportToWkt() + expWkt = "MULTIPOLYGON(((0 0,1 0,1 1,2 1,2 2,0 2,0 0)))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from polygon to multipolygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + # MULTIPOLYGON (which has a single part) TO POLYGON + multiPolygon = QgsGeometry.fromMultiPolygon([points[0]]) + wkt = multiPolygon.convertToType(QGis.Polygon, False).exportToWkt() + expWkt = "POLYGON((0 0,1 0,1 1,2 1,2 2,0 2,0 0))" + assert compareWkt( expWkt, wkt ), "convertToType failed: from multiline to polygon. Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt ) + if __name__ == '__main__': unittest.main()