Skip to content

Commit b620b6e

Browse files
committed
Add method to QgsGeometryFactory to create a multigeometry
from any wkb type Eg calling QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PolygonM ) will return a new QgsMultiPolygonV2 with M values.
1 parent f5f0a29 commit b620b6e

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

src/core/geometry/qgsgeometryfactory.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,39 @@ QgsAbstractGeometry *QgsGeometryFactory::geomFromWkbType( QgsWkbTypes::Type t )
264264
return nullptr;
265265
}
266266
}
267+
268+
std::unique_ptr<QgsGeometryCollection> QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::Type t )
269+
{
270+
QgsWkbTypes::Type type = QgsWkbTypes::flatType( QgsWkbTypes::multiType( t ) );
271+
std::unique_ptr< QgsGeometryCollection > collect;
272+
switch ( type )
273+
{
274+
case QgsWkbTypes::MultiPoint:
275+
collect.reset( new QgsMultiPointV2() );
276+
break;
277+
case QgsWkbTypes::MultiLineString:
278+
collect.reset( new QgsMultiLineString() );
279+
break;
280+
case QgsWkbTypes::MultiCurve:
281+
collect.reset( new QgsMultiCurve() );
282+
break;
283+
case QgsWkbTypes::MultiPolygon:
284+
collect.reset( new QgsMultiPolygonV2() );
285+
break;
286+
case QgsWkbTypes::MultiSurface:
287+
collect.reset( new QgsMultiSurface() );
288+
break;
289+
case QgsWkbTypes::GeometryCollection:
290+
collect.reset( new QgsGeometryCollection() );
291+
break;
292+
default:
293+
// should not be possible
294+
return nullptr;
295+
}
296+
if ( QgsWkbTypes::hasM( t ) )
297+
collect->addMValue();
298+
if ( QgsWkbTypes::hasZ( t ) )
299+
collect->addZValue();
300+
301+
return collect;
302+
}

src/core/geometry/qgsgeometryfactory.h

+8
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121
#include "qgis_core.h"
2222
#include <QString>
23+
#include <memory>
2324

2425
class QgsAbstractGeometry;
2526
class QgsLineString;
2627
class QgsConstWkbPtr;
2728
class QgsRectangle;
29+
class QgsGeometryCollection;
2830

2931
//compatibility with old classes
3032
#include "qgspointxy.h"
@@ -70,6 +72,12 @@ class CORE_EXPORT QgsGeometryFactory
7072
//! Return empty geometry from wkb type
7173
static QgsAbstractGeometry *geomFromWkbType( QgsWkbTypes::Type t );
7274

75+
/**
76+
* Returns a new geometry collection matching a specified WKB \a type. For instance, if
77+
* type is PolygonM the returned geometry will be a QgsMultiPolygonV2 with M values.
78+
*/
79+
static std::unique_ptr< QgsGeometryCollection > createCollectionOfType( QgsWkbTypes::Type type );
80+
7381
private:
7482
static QgsLineString *linestringFromPolyline( const QgsPolyline &polyline );
7583
};

tests/src/core/testqgsgeometry.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class TestQgsGeometry : public QObject
127127
void isSimple();
128128

129129
void reshapeGeometryLineMerge();
130+
void createCollectionOfType();
130131

131132
private:
132133
//! A helper method to do a render check to see if the geometry op is as expected
@@ -5540,5 +5541,38 @@ void TestQgsGeometry::reshapeGeometryLineMerge()
55405541
QCOMPARE( g3D_2.exportToWkt(), QString( "LineStringZ (-10 -10 -1, 10 10 1, 20 20 2)" ) );
55415542
}
55425543

5544+
void TestQgsGeometry::createCollectionOfType()
5545+
{
5546+
std::unique_ptr< QgsGeometryCollection > collect( QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::Unknown ) );
5547+
QVERIFY( !collect );
5548+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::Point );
5549+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPoint );
5550+
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
5551+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PointM );
5552+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPointM );
5553+
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
5554+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PointZM );
5555+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPointZM );
5556+
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
5557+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PointZ );
5558+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPointZ );
5559+
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
5560+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::MultiPoint );
5561+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPoint );
5562+
QVERIFY( dynamic_cast< QgsMultiPointV2 *>( collect.get() ) );
5563+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::LineStringZ );
5564+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiLineStringZ );
5565+
QVERIFY( dynamic_cast< QgsMultiLineString *>( collect.get() ) );
5566+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::PolygonM );
5567+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiPolygonM );
5568+
QVERIFY( dynamic_cast< QgsMultiPolygonV2 *>( collect.get() ) );
5569+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::GeometryCollectionZ );
5570+
QCOMPARE( collect->wkbType(), QgsWkbTypes::GeometryCollectionZ );
5571+
QVERIFY( dynamic_cast< QgsGeometryCollection *>( collect.get() ) );
5572+
collect = QgsGeometryFactory::createCollectionOfType( QgsWkbTypes::CurvePolygonM );
5573+
QCOMPARE( collect->wkbType(), QgsWkbTypes::MultiSurfaceM );
5574+
QVERIFY( dynamic_cast< QgsMultiSurface *>( collect.get() ) );
5575+
}
5576+
55435577
QGSTEST_MAIN( TestQgsGeometry )
55445578
#include "testqgsgeometry.moc"

0 commit comments

Comments
 (0)