Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
with
273 additions
and 1 deletion.
@@ -0,0 +1,271 @@ | ||
/*************************************************************************** | ||
testqgsnetworkanalysis.cpp | ||
-------------------------- | ||
Date : November 2016 | ||
Copyright : (C) 2016 by Nyall Dawson | ||
Email : nyall dot dawson at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
#include "qgstest.h" | ||
|
||
//header for class being tested | ||
#include "qgsgeometrysnapper.h" | ||
#include "qgsgeometry.h" | ||
#include <qgsapplication.h> | ||
#include "qgsvectordataprovider.h" | ||
#include "qgsvectorlayer.h" | ||
#include "qgsvectorlayerdirector.h" | ||
#include "qgsnetworkdistancestrategy.h" | ||
#include "qgsgraphbuilder.h" | ||
#include "qgsgraph.h" | ||
|
||
class TestQgsNetworkAnalysis : public QObject | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
|
||
private slots: | ||
void initTestCase();// will be called before the first testfunction is executed. | ||
void cleanupTestCase();// will be called after the last testfunction was executed. | ||
void init() ;// will be called before each testfunction is executed. | ||
void cleanup() ;// will be called after every testfunction. | ||
void testGraph(); | ||
void testBuild(); | ||
void testBuildTolerance(); | ||
|
||
private: | ||
std::unique_ptr< QgsVectorLayer > buildNetwork(); | ||
|
||
|
||
}; | ||
|
||
void TestQgsNetworkAnalysis::initTestCase() | ||
{ | ||
// | ||
// Runs once before any tests are run | ||
// | ||
// init QGIS's paths - true means that all path will be inited from prefix | ||
QgsApplication::init(); | ||
QgsApplication::initQgis(); | ||
} | ||
void TestQgsNetworkAnalysis::cleanupTestCase() | ||
{ | ||
QgsApplication::exitQgis(); | ||
} | ||
void TestQgsNetworkAnalysis::init() | ||
{ | ||
|
||
} | ||
void TestQgsNetworkAnalysis::cleanup() | ||
{ | ||
|
||
} | ||
|
||
void TestQgsNetworkAnalysis::testGraph() | ||
{ | ||
QgsGraph graph; | ||
QCOMPARE( graph.vertexCount(), 0 ); | ||
QCOMPARE( graph.edgeCount(), 0 ); | ||
graph.addVertex( QgsPointXY( 1, 2 ) ); | ||
QCOMPARE( graph.vertexCount(), 1 ); | ||
QCOMPARE( graph.vertex( 0 ).point(), QgsPointXY( 1, 2 ) ); | ||
QVERIFY( graph.vertex( 0 ).inEdges().empty() ); | ||
QVERIFY( graph.vertex( 0 ).outEdges().empty() ); | ||
QCOMPARE( graph.findVertex( QgsPointXY( 1, 2 ) ), 0 ); | ||
graph.addVertex( QgsPointXY( 3, 4 ) ); | ||
QCOMPARE( graph.vertexCount(), 2 ); | ||
QCOMPARE( graph.vertex( 1 ).point(), QgsPointXY( 3, 4 ) ); | ||
QVERIFY( graph.vertex( 1 ).inEdges().empty() ); | ||
QVERIFY( graph.vertex( 1 ).outEdges().empty() ); | ||
QCOMPARE( graph.findVertex( QgsPointXY( 1, 2 ) ), 0 ); | ||
QCOMPARE( graph.findVertex( QgsPointXY( 3, 4 ) ), 1 ); | ||
QCOMPARE( graph.edgeCount(), 0 ); | ||
|
||
graph.addEdge( 1, 0, QVector< QVariant >() << 9 ); | ||
QCOMPARE( graph.edgeCount(), 1 ); | ||
QCOMPARE( graph.edge( 0 ).cost( 0 ).toInt(), 9 ); | ||
QCOMPARE( graph.edge( 0 ).inVertex(), 0 ); | ||
QCOMPARE( graph.edge( 0 ).outVertex(), 1 ); | ||
QCOMPARE( graph.vertex( 0 ).inEdges(), QList< int >() << 0 ); | ||
QCOMPARE( graph.vertex( 0 ).outEdges(), QList< int >() ); | ||
QCOMPARE( graph.vertex( 1 ).inEdges(), QList< int >() ); | ||
QCOMPARE( graph.vertex( 1 ).outEdges(), QList< int >() << 0 ); | ||
|
||
graph.addVertex( QgsPointXY( 7, 8 ) ); | ||
QCOMPARE( graph.vertexCount(), 3 ); | ||
QCOMPARE( graph.vertex( 2 ).point(), QgsPointXY( 7, 8 ) ); | ||
QVERIFY( graph.vertex( 2 ).inEdges().empty() ); | ||
QVERIFY( graph.vertex( 2 ).outEdges().empty() ); | ||
QCOMPARE( graph.edgeCount(), 1 ); | ||
graph.addEdge( 2, 1, QVector< QVariant >() << 8 ); | ||
|
||
QCOMPARE( graph.edge( 1 ).cost( 0 ).toInt(), 8 ); | ||
QCOMPARE( graph.edge( 1 ).inVertex(), 1 ); | ||
QCOMPARE( graph.edge( 1 ).outVertex(), 2 ); | ||
QCOMPARE( graph.vertex( 1 ).inEdges(), QList< int >() << 1 ); | ||
QCOMPARE( graph.vertex( 1 ).outEdges(), QList< int >() << 0 ); | ||
QCOMPARE( graph.vertex( 2 ).inEdges(), QList< int >() ); | ||
QCOMPARE( graph.vertex( 2 ).outEdges(), QList< int >() << 1 ); | ||
} | ||
|
||
std::unique_ptr<QgsVectorLayer> TestQgsNetworkAnalysis::buildNetwork() | ||
{ | ||
std::unique_ptr< QgsVectorLayer > l = qgis::make_unique< QgsVectorLayer >( QStringLiteral( "LineString?crs=epsg:4326" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) ); | ||
|
||
QgsFeature ff( 0 ); | ||
QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(0 0, 10 0, 10 10)" ) ); | ||
ff.setGeometry( refGeom ); | ||
QgsFeatureList flist; | ||
flist << ff; | ||
l->dataProvider()->addFeatures( flist ); | ||
|
||
return l; | ||
} | ||
|
||
|
||
void TestQgsNetworkAnalysis::testBuild() | ||
{ | ||
std::unique_ptr<QgsVectorLayer> network = buildNetwork(); | ||
std::unique_ptr< QgsVectorLayerDirector > director = qgis::make_unique< QgsVectorLayerDirector > ( network.get(), | ||
-1, QString(), QString(), QString(), QgsVectorLayerDirector::DirectionBoth ); | ||
std::unique_ptr< QgsNetworkDistanceStrategy > strategy = qgis::make_unique< QgsNetworkDistanceStrategy >(); | ||
director->addStrategy( strategy.release() ); | ||
std::unique_ptr< QgsGraphBuilder > builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0 ); | ||
|
||
QVector<QgsPointXY > snapped; | ||
director->makeGraph( builder.get(), QVector<QgsPointXY>() << QgsPointXY( 0, 0 ) << QgsPointXY( 10, 10 ), snapped ); | ||
QCOMPARE( snapped, QVector<QgsPointXY>() << QgsPointXY( 0, 0 ) << QgsPointXY( 10, 10 ) ); | ||
std::unique_ptr< QgsGraph > graph( builder->graph() ); | ||
QCOMPARE( graph->vertexCount(), 3 ); | ||
QCOMPARE( graph->edgeCount(), 4 ); | ||
QCOMPARE( graph->vertex( 0 ).point(), QgsPointXY( 0, 0 ) ); | ||
QCOMPARE( graph->vertex( 0 ).inEdges(), QList< int >() << 1 ); | ||
QCOMPARE( graph->edge( 1 ).inVertex(), 0 ); | ||
QCOMPARE( graph->edge( 1 ).outVertex(), 1 ); | ||
QCOMPARE( graph->vertex( 0 ).outEdges(), QList< int >() << 0 ); | ||
QCOMPARE( graph->edge( 0 ).inVertex(), 1 ); | ||
QCOMPARE( graph->edge( 0 ).outVertex(), 0 ); | ||
QCOMPARE( graph->vertex( 1 ).point(), QgsPointXY( 10, 0 ) ); | ||
QCOMPARE( graph->vertex( 1 ).inEdges(), QList< int >() << 0 << 3 ); | ||
QCOMPARE( graph->vertex( 1 ).outEdges(), QList< int >() << 1 << 2 ); | ||
QCOMPARE( graph->edge( 2 ).inVertex(), 2 ); | ||
QCOMPARE( graph->edge( 2 ).outVertex(), 1 ); | ||
QCOMPARE( graph->edge( 3 ).inVertex(), 1 ); | ||
QCOMPARE( graph->edge( 3 ).outVertex(), 2 ); | ||
QCOMPARE( graph->vertex( 2 ).point(), QgsPointXY( 10, 10 ) ); | ||
QCOMPARE( graph->vertex( 2 ).inEdges(), QList< int >() << 2 ); | ||
QCOMPARE( graph->vertex( 2 ).outEdges(), QList< int >() << 3 ); | ||
|
||
builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0 ); | ||
director->makeGraph( builder.get(), QVector<QgsPointXY>() << QgsPointXY( 10, 0 ) << QgsPointXY( 10, 10 ), snapped ); | ||
QCOMPARE( snapped, QVector<QgsPointXY>() << QgsPointXY( 10, 0 ) << QgsPointXY( 10, 10 ) ); | ||
|
||
builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0 ); | ||
director->makeGraph( builder.get(), QVector<QgsPointXY>(), snapped ); | ||
QCOMPARE( snapped, QVector<QgsPointXY>() ); | ||
|
||
builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0 ); | ||
director->makeGraph( builder.get(), QVector<QgsPointXY>() << QgsPointXY( 0.2, 0.1 ) << QgsPointXY( 10.1, 9 ), snapped ); | ||
QCOMPARE( snapped, QVector<QgsPointXY>() << QgsPointXY( 0.2, 0.0 ) << QgsPointXY( 10.0, 9 ) ); | ||
graph.reset( builder->graph() ); | ||
QCOMPARE( graph->vertexCount(), 5 ); | ||
QCOMPARE( graph->edgeCount(), 8 ); | ||
|
||
} | ||
|
||
void TestQgsNetworkAnalysis::testBuildTolerance() | ||
{ | ||
std::unique_ptr<QgsVectorLayer> network = buildNetwork(); | ||
// has already a linestring LineString(0 0, 10 0, 10 10) | ||
|
||
QgsFeature ff( 0 ); | ||
// 0.1 distance gap | ||
QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(10.1 10, 20 10 )" ) ); | ||
ff.setGeometry( refGeom ); | ||
QgsFeatureList flist; | ||
flist << ff; | ||
network->dataProvider()->addFeatures( flist ); | ||
|
||
std::unique_ptr< QgsVectorLayerDirector > director = qgis::make_unique< QgsVectorLayerDirector > ( network.get(), | ||
-1, QString(), QString(), QString(), QgsVectorLayerDirector::DirectionBoth ); | ||
std::unique_ptr< QgsNetworkDistanceStrategy > strategy = qgis::make_unique< QgsNetworkDistanceStrategy >(); | ||
director->addStrategy( strategy.release() ); | ||
std::unique_ptr< QgsGraphBuilder > builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0 ); | ||
|
||
QVector<QgsPointXY > snapped; | ||
director->makeGraph( builder.get(), QVector<QgsPointXY>(), snapped ); | ||
std::unique_ptr< QgsGraph > graph( builder->graph() ); | ||
QCOMPARE( graph->vertexCount(), 5 ); | ||
QCOMPARE( graph->edgeCount(), 6 ); | ||
QCOMPARE( graph->vertex( 0 ).point(), QgsPointXY( 0, 0 ) ); | ||
QCOMPARE( graph->vertex( 0 ).inEdges(), QList< int >() << 1 ); | ||
QCOMPARE( graph->edge( 1 ).inVertex(), 0 ); | ||
QCOMPARE( graph->edge( 1 ).outVertex(), 1 ); | ||
QCOMPARE( graph->vertex( 0 ).outEdges(), QList< int >() << 0 ); | ||
QCOMPARE( graph->edge( 0 ).inVertex(), 1 ); | ||
QCOMPARE( graph->edge( 0 ).outVertex(), 0 ); | ||
QCOMPARE( graph->vertex( 1 ).point(), QgsPointXY( 10, 0 ) ); | ||
QCOMPARE( graph->vertex( 1 ).inEdges(), QList< int >() << 0 << 3 ); | ||
QCOMPARE( graph->vertex( 1 ).outEdges(), QList< int >() << 1 << 2 ); | ||
QCOMPARE( graph->edge( 2 ).inVertex(), 2 ); | ||
QCOMPARE( graph->edge( 2 ).outVertex(), 1 ); | ||
QCOMPARE( graph->edge( 3 ).inVertex(), 1 ); | ||
QCOMPARE( graph->edge( 3 ).outVertex(), 2 ); | ||
QCOMPARE( graph->vertex( 2 ).point(), QgsPointXY( 10, 10 ) ); | ||
QCOMPARE( graph->vertex( 2 ).inEdges(), QList< int >() << 2 ); | ||
QCOMPARE( graph->vertex( 2 ).outEdges(), QList< int >() << 3 ); | ||
QCOMPARE( graph->vertex( 3 ).point(), QgsPointXY( 10.1, 10 ) ); | ||
QCOMPARE( graph->vertex( 3 ).inEdges(), QList< int >() << 5 ); | ||
QCOMPARE( graph->vertex( 3 ).outEdges(), QList< int >() << 4 ); | ||
QCOMPARE( graph->vertex( 4 ).point(), QgsPointXY( 20, 10 ) ); | ||
QCOMPARE( graph->edge( 4 ).inVertex(), 4 ); | ||
QCOMPARE( graph->edge( 4 ).outVertex(), 3 ); | ||
QCOMPARE( graph->edge( 5 ).inVertex(), 3 ); | ||
QCOMPARE( graph->edge( 5 ).outVertex(), 4 ); | ||
|
||
#if 0 // broken | ||
// with tolerance | ||
builder = qgis::make_unique< QgsGraphBuilder > ( network->sourceCrs(), true, 0.11 ); | ||
director->makeGraph( builder.get(), QVector<QgsPointXY>(), snapped ); | ||
graph.reset( builder->graph() ); | ||
QCOMPARE( graph->vertexCount(), 5 ); | ||
QCOMPARE( graph->edgeCount(), 6 ); | ||
QCOMPARE( graph->vertex( 0 ).point(), QgsPointXY( 0, 0 ) ); | ||
QCOMPARE( graph->vertex( 0 ).inEdges(), QList< int >() << 1 ); | ||
QCOMPARE( graph->edge( 1 ).inVertex(), 0 ); | ||
QCOMPARE( graph->edge( 1 ).outVertex(), 1 ); | ||
QCOMPARE( graph->vertex( 0 ).outEdges(), QList< int >() << 0 ); | ||
QCOMPARE( graph->edge( 0 ).inVertex(), 1 ); | ||
QCOMPARE( graph->edge( 0 ).outVertex(), 0 ); | ||
QCOMPARE( graph->vertex( 1 ).point(), QgsPointXY( 10, 0 ) ); | ||
QCOMPARE( graph->vertex( 1 ).inEdges(), QList< int >() << 0 << 3 ); | ||
QCOMPARE( graph->vertex( 1 ).outEdges(), QList< int >() << 1 << 2 ); | ||
QCOMPARE( graph->edge( 2 ).inVertex(), 2 ); | ||
QCOMPARE( graph->edge( 2 ).outVertex(), 1 ); | ||
QCOMPARE( graph->edge( 3 ).inVertex(), 1 ); | ||
QCOMPARE( graph->edge( 3 ).outVertex(), 2 ); | ||
QCOMPARE( graph->vertex( 2 ).point(), QgsPointXY( 10, 10 ) ); | ||
QCOMPARE( graph->vertex( 2 ).inEdges(), QList< int >() << 2 << 5 ); | ||
QCOMPARE( graph->vertex( 2 ).outEdges(), QList< int >() << 3 << 4 ); | ||
QCOMPARE( graph->vertex( 3 ).point(), QgsPointXY( 10.1, 10 ) ); | ||
QCOMPARE( graph->vertex( 3 ).inEdges(), QList< int >() ); | ||
QCOMPARE( graph->vertex( 3 ).outEdges(), QList< int >() ); | ||
QCOMPARE( graph->vertex( 4 ).point(), QgsPointXY( 20, 10 ) ); | ||
QCOMPARE( graph->edge( 4 ).inVertex(), 4 ); | ||
QCOMPARE( graph->edge( 4 ).outVertex(), 2 ); | ||
QCOMPARE( graph->edge( 5 ).inVertex(), 2 ); | ||
QCOMPARE( graph->edge( 5 ).outVertex(), 4 ); | ||
#endif | ||
} | ||
|
||
|
||
|
||
QGSTEST_MAIN( TestQgsNetworkAnalysis ) | ||
#include "testqgsnetworkanalysis.moc" |