Merge pull request #1120 from 3nids/pasteconvertgeom

copy/paste: try to convert geometries (fixes #3604)
This commit is contained in:
Jürgen Fischer 2014-03-03 09:38:30 +01:00
commit 2f2d6ac95b
5 changed files with 551 additions and 7 deletions

View File

@ -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

View File

@ -5580,6 +5580,7 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
{
features = clipboard()->copyOf( pasteVectorLayer->pendingFields() );
}
int nTotalFeatures = features.count();
QHash<int, int> 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();
}

View File

@ -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;
}
}

View File

@ -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 );

View File

@ -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()