Skip to content

Commit d3854f6

Browse files
author
stopa85
committedFeb 3, 2011
roadgraph plugin refactoring. Step 1 of 3.
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@15122 c8812cc2-4d05-0410-92ff-de0c093fc19c

10 files changed

+192
-154
lines changed
 

‎src/plugins/roadgraph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SET (VRP_SRCS
1313
linevectorlayerdirector.cpp
1414
simplegraphbuilder.cpp
1515
exportdlg.cpp
16+
graphbuilder.cpp
1617
)
1718

1819
#SET ([pluginlcasename]_UIS [pluginlcasename]guibase.ui)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/***************************************************************************
2+
* Copyright (C) 2010 by Sergey Yakushev *
3+
* yakushevs <at >list.ru *
4+
* *
5+
* *
6+
* This program is free software; you can redistribute it and/or modify *
7+
* it under the terms of the GNU General Public License as published by *
8+
* the Free Software Foundation; either version 2 of the License, or *
9+
* (at your option) any later version. *
10+
***************************************************************************/
11+
12+
/**
13+
* \file graphbuilder.cpp
14+
* \brief implementation of RgGraphBuilder
15+
*/
16+
17+
#include "graphbuilder.h"
18+
19+
// Qgis includes
20+
21+
RgGraphBuilder::RgGraphBuilder( const QgsCoordinateReferenceSystem& crs ) :
22+
mCrs( crs )
23+
{
24+
25+
}
26+
27+
RgGraphBuilder::~RgGraphBuilder()
28+
{
29+
30+
}
31+
32+
QgsCoordinateReferenceSystem& RgGraphBuilder::destinationCrs()
33+
{
34+
return mCrs;
35+
}

‎src/plugins/roadgraph/graphbuilder.h

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,17 @@
3232
class RgGraphBuilder
3333
{
3434
public:
35-
//! Destructor
36-
virtual ~RgGraphBuilder()
37-
{};
38-
/**
39-
* set source CRS
40-
*/
41-
virtual void setSourceCrs( const QgsCoordinateReferenceSystem& crs ) = 0;
35+
//! Constructor
36+
RgGraphBuilder( const QgsCoordinateReferenceSystem& crs );
4237

38+
//! Destructor
39+
virtual ~RgGraphBuilder();
40+
4341
/**
44-
* set destionation CRS
42+
* get destinaltion Crs
4543
*/
46-
virtual void setDestinationCrs( const QgsCoordinateReferenceSystem& crs ) = 0;
47-
44+
QgsCoordinateReferenceSystem& destinationCrs();
45+
4846
/**
4947
* add vertex
5048
*/
@@ -53,16 +51,9 @@ class RgGraphBuilder
5351
/**
5452
* add arc
5553
*/
56-
virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed ) = 0;
57-
58-
/**
59-
* tie point
60-
* @param pt maps point
61-
* @param ok ok = false if tiePoint failed.
62-
* @return Graph vertex corresponding pt.
63-
* @note: graph can be modified
64-
*/
65-
virtual QgsPoint tiePoint( const QgsPoint &pt, bool &ok ) = 0;
54+
virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed ) = 0;
6655

56+
private:
57+
QgsCoordinateReferenceSystem mCrs;
6758
};
6859
#endif //GRAPHBUILDER

‎src/plugins/roadgraph/graphdirector.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,32 @@
2121
#include <qgsrectangle.h>
2222

2323
//forward declarations
24-
class RgSettings;
2524
class RgGraphBuilder;
2625

27-
/**
28-
* \class RgGraphDirector
29-
* \brief Determine making the graph
30-
* contained the settings
31-
*/
26+
/**
27+
* \class RgGraphDirector
28+
* \brief Determine making the graph
29+
*/
3230
class RgGraphDirector
3331
{
3432
public:
3533
//! Destructor
3634
virtual ~RgGraphDirector() { };
3735

3836
/**
39-
* get adjacency matrix
37+
* Make a graph using RgGraphBuilder
38+
*
39+
* @param builder The graph builder
40+
*
41+
* @param additionalPoints Vector of points that must be tied to the graph
42+
*
43+
* @param tiedPoints Vector of tied points
44+
*
45+
* @note if tiedPoints[i]==QgsPoint(0.0,0.0) then tied failed.
4046
*/
41-
virtual void makeGraph( RgGraphBuilder * ) const = 0;
47+
virtual void makeGraph( RgGraphBuilder *builder,
48+
const QVector< QgsPoint >& additionalPoints,
49+
QVector< QgsPoint>& tiedPoints ) const = 0;
4250

4351
/**
4452
* return Director name

‎src/plugins/roadgraph/linevectorlayerdirector.cpp

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
#include <qgsvectordataprovider.h>
2525
#include <qgspoint.h>
2626
#include <qgsgeometry.h>
27+
#include <qgsdistancearea.h>
2728

2829
// QT includes
2930
#include <QString>
3031

3132
//standard includes
32-
#include <iostream>
3333

3434
RgLineVectorLayerDirector::RgLineVectorLayerDirector( const QString& layerId,
3535
int directionFieldId,
@@ -61,15 +61,64 @@ QString RgLineVectorLayerDirector::name() const
6161
return QString( "Vector line" );
6262
}
6363

64-
void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
64+
void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder, const QVector< QgsPoint >& additionalPoints,
65+
QVector< QgsPoint >& tiedPoint ) const
6566
{
6667
QgsVectorLayer *vl = myLayer();
6768

6869
if ( vl == NULL )
6970
return;
71+
72+
QgsCoordinateTransform ct( vl->crs(), builder->destinationCrs() );
73+
74+
QgsDistanceArea da;
75+
da.setSourceCrs( builder->destinationCrs().srsid() );
76+
da.setProjectionsEnabled( true );
7077

71-
builder->setSourceCrs( vl->crs() );
78+
tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint(0.0, 0.0) );
79+
TiePointInfo tmpInfo;
80+
tmpInfo.mLength = infinity();
81+
82+
QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
83+
QVector< TiePointInfo >::iterator pointLengthIt;
84+
85+
// begin: tie points to the graph
7286
QgsAttributeList la;
87+
vl->select( la );
88+
QgsFeature feature;
89+
while ( vl->nextFeature( feature ) )
90+
{
91+
QgsPoint pt1, pt2;
92+
bool isFirstPoint = true;
93+
QgsPolyline pl = feature.geometry()->asPolyline();
94+
QgsPolyline::iterator pointIt;
95+
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
96+
{
97+
pt2 = ct.transform( *pointIt );
98+
if ( !isFirstPoint )
99+
{
100+
int i=0;
101+
for ( i = 0; i != additionalPoints.size(); ++i )
102+
{
103+
TiePointInfo info;
104+
info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), info.mTiedPoint );
105+
106+
if ( pointLengthMap[ i ].mLength > info.mLength )
107+
{
108+
info.mFirstPoint = pt1;
109+
info.mLastPoint = pt2;
110+
111+
pointLengthMap[ i ] = info;
112+
tiedPoint[ i ] = info.mTiedPoint;
113+
}
114+
}
115+
}
116+
pt1 = pt2;
117+
isFirstPoint = false;
118+
}
119+
}
120+
// end: tie points to graph
121+
73122
if ( mDirectionFieldId != -1 )
74123
{
75124
la.push_back( mDirectionFieldId );
@@ -81,8 +130,8 @@ void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
81130

82131
SpeedUnit su = SpeedUnit::byName( mSpeedUnitName );
83132

133+
// begin graph construction
84134
vl->select( la );
85-
QgsFeature feature;
86135
while ( vl->nextFeature( feature ) )
87136
{
88137
QgsAttributeMap attr = feature.attributeMap();
@@ -132,20 +181,48 @@ void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
132181
QgsPolyline::iterator pointIt;
133182
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
134183
{
135-
pt2 = *pointIt;
136-
if ( !isFirstPoint )
184+
pt2 = ct.transform( *pointIt );
185+
186+
std::map< double, QgsPoint > pointsOnArc;
187+
pointsOnArc[ 0.0 ] = pt1;
188+
pointsOnArc[ pt1.sqrDist( pt2 ) ] = pt2;
189+
190+
for( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
137191
{
138-
if ( directionType == 1 ||
139-
directionType == 3 )
140-
{
141-
builder->addArc( pt1, pt2, speed*su.multipler() );
142-
}
143-
if ( directionType == 2 ||
144-
directionType == 3 )
192+
if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
145193
{
146-
builder->addArc( pt2, pt1, speed*su.multipler() );
194+
QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
195+
pointsOnArc[ pt1.sqrDist( tiedPoint ) ] = tiedPoint;
147196
}
148197
}
198+
199+
if ( !isFirstPoint )
200+
{
201+
std::map< double, QgsPoint >::iterator pointsIt;
202+
QgsPoint pt1;
203+
QgsPoint pt2;
204+
bool isFirstPoint = true;
205+
for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
206+
{
207+
pt2 = pointsIt->second;
208+
if ( !isFirstPoint )
209+
{
210+
double cost = da.measureLine( pt1, pt2 );
211+
if ( directionType == 1 ||
212+
directionType == 3 )
213+
{
214+
builder->addArc( pt1, pt2, cost, speed*su.multipler() );
215+
}
216+
if ( directionType == 2 ||
217+
directionType == 3 )
218+
{
219+
builder->addArc( pt2, pt1, cost, speed*su.multipler() );
220+
}
221+
}
222+
pt1 = pt2;
223+
isFirstPoint = false;
224+
}
225+
} // if ( !isFirstPoint )
149226
pt1 = pt2;
150227
isFirstPoint = false;
151228
} // for (it = pl.begin(); it != pl.end(); ++it)

‎src/plugins/roadgraph/linevectorlayerdirector.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ class QgsVectorLayer;
3232
*/
3333
class RgLineVectorLayerDirector : public RgGraphDirector
3434
{
35+
private:
36+
struct TiePointInfo
37+
{
38+
QgsPoint mTiedPoint;
39+
double mLength;
40+
QgsPoint mFirstPoint;
41+
QgsPoint mLastPoint;
42+
};
3543
public:
3644
RgLineVectorLayerDirector( const QString& layerId,
3745
int directionFiledId,
@@ -48,8 +56,10 @@ class RgLineVectorLayerDirector : public RgGraphDirector
4856
/**
4957
* MANDATORY DIRECTOR PROPERTY DECLARATION
5058
*/
51-
void makeGraph( RgGraphBuilder * ) const;
52-
59+
void makeGraph( RgGraphBuilder *builder,
60+
const QVector< QgsPoint >& additionalPoints,
61+
QVector< QgsPoint>& tiedPoints ) const;
62+
5363
QString name() const;
5464

5565
private:

‎src/plugins/roadgraph/roadgraphplugin.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,9 @@ void RoadGraphPlugin::render( QPainter *painter )
296296
if ( graphDirector == NULL )
297297
return;
298298

299-
RgSimpleGraphBuilder builder;
300-
builder.setDestinationCrs( mQGisIface->mapCanvas()->mapRenderer()->destinationSrs() );
301-
graphDirector->makeGraph( &builder );
299+
RgSimpleGraphBuilder builder ( mQGisIface->mapCanvas()->mapRenderer()->destinationSrs() );
300+
QVector< QgsPoint > null;
301+
graphDirector->makeGraph( &builder , null, null );
302302
AdjacencyMatrix m = builder.adjacencyMatrix();
303303

304304
AdjacencyMatrix::iterator it1;

‎src/plugins/roadgraph/shortestpathwidget.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,31 +223,33 @@ bool RgShortestPathWidget::getPath( AdjacencyMatrix& matrix, QgsPoint& p1, QgsPo
223223
{
224224
if ( mFrontPointLineEdit->text().isNull() || mBackPointLineEdit->text().isNull() )
225225
return false;
226-
RgSimpleGraphBuilder builder;
227-
builder.setDestinationCrs( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() );
226+
RgSimpleGraphBuilder builder( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() );
228227
{
229228
const RgGraphDirector *director = mPlugin->director();
230229
if ( director == NULL )
231230
{
232231
QMessageBox::critical( this, tr( "Plugin isn't configured" ), tr( "Plugin isn't configured!" ) );
233232
return false;
234233
}
235-
director->makeGraph( &builder );
236-
234+
QVector< QgsPoint > points;
235+
QVector< QgsPoint > tiedPoint;
236+
237+
points.push_back( mFrontPoint );
238+
points.push_back( mBackPoint );
239+
240+
director->makeGraph( &builder, points, tiedPoint );
241+
p1 = tiedPoint[ 0 ];
242+
p2 = tiedPoint[ 1 ];
237243
// not need
238244
delete director;
239245
}
240246

241-
bool ok;
242-
243-
p1 = builder.tiePoint( mFrontPoint, ok );
244-
if ( !ok )
247+
if ( p1 == QgsPoint(0.0, 0.0) )
245248
{
246249
QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Start point doesn't tie to the road!" ) );
247250
return false;
248251
}
249-
p2 = builder.tiePoint( mBackPoint, ok );
250-
if ( !ok )
252+
if ( p1 == QgsPoint(0.0, 0.0) )
251253
{
252254
QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Stop point doesn't tie to the road!" ) );
253255
return false;

‎src/plugins/roadgraph/simplegraphbuilder.cpp

Lines changed: 6 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/***************************************************************************
22
* Copyright (C) 2010 by Sergey Yakushev *
3-
* yakushevs@list.ru *
3+
* yakushevs <at> list.ru *
44
* *
55
* *
66
* This program is free software; you can redistribute it and/or modify *
@@ -18,99 +18,20 @@
1818
#include "utils.h"
1919

2020
// Qgis includes
21-
#include <qgscoordinatetransform.h>
22-
#include <qgsdistancearea.h>
2321

24-
#include <iostream>
25-
26-
RgSimpleGraphBuilder::RgSimpleGraphBuilder()
27-
{
28-
mCoordinateTransform = new QgsCoordinateTransform();
29-
mDistanceArea = new QgsDistanceArea();
30-
mDistanceArea->setProjectionsEnabled( true );
31-
}
32-
33-
RgSimpleGraphBuilder::~RgSimpleGraphBuilder()
34-
{
35-
delete mCoordinateTransform;
36-
delete mDistanceArea;
37-
}
38-
39-
void RgSimpleGraphBuilder::setSourceCrs( const QgsCoordinateReferenceSystem& crs )
40-
{
41-
mCoordinateTransform->setSourceCrs( crs );
42-
}
43-
44-
void RgSimpleGraphBuilder::setDestinationCrs( const QgsCoordinateReferenceSystem& crs )
22+
RgSimpleGraphBuilder::RgSimpleGraphBuilder( const QgsCoordinateReferenceSystem& crs ) :
23+
RgGraphBuilder( crs )
4524
{
46-
mCoordinateTransform->setDestCRS( crs );
47-
mDistanceArea->setSourceCrs( crs.srsid() );
4825
}
4926

5027
void RgSimpleGraphBuilder::addVertex( const QgsPoint& pt )
5128
{
52-
mMatrix[ mCoordinateTransform->transform( pt )];
29+
mMatrix[ pt ];
5330
}
5431

55-
void RgSimpleGraphBuilder::addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed )
32+
void RgSimpleGraphBuilder::addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed )
5633
{
57-
QgsPoint p1 = mCoordinateTransform->transform( pt1 );
58-
QgsPoint p2 = mCoordinateTransform->transform( pt2 );
59-
60-
double distance = mDistanceArea->measureLine( p1, p2 );
61-
double time = distance / speed;
62-
mMatrix[ p1 ][ p2 ] = ArcAttributes( distance, time, 0 );
63-
}
64-
65-
QgsPoint RgSimpleGraphBuilder::tiePoint( const QgsPoint &pt, bool &b )
66-
{
67-
b = false;
68-
AdjacencyMatrix::iterator it1;
69-
AdjacencyMatrixString::iterator it2;
70-
71-
double min = infinity();
72-
QgsPoint minP1, minP2;
73-
QgsPoint center;
74-
for ( it1 = mMatrix.begin(); it1 != mMatrix.end(); ++it1 )
75-
{
76-
for ( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
77-
{
78-
QgsPoint c;
79-
double d = distance( it1->first, it2->first, pt, c );
80-
if ( d < min )
81-
{
82-
minP1 = it1->first;
83-
minP2 = it2->first;
84-
min = d;
85-
center = c;
86-
}
87-
}
88-
}
89-
if ( min >= infinity() )
90-
return center;
91-
92-
double c = mMatrix[ minP1 ][ minP2 ].mCost;
93-
double t = mMatrix[ minP1 ][ minP2 ].mTime;
94-
95-
double newArcLength = mDistanceArea->measureLine( minP1, center );
96-
mMatrix[ minP1 ][ center ] = ArcAttributes( newArcLength, t * newArcLength / c, 0 );
97-
newArcLength = mDistanceArea->measureLine( center, minP2 );
98-
mMatrix[ center ][ minP2 ] = ArcAttributes( newArcLength, t * newArcLength / c, 0 );
99-
100-
if ( mMatrix[ minP2 ].find( minP1 ) != mMatrix[ minP2 ].end() )
101-
{
102-
c = mMatrix[ minP2 ][ minP1 ].mCost;
103-
t = mMatrix[ minP2 ][ minP1 ].mTime;
104-
newArcLength = mDistanceArea->measureLine( center, minP1 );
105-
mMatrix[ center ][ minP1 ] = ArcAttributes( newArcLength, t * newArcLength / c, 0 );
106-
newArcLength = mDistanceArea->measureLine( minP2, center );
107-
mMatrix[ minP2 ][ center ] = ArcAttributes( newArcLength, t * newArcLength / c, 0 );
108-
}
109-
110-
mMatrix[minP1].erase( minP2 );
111-
mMatrix[minP2].erase( minP1 );
112-
b = true;
113-
return center;
34+
mMatrix[ pt1 ][ pt2 ] = ArcAttributes( cost, cost / speed, 0 );
11435
}
11536

11637
AdjacencyMatrix RgSimpleGraphBuilder::adjacencyMatrix()

‎src/plugins/roadgraph/simplegraphbuilder.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,19 @@ class RgSimpleGraphBuilder : public RgGraphBuilder
3737
/**
3838
* default constructor
3939
*/
40-
RgSimpleGraphBuilder();
40+
RgSimpleGraphBuilder( const QgsCoordinateReferenceSystem& crs );
41+
4142
/**
42-
* MANDATORY DIRECTOR PROPERTY DECLARATION
43+
* MANDATORY BUILDER PROPERTY DECLARATION
4344
*/
44-
~RgSimpleGraphBuilder();
45-
void setSourceCrs( const QgsCoordinateReferenceSystem& crs );
46-
void setDestinationCrs( const QgsCoordinateReferenceSystem& crs );
4745
void addVertex( const QgsPoint& pt );
48-
void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed );
49-
QgsPoint tiePoint( const QgsPoint& pt, bool& ok );
50-
46+
void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed );
47+
5148
/**
5249
* return Adjacecncy matrix;
5350
*/
5451
AdjacencyMatrix adjacencyMatrix();
5552
private:
5653
AdjacencyMatrix mMatrix;
57-
58-
QgsDistanceArea* mDistanceArea;
59-
60-
QgsCoordinateTransform* mCoordinateTransform;
6154
};
6255
#endif //SIMPLEGRAPHBUILDER

0 commit comments

Comments
 (0)
Please sign in to comment.