Skip to content

Commit 9fd6b24

Browse files
committedJan 27, 2016
Move extraction of linestrings out of QgsExpression file + add unit test
1 parent 5210c12 commit 9fd6b24

File tree

4 files changed

+81
-46
lines changed

4 files changed

+81
-46
lines changed
 

‎src/core/geometry/qgsgeometryutils.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,52 @@ email : marco.hugentobler at sourcepole dot com
1414
***************************************************************************/
1515

1616
#include "qgsgeometryutils.h"
17+
18+
#include "qgscurvev2.h"
19+
#include "qgscurvepolygonv2.h"
20+
#include "qgsgeometrycollectionv2.h"
21+
#include "qgslinestringv2.h"
1722
#include "qgswkbptr.h"
23+
1824
#include <QStringList>
1925
#include <QVector>
2026

27+
QList<QgsLineStringV2*> QgsGeometryUtils::extractLineStrings(const QgsAbstractGeometryV2* geom)
28+
{
29+
QList< QgsLineStringV2* > linestrings;
30+
if ( !geom )
31+
return linestrings;
32+
33+
QList< const QgsAbstractGeometryV2 * > geometries;
34+
geometries << geom;
35+
while ( ! geometries.isEmpty() )
36+
{
37+
const QgsAbstractGeometryV2* g = geometries.takeFirst();
38+
if ( const QgsCurveV2* curve = dynamic_cast< const QgsCurveV2* >( g ) )
39+
{
40+
linestrings << static_cast< QgsLineStringV2* >( curve->segmentize() );
41+
}
42+
else if ( const QgsGeometryCollectionV2* collection = dynamic_cast< const QgsGeometryCollectionV2* >( g ) )
43+
{
44+
for ( int i = 0; i < collection->numGeometries(); ++i )
45+
{
46+
geometries.append( collection->geometryN( i ) );
47+
}
48+
}
49+
else if ( const QgsCurvePolygonV2* curvePolygon = dynamic_cast< const QgsCurvePolygonV2* >( g ) )
50+
{
51+
if ( curvePolygon->exteriorRing() )
52+
linestrings << static_cast< QgsLineStringV2* >( curvePolygon->exteriorRing()->segmentize() );
53+
54+
for ( int i = 0; i < curvePolygon->numInteriorRings(); ++i )
55+
{
56+
linestrings << static_cast< QgsLineStringV2* >( curvePolygon->interiorRing( i )->segmentize() );
57+
}
58+
}
59+
}
60+
return linestrings;
61+
}
62+
2163
QgsPointV2 QgsGeometryUtils::closestVertex( const QgsAbstractGeometryV2& geom, const QgsPointV2& pt, QgsVertexId& id )
2264
{
2365
double minDist = std::numeric_limits<double>::max();

‎src/core/geometry/qgsgeometryutils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ email : marco.hugentobler at sourcepole dot com
1919
#include "qgspointv2.h"
2020
#include <limits>
2121

22+
class QgsLineStringV2;
23+
2224
/** \ingroup core
2325
* \class QgsGeometryUtils
2426
* \brief Contains various geometry utility functions.
@@ -30,6 +32,11 @@ class CORE_EXPORT QgsGeometryUtils
3032
{
3133
public:
3234

35+
/** Returns list of linestrings extracted from the passed geometry. The returned objects
36+
* have to be deleted by the caller.
37+
*/
38+
static QList<QgsLineStringV2*> extractLineStrings( const QgsAbstractGeometryV2* geom );
39+
3340
/** Returns the closest vertex to a geometry for a specified point
3441
*/
3542
static QgsPointV2 closestVertex( const QgsAbstractGeometryV2& geom, const QgsPointV2& pt, QgsVertexId& id );

‎src/core/qgsexpression.cpp

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "qgsfeature.h"
3030
#include "qgsgeometry.h"
3131
#include "qgsgeometryengine.h"
32+
#include "qgsgeometryutils.h"
3233
#include "qgslogger.h"
3334
#include "qgsmaplayerregistry.h"
3435
#include "qgsogcutils.h"
@@ -1432,52 +1433,7 @@ static QVariant fcnSegmentsToLines( const QVariantList& values, const QgsExpress
14321433
if ( geom.isEmpty() )
14331434
return QVariant();
14341435

1435-
QList< QgsAbstractGeometryV2 * > geometries;
1436-
1437-
QgsGeometryCollectionV2* collection = dynamic_cast< QgsGeometryCollectionV2* >( geom.geometry() );
1438-
if ( collection )
1439-
{
1440-
for ( int i = 0; i < collection->numGeometries(); ++i )
1441-
{
1442-
geometries.append( collection->geometryN( i ) );
1443-
}
1444-
}
1445-
else
1446-
{
1447-
geometries.append( geom.geometry() );
1448-
}
1449-
1450-
QList< QgsLineStringV2* > linesToProcess;
1451-
while ( ! geometries.isEmpty() )
1452-
{
1453-
QgsAbstractGeometryV2* g = geometries.takeFirst();
1454-
QgsCurveV2* curve = dynamic_cast< QgsCurveV2* >( g );
1455-
if ( curve )
1456-
{
1457-
linesToProcess << static_cast< QgsLineStringV2* >( curve->segmentize() );
1458-
continue;
1459-
}
1460-
QgsGeometryCollectionV2* collection = dynamic_cast< QgsGeometryCollectionV2* >( g );
1461-
if ( collection )
1462-
{
1463-
for ( int i = 0; i < collection->numGeometries(); ++i )
1464-
{
1465-
geometries.append( collection->geometryN( i ) );
1466-
}
1467-
}
1468-
QgsCurvePolygonV2* curvePolygon = dynamic_cast< QgsCurvePolygonV2* >( g );
1469-
if ( curvePolygon )
1470-
{
1471-
if ( curvePolygon->exteriorRing() )
1472-
linesToProcess << static_cast< QgsLineStringV2* >( curvePolygon->exteriorRing()->segmentize() );
1473-
1474-
for ( int i = 0; i < curvePolygon->numInteriorRings(); ++i )
1475-
{
1476-
linesToProcess << static_cast< QgsLineStringV2* >( curvePolygon->interiorRing( i )->segmentize() );
1477-
}
1478-
continue;
1479-
}
1480-
}
1436+
QList< QgsLineStringV2* > linesToProcess = QgsGeometryUtils::extractLineStrings( geom.geometry() );
14811437

14821438
//ok, now we have a complete list of segmentized lines from the geometry
14831439
QgsMultiLineStringV2* ml = new QgsMultiLineStringV2();

‎tests/src/core/testqgsgeometryutils.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
#include <QtTest/QtTest>
1717
#include <QObject>
1818
#include "qgsgeometryutils.h"
19+
#include "qgslinestringv2.h"
20+
#include "qgspolygonv2.h"
21+
#include "qgsmultipolygonv2.h"
1922

2023
class TestQgsGeometryUtils: public QObject
2124
{
2225
Q_OBJECT
2326
private slots:
27+
void testExtractLinestrings();
2428
void testCircleClockwise_data();
2529
void testCircleClockwise();
2630
void testAngleOnCircle_data();
@@ -41,6 +45,32 @@ class TestQgsGeometryUtils: public QObject
4145
void testAverageAngle();
4246
};
4347

48+
49+
void TestQgsGeometryUtils::testExtractLinestrings()
50+
{
51+
QgsLineStringV2* outerRing1 = new QgsLineStringV2();
52+
outerRing1->setPoints( QList<QgsPointV2>() << QgsPointV2( 1, 1 ) << QgsPointV2( 1, 2 ) << QgsPointV2( 2, 2 ) << QgsPointV2( 2, 1 ) << QgsPointV2( 1, 1 ) );
53+
QgsPolygonV2* polygon1 = new QgsPolygonV2();
54+
polygon1->setExteriorRing( outerRing1 );
55+
56+
QgsLineStringV2* outerRing2 = new QgsLineStringV2();
57+
outerRing2->setPoints( QList<QgsPointV2>() << QgsPointV2( 10, 10 ) << QgsPointV2( 10, 20 ) << QgsPointV2( 20, 20 ) << QgsPointV2( 20, 10 ) << QgsPointV2( 10, 10 ) );
58+
QgsPolygonV2* polygon2 = new QgsPolygonV2();
59+
polygon2->setExteriorRing( outerRing2 );
60+
61+
QgsLineStringV2* innerRing2 = new QgsLineStringV2();
62+
innerRing2->setPoints( QList<QgsPointV2>() << QgsPointV2( 14, 14 ) << QgsPointV2( 14, 16 ) << QgsPointV2( 16, 16 ) << QgsPointV2( 16, 14 ) << QgsPointV2( 14, 14 ) );
63+
polygon2->setInteriorRings( QList<QgsCurveV2*>() << innerRing2 );
64+
65+
QgsMultiPolygonV2 mpg;
66+
mpg.addGeometry( polygon1 );
67+
mpg.addGeometry( polygon2 );
68+
69+
QList<QgsLineStringV2*> linestrings = QgsGeometryUtils::extractLineStrings( &mpg );
70+
QCOMPARE( linestrings.count(), 3 );
71+
qDeleteAll( linestrings );
72+
}
73+
4474
void TestQgsGeometryUtils::testLeftOfLine_data()
4575
{
4676
QTest::addColumn<double>( "x" );

0 commit comments

Comments
 (0)
Failed to load comments.