Skip to content

Commit

Permalink
roadgraph plugin refactoring. Step 1 of 3.
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@15122 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
stopa85 committed Feb 3, 2011
1 parent 8444f2d commit d3854f6
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 154 deletions.
1 change: 1 addition & 0 deletions src/plugins/roadgraph/CMakeLists.txt
Expand Up @@ -13,6 +13,7 @@ SET (VRP_SRCS
linevectorlayerdirector.cpp
simplegraphbuilder.cpp
exportdlg.cpp
graphbuilder.cpp
)

#SET ([pluginlcasename]_UIS [pluginlcasename]guibase.ui)
Expand Down
35 changes: 35 additions & 0 deletions src/plugins/roadgraph/graphbuilder.cpp
@@ -0,0 +1,35 @@
/***************************************************************************
* Copyright (C) 2010 by Sergey Yakushev *
* yakushevs <at >list.ru *
* *
* *
* 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. *
***************************************************************************/

/**
* \file graphbuilder.cpp
* \brief implementation of RgGraphBuilder
*/

#include "graphbuilder.h"

// Qgis includes

RgGraphBuilder::RgGraphBuilder( const QgsCoordinateReferenceSystem& crs ) :
mCrs( crs )
{

}

RgGraphBuilder::~RgGraphBuilder()
{

}

QgsCoordinateReferenceSystem& RgGraphBuilder::destinationCrs()
{
return mCrs;
}
31 changes: 11 additions & 20 deletions src/plugins/roadgraph/graphbuilder.h
Expand Up @@ -32,19 +32,17 @@
class RgGraphBuilder
{
public:
//! Destructor
virtual ~RgGraphBuilder()
{};
/**
* set source CRS
*/
virtual void setSourceCrs( const QgsCoordinateReferenceSystem& crs ) = 0;
//! Constructor
RgGraphBuilder( const QgsCoordinateReferenceSystem& crs );

//! Destructor
virtual ~RgGraphBuilder();

/**
* set destionation CRS
* get destinaltion Crs
*/
virtual void setDestinationCrs( const QgsCoordinateReferenceSystem& crs ) = 0;

QgsCoordinateReferenceSystem& destinationCrs();
/**
* add vertex
*/
Expand All @@ -53,16 +51,9 @@ class RgGraphBuilder
/**
* add arc
*/
virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed ) = 0;

/**
* tie point
* @param pt maps point
* @param ok ok = false if tiePoint failed.
* @return Graph vertex corresponding pt.
* @note: graph can be modified
*/
virtual QgsPoint tiePoint( const QgsPoint &pt, bool &ok ) = 0;
virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed ) = 0;

private:
QgsCoordinateReferenceSystem mCrs;
};
#endif //GRAPHBUILDER
24 changes: 16 additions & 8 deletions src/plugins/roadgraph/graphdirector.h
Expand Up @@ -21,24 +21,32 @@
#include <qgsrectangle.h>

//forward declarations
class RgSettings;
class RgGraphBuilder;

/**
* \class RgGraphDirector
* \brief Determine making the graph
* contained the settings
*/
/**
* \class RgGraphDirector
* \brief Determine making the graph
*/
class RgGraphDirector
{
public:
//! Destructor
virtual ~RgGraphDirector() { };

/**
* get adjacency matrix
* Make a graph using RgGraphBuilder
*
* @param builder The graph builder
*
* @param additionalPoints Vector of points that must be tied to the graph
*
* @param tiedPoints Vector of tied points
*
* @note if tiedPoints[i]==QgsPoint(0.0,0.0) then tied failed.
*/
virtual void makeGraph( RgGraphBuilder * ) const = 0;
virtual void makeGraph( RgGraphBuilder *builder,
const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint>& tiedPoints ) const = 0;

/**
* return Director name
Expand Down
105 changes: 91 additions & 14 deletions src/plugins/roadgraph/linevectorlayerdirector.cpp
Expand Up @@ -24,12 +24,12 @@
#include <qgsvectordataprovider.h>
#include <qgspoint.h>
#include <qgsgeometry.h>
#include <qgsdistancearea.h>

// QT includes
#include <QString>

//standard includes
#include <iostream>

RgLineVectorLayerDirector::RgLineVectorLayerDirector( const QString& layerId,
int directionFieldId,
Expand Down Expand Up @@ -61,15 +61,64 @@ QString RgLineVectorLayerDirector::name() const
return QString( "Vector line" );
}

void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder, const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint >& tiedPoint ) const
{
QgsVectorLayer *vl = myLayer();

if ( vl == NULL )
return;

QgsCoordinateTransform ct( vl->crs(), builder->destinationCrs() );

QgsDistanceArea da;
da.setSourceCrs( builder->destinationCrs().srsid() );
da.setProjectionsEnabled( true );

builder->setSourceCrs( vl->crs() );
tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint(0.0, 0.0) );
TiePointInfo tmpInfo;
tmpInfo.mLength = infinity();

QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
QVector< TiePointInfo >::iterator pointLengthIt;

// begin: tie points to the graph
QgsAttributeList la;
vl->select( la );
QgsFeature feature;
while ( vl->nextFeature( feature ) )
{
QgsPoint pt1, pt2;
bool isFirstPoint = true;
QgsPolyline pl = feature.geometry()->asPolyline();
QgsPolyline::iterator pointIt;
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
{
pt2 = ct.transform( *pointIt );
if ( !isFirstPoint )
{
int i=0;
for ( i = 0; i != additionalPoints.size(); ++i )
{
TiePointInfo info;
info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), info.mTiedPoint );

if ( pointLengthMap[ i ].mLength > info.mLength )
{
info.mFirstPoint = pt1;
info.mLastPoint = pt2;

pointLengthMap[ i ] = info;
tiedPoint[ i ] = info.mTiedPoint;
}
}
}
pt1 = pt2;
isFirstPoint = false;
}
}
// end: tie points to graph

if ( mDirectionFieldId != -1 )
{
la.push_back( mDirectionFieldId );
Expand All @@ -81,8 +130,8 @@ void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const

SpeedUnit su = SpeedUnit::byName( mSpeedUnitName );

// begin graph construction
vl->select( la );
QgsFeature feature;
while ( vl->nextFeature( feature ) )
{
QgsAttributeMap attr = feature.attributeMap();
Expand Down Expand Up @@ -132,20 +181,48 @@ void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
QgsPolyline::iterator pointIt;
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
{
pt2 = *pointIt;
if ( !isFirstPoint )
pt2 = ct.transform( *pointIt );

std::map< double, QgsPoint > pointsOnArc;
pointsOnArc[ 0.0 ] = pt1;
pointsOnArc[ pt1.sqrDist( pt2 ) ] = pt2;

for( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
{
if ( directionType == 1 ||
directionType == 3 )
{
builder->addArc( pt1, pt2, speed*su.multipler() );
}
if ( directionType == 2 ||
directionType == 3 )
if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
{
builder->addArc( pt2, pt1, speed*su.multipler() );
QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
pointsOnArc[ pt1.sqrDist( tiedPoint ) ] = tiedPoint;
}
}

if ( !isFirstPoint )
{
std::map< double, QgsPoint >::iterator pointsIt;
QgsPoint pt1;
QgsPoint pt2;
bool isFirstPoint = true;
for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
{
pt2 = pointsIt->second;
if ( !isFirstPoint )
{
double cost = da.measureLine( pt1, pt2 );
if ( directionType == 1 ||
directionType == 3 )
{
builder->addArc( pt1, pt2, cost, speed*su.multipler() );
}
if ( directionType == 2 ||
directionType == 3 )
{
builder->addArc( pt2, pt1, cost, speed*su.multipler() );
}
}
pt1 = pt2;
isFirstPoint = false;
}
} // if ( !isFirstPoint )
pt1 = pt2;
isFirstPoint = false;
} // for (it = pl.begin(); it != pl.end(); ++it)
Expand Down
14 changes: 12 additions & 2 deletions src/plugins/roadgraph/linevectorlayerdirector.h
Expand Up @@ -32,6 +32,14 @@ class QgsVectorLayer;
*/
class RgLineVectorLayerDirector : public RgGraphDirector
{
private:
struct TiePointInfo
{
QgsPoint mTiedPoint;
double mLength;
QgsPoint mFirstPoint;
QgsPoint mLastPoint;
};
public:
RgLineVectorLayerDirector( const QString& layerId,
int directionFiledId,
Expand All @@ -48,8 +56,10 @@ class RgLineVectorLayerDirector : public RgGraphDirector
/**
* MANDATORY DIRECTOR PROPERTY DECLARATION
*/
void makeGraph( RgGraphBuilder * ) const;

void makeGraph( RgGraphBuilder *builder,
const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint>& tiedPoints ) const;

QString name() const;

private:
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/roadgraph/roadgraphplugin.cpp
Expand Up @@ -296,9 +296,9 @@ void RoadGraphPlugin::render( QPainter *painter )
if ( graphDirector == NULL )
return;

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

AdjacencyMatrix::iterator it1;
Expand Down
22 changes: 12 additions & 10 deletions src/plugins/roadgraph/shortestpathwidget.cpp
Expand Up @@ -223,31 +223,33 @@ bool RgShortestPathWidget::getPath( AdjacencyMatrix& matrix, QgsPoint& p1, QgsPo
{
if ( mFrontPointLineEdit->text().isNull() || mBackPointLineEdit->text().isNull() )
return false;
RgSimpleGraphBuilder builder;
builder.setDestinationCrs( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() );
RgSimpleGraphBuilder builder( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() );
{
const RgGraphDirector *director = mPlugin->director();
if ( director == NULL )
{
QMessageBox::critical( this, tr( "Plugin isn't configured" ), tr( "Plugin isn't configured!" ) );
return false;
}
director->makeGraph( &builder );

QVector< QgsPoint > points;
QVector< QgsPoint > tiedPoint;

points.push_back( mFrontPoint );
points.push_back( mBackPoint );

director->makeGraph( &builder, points, tiedPoint );
p1 = tiedPoint[ 0 ];
p2 = tiedPoint[ 1 ];
// not need
delete director;
}

bool ok;

p1 = builder.tiePoint( mFrontPoint, ok );
if ( !ok )
if ( p1 == QgsPoint(0.0, 0.0) )
{
QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Start point doesn't tie to the road!" ) );
return false;
}
p2 = builder.tiePoint( mBackPoint, ok );
if ( !ok )
if ( p1 == QgsPoint(0.0, 0.0) )
{
QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Stop point doesn't tie to the road!" ) );
return false;
Expand Down

0 comments on commit d3854f6

Please sign in to comment.