54 changes: 54 additions & 0 deletions python/analysis/network/qgsgraphdirector.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
%ModuleHeaderCode
#include <qgslinevectorlayerdirector.h>
%End

/**
* \ingroup networkanalysis
* \class QgsGraphDirector
* \brief Determine making the graph. QgsGraphBuilder and QgsGraphDirector is a builder patter.
*/
class QgsGraphDirector : QObject
{
%TypeHeaderCode
#include <qgsgraphbuilder.h>
%End

%ConvertToSubClassCode
if ( dynamic_cast< QgsLineVectorLayerDirector* > ( sipCpp ) != NULL )
sipClass = sipClass_QgsLineVectorLayerDirector;
else
sipClass = NULL;
%End


signals:
void buildProgress( int, int ) const;
void buildMessage( QString ) const;

public:
//! Destructor
virtual ~QgsGraphDirector();

/**
* 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( QgsGraphBuilderInterface* builder,
const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint>& tiedPoints /Out/ );

void addProperter( QgsArcProperter* prop /Transfer/ ) ;

/**
* return Director name
*/
virtual QString name() const = 0;
};

41 changes: 41 additions & 0 deletions python/analysis/network/qgslinevectorlayerdirector.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* \ingroup networkanalysis
* \class QgsLineVectorLayerDirector
* \brief Determine making the graph from vector line layer
*/
class QgsLineVectorLayerDirector : QgsGraphDirector
{
%TypeHeaderCode
#include <qgslinevectorlayerdirector.h>
%End

public:
/**
* @param myLayer source vector layer
* @param directionFieldId feield contain road direction value
* @param directDirectionValue value for one-way road
* @param reverseDirectionValue value for reverse one-way road
* @param bothDirectionValue value for road
* @param defaultDirection 1 - direct direction, 2 - reverse direction, 3 - both direction
*/
QgsLineVectorLayerDirector( QgsVectorLayer* myLayer,
int directionFieldId,
const QString& directDirectionValue,
const QString& reverseDirectionValue,
const QString& bothDirectionValue,
int defaultDirection
);

//! Destructor
virtual ~QgsLineVectorLayerDirector();

/*
* MANDATORY DIRECTOR PROPERTY DECLARATION
*/
void makeGraph( QgsGraphBuilderInterface *builder,
const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint>& tiedPoints /Out/ ) const;

QString name() const;
};

2 changes: 1 addition & 1 deletion src/analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

SUBDIRS( network )

#############################################################
# sources
Expand Down
67 changes: 67 additions & 0 deletions src/analysis/network/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@


#############################################################
# sources

SET(QGIS_NETWORK_ANALYSIS_SRCS
qgsgraph.cpp
qgsgraphbuilder.cpp
qgsdistancearcproperter.cpp
qgslinevectorlayerdirector.cpp
qgsgraphanalyzer.cpp
)

INCLUDE_DIRECTORIES(BEFORE raster)

SET(QGIS_NETWORK_ANALYSIS_MOC_HDRS
qgsgraphdirector.h
)

QT4_WRAP_CPP(QGIS_NETWORK_ANALYSIS_MOC_SRCS ${QGIS_NETWORK_ANALYSIS_MOC_HDRS})


INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}../../core/
${CMAKE_CURRENT_SOURCE_DIR}../../core/spatialindex
${PROJ_INCLUDE_DIR}
${GEOS_INCLUDE_DIR}
${GDAL_INCLUDE_DIR}
)


#############################################################
# qgis_analysis library

ADD_LIBRARY(qgis_networkanalysis SHARED ${QGIS_NETWORK_ANALYSIS_SRCS} ${QGIS_NETWORK_ANALYSIS_MOC_SRCS} )

ADD_DEPENDENCIES(qgis_networkanalysis qgis_core)

SET_TARGET_PROPERTIES(qgis_networkanalysis PROPERTIES VERSION ${COMPLETE_VERSION} SOVERSION ${COMPLETE_VERSION})

TARGET_LINK_LIBRARIES(qgis_networkanalysis
qgis_core
)

IF (APPLE)
SET_TARGET_PROPERTIES(qgis_networkanalysis PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE )
ENDIF (APPLE)

INSTALL(TARGETS qgis_networkanalysis
RUNTIME DESTINATION ${QGIS_BIN_DIR}
LIBRARY DESTINATION ${QGIS_LIB_DIR}
ARCHIVE DESTINATION ${QGIS_LIB_DIR})


SET(QGIS_NETWORK_ANALYSIS_HDRS
qgsgraph.h
qgsgraphbuilderintr.h
qgsgraphbuilder.h
qgsarcproperter.h
qgsdistancearcproperter.h
qgsgraphdirector.h
qgslinevectorlayerdirector.h
qgsgraphanalyzer.h )

INSTALL(CODE "MESSAGE(\"Installing NETWORK ANALYSIS headers...\")")
INSTALL(FILES ${QGIS_NETWORK_ANALYSIS_HDRS} ${QGIS_NETWORK_ANALYSIS_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
54 changes: 54 additions & 0 deletions src/analysis/network/qgsarcproperter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/***************************************************************************
qgsedgeproperter.h
--------------------------------------
Date : 2011-04-01
Copyright : (C) 2010 by Yakushev Sergey
Email : 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. *
* *
***************************************************************************/

#ifndef QGSEDGEPROPERTERH
#define QGSEDGEPROPERTERH

// QT4 includes
#include <QVariant>

// QGIS includes
#include <qgsfeature.h>
#include <qgslabel.h>

/**
* \ingroup networkanalysis
* \class QgsEdgeProperter
* \brief QgsEdgeProperter is a strategy pattern.
* You can use it for customize arc property. For example look at QgsDistanceArcProperter or src/plugins/roadgraph/speedproperter.h
*/
class ANALYSIS_EXPORT QgsArcProperter
{
public:
/**
* default constructor
*/
QgsArcProperter()
{ }

/**
* QgsGraphDirector call this method for fetching attribute from source layer
* \return required attributes list
*/
virtual QgsAttributeList requiredAttributes() const
{ return QgsAttributeList(); }

/**
* calculate and return adge property
*/
virtual QVariant property( double distance, const QgsFeature& f ) const
{ return QVariant(); }
};
#endif //QGSEDGEPROPERTYH
18 changes: 18 additions & 0 deletions src/analysis/network/qgsdistancearcproperter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/***************************************************************************
* Copyright (C) 2011 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. *
***************************************************************************/

//QGIS includes
#include "qgsdistancearcproperter.h"

QVariant QgsDistanceArcProperter::property( double distance, const QgsFeature& f ) const
{
return QVariant( distance );
}
30 changes: 30 additions & 0 deletions src/analysis/network/qgsdistancearcproperter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/***************************************************************************
qgsedgeproperter.h
--------------------------------------
Date : 2011-04-01
Copyright : (C) 2010 by Yakushev Sergey
Email : 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. *
* *
***************************************************************************/

#ifndef QGSEDGEDISTANCEPROPERTERH
#define QGSEDGEDISTANCEPROPERTERH

// QT4 includes
#include <QVariant>

// QGIS includes
#include <qgsarcproperter.h>

class ANALYSIS_EXPORT QgsDistanceArcProperter : public QgsArcProperter
{
public:
virtual QVariant property( double distance, const QgsFeature& ) const;
};
#endif //QGSEDGEDISTANCEPROPERTYH
139 changes: 139 additions & 0 deletions src/analysis/network/qgsgraph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/***************************************************************************
* Copyright (C) 2011 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 qgsgraph.cpp
* \brief implementation QgsGraph, QgsGraphVertex, QgsGraphArc
*/

#include "qgsgraph.h"

QgsGraph::QgsGraph()
{
}


QgsGraph::~QgsGraph()
{

}

int QgsGraph::addVertex( const QgsPoint& pt )
{
mGraphVertexes.append( QgsGraphVertex( pt ) );
return mGraphVertexes.size()-1;
}

int QgsGraph::addArc( int outVertexIdx, int inVertexIdx, const QVector< QVariant >& properties )
{
QgsGraphArc e;

e.mProperties = properties;
e.mOut = outVertexIdx;
e.mIn = inVertexIdx;
mGraphArc.push_back( e );
int edgeIdx = mGraphArc.size()-1;

mGraphVertexes[ outVertexIdx ].mOutArc.push_back( edgeIdx );
mGraphVertexes[ inVertexIdx ].mInArc.push_back( edgeIdx );

return mGraphArc.size()-1;
}

const QgsGraphVertex& QgsGraph::vertex( int idx ) const
{
return mGraphVertexes[ idx ];
}

const QgsGraphArc& QgsGraph::arc( int idx ) const
{
return mGraphArc[ idx ];
}


int QgsGraph::vertexCount() const
{
return mGraphVertexes.size();
}

int QgsGraph::arcCount() const
{
return mGraphArc.size();
}

int QgsGraph::findVertex( const QgsPoint& pt ) const
{
int i = 0;
for ( i = 0; i < mGraphVertexes.size(); ++i )
{
if ( mGraphVertexes[ i ].point() == pt )
{
return i;
}
}
return -1;
}

QgsGraphArc::QgsGraphArc()
{

}

QVariant QgsGraphArc::property(int i) const
{
return mProperties[ i ];
}

QVector< QVariant > QgsGraphArc::properties() const
{
return mProperties;
}

int QgsGraphArc::inVertex() const
{
return mIn;
}

int QgsGraphArc::outVertex() const
{
return mOut;
}

int QgsGraphArc::in() const
{
return mIn;
}

int QgsGraphArc::out() const
{
return mOut;
}

QgsGraphVertex::QgsGraphVertex( const QgsPoint& point )
: mCoordinate( point )
{

}

QgsGraphArcIdList QgsGraphVertex::outArc() const
{
return mOutArc;
}

QgsGraphArcIdList QgsGraphVertex::inArc() const
{
return mInArc;
}

QgsPoint QgsGraphVertex::point() const
{
return mCoordinate;
}
180 changes: 180 additions & 0 deletions src/analysis/network/qgsgraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/***************************************************************************
graph.h
--------------------------------------
Date : 2011-04-01
Copyright : (C) 2010 by Yakushev Sergey
Email : 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 qgsgraph.h
* Этот файл описывает встроенные в QGIS классы описывающие математический граф. Вершина графа идентифицируется своими географическими координатами, никакие дополнительные свойства ей не могут быть присвоены. Количество свойств графа определяется разработчиком и не ограничено, например длина и время движения по дуге. Граф может быть направленным, иметь инцедентные ребра и петли.
*
*/

#ifndef QGSGRAPHH
#define QGSGRAPHH

// QT4 includes
#include <QList>
#include <QVector>
#include <QVariant>

// QGIS includes
#include "qgspoint.h"

class QgsGraphVertex;

/**
* \ingroup networkanalysis
* \class QgsGraphEdge
* \brief This class implement a graph edge
*/
class ANALYSIS_EXPORT QgsGraphArc
{
public:
QgsGraphArc();

/**
* return property value
* @param propertyIndex property index
*/
QVariant property( int propertyIndex ) const;

/**
* get array of proertyes
*/
QVector< QVariant > properties() const;

/**
* return index of outgoing vertex
*/
int out() const;
int outVertex() const;

/**
* return index of incoming vertex
*/
int in() const;
int inVertex() const;

private:

QVector< QVariant > mProperties;

int mOut;
int mIn;

friend class QgsGraph;
};


typedef QList< int > QgsGraphArcIdList;

/**
* \ingroup networkanalysis
* \class QgsGraphVertex
* \brief This class implement a graph vertex
*/
class ANALYSIS_EXPORT QgsGraphVertex
{
public:
/**
* default constructor. It need for QT's container, e.g. QVector
*/
QgsGraphVertex() {}

/**
* This constructor initializes QgsGraphVertex object and associates a vertex with a point
*/

QgsGraphVertex( const QgsPoint& point );

/**
* return outgoing edges
*/
QgsGraphArcIdList outArc() const;

/**
* return incoming edges
*/
QgsGraphArcIdList inArc() const;

/**
* return vertex point
*/
QgsPoint point() const;

private:
QgsPoint mCoordinate;
QgsGraphArcIdList mOutArc;
QgsGraphArcIdList mInArc;

friend class QgsGraph;
};

/**
* \ingroup networkanalysis
* \class QgsGraph
* \brief Mathematics graph representation
*/

class ANALYSIS_EXPORT QgsGraph
{
public:
QgsGraph();

~QgsGraph();

// begin graph constructing methods
/**
* add vertex to a grap
*/
int addVertex( const QgsPoint& pt );

/**
* add edge to a graph
*/
int addArc( int outVertexIdx, int inVertexIdx, const QVector< QVariant >& properties );

/**
* retrun vertex count
*/
int vertexCount() const;

/**
* return vertex at index
*/
const QgsGraphVertex& vertex( int idx ) const;

/**
* retrun edge count
*/
int arcCount() const;

/**
* retrun edge at index
*/
const QgsGraphArc& arc( int idx ) const;

/**
* find vertex by point
* \return vertex index
*/
int findVertex( const QgsPoint& pt ) const;

private:
QVector<QgsGraphVertex> mGraphVertexes;

QVector<QgsGraphArc> mGraphArc;
};

#endif //QGSGRAPHH
114 changes: 114 additions & 0 deletions src/analysis/network/qgsgraphanalyzer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/***************************************************************************
qgsgraphanlyzer.cpp - QGIS Tools for graph analysis
-------------------
begin : 14 april 2011
copyright : (C) Sergey Yakushev
email : Yakushevs@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. *
* *
***************************************************************************/
// C++ standart includes
#include <limits>

// QT includes
#include <QMap>
#include <QVector>
#include <QPair>

//QGIS-uncludes
#include "qgsgraph.h"
#include "qgsgraphanalyzer.h"

void QgsGraphAnalyzer::shortestpath( const QgsGraph* source, int startPointIdx, int criterionNum, const QVector<int>& destPointCost, QVector<double>& cost, QgsGraph* treeResult )
{

// QMap< cost, vertexIdx > not_begin
// I use it and not create any struct or class.
QMap< double, int > not_begin;
QMap< double, int >::iterator it;

// QVector< QPair< cost, arc id > result
QVector< QPair< double, int > > result;

result.reserve( source->vertexCount() );
int i;
for ( i=0; i < source->vertexCount(); ++i )
{
result.push_back( QPair<double, int> ( std::numeric_limits<double>::infinity() , i ) );
}
result[ startPointIdx ] = QPair<double, int> ( 0.0, -1 );

not_begin.insert( 0.0, startPointIdx );

// begin Dijkstra algorithm
while ( !not_begin.empty() )
{
it = not_begin.begin();
double curCost = it.key();
int curVertex = it.value();
not_begin.erase( it );

// edge index list
QgsGraphArcIdList l = source->vertex( curVertex ).outArc();
QgsGraphArcIdList::iterator arcIt;
for ( arcIt = l.begin(); arcIt != l.end(); ++arcIt )
{
const QgsGraphArc& arc = source->arc( *arcIt );
double cost = arc.property( criterionNum ).toDouble() + curCost;

if ( cost < result[ arc.in() ].first )
{
result[ arc.in() ] = QPair< double, int >( cost, *arcIt );
not_begin.insert( cost, arc.in() );
}
}
}

// fill shortestpath tree
if ( treeResult != NULL )
{
// sourceVertexIdx2resultVertexIdx
QVector<int> source2result( result.size(), -1 );

for ( i=0; i < source->vertexCount(); ++i )
{
if ( result[ i ].first < std::numeric_limits<double>::infinity() )
{
source2result[ i ] = treeResult->addVertex( source->vertex(i).point() );
}
}
for ( i=0; i < source->vertexCount(); ++i )
{
if ( result[ i ].first < std::numeric_limits<double>::infinity() && result[i].second != -1)
{
const QgsGraphArc& arc = source->arc( result[i].second );

treeResult->addArc( source2result[ arc.out() ], source2result[ i ],
arc.properties() );
}
}
}

// fill shortestpath's costs
for ( i=0; i < destPointCost.size(); ++i )
{
cost[i] = result[ destPointCost[i] ].first;
}
}

QgsGraph* QgsGraphAnalyzer::shortestTree( const QgsGraph* source, int startVertexIdx, int criterionNum)
{
QgsGraph *g = new QgsGraph;
QVector<int> v;
QVector<double> vv;
QgsGraphAnalyzer::shortestpath( source, startVertexIdx, criterionNum, v, vv, g );

return g;
}
53 changes: 53 additions & 0 deletions src/analysis/network/qgsgraphanalyzer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/***************************************************************************
qgsgraphalyzer.h - QGIS Tools for graph analysis
-------------------
begin : 14 april 2010
copyright : (C) Sergey Yakushev
email : yakushevs@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. *
* *
***************************************************************************/

#ifndef QGSGRAPHANALYZERH
#define QGSGRAPHANALYZERH

//QT-includes
#include <QVector>

// forward-declaration
class QgsGraph;

/** \ingroup networkanalysis
* The QGis class provides graph analysis functions
*/

class ANALYSIS_EXPORT QgsGraphAnalyzer
{
public:
/**
* solve shortest path problem using dijkstra algorithm
* @param source The source graph
* @param startVertexIdx index of start vertex
* @param criterionNum index of edge property as optimization criterion
* @param destPointCost array of vertex indexes. Function calculating shortest path costs for vertices with these indexes
* @param cost array of cost paths
* @param treeResult return shortest path tree
*/
static void shortestpath( const QgsGraph* source, int startVertexIdx, int criterionNum, const QVector<int>& destPointCost, QVector<double>& cost, QgsGraph* treeResult );

/**
* return shortest path tree with root-node in startVertexIdx
* @param source The source graph
* @param startVertexIdx index of start vertex
* @param criterionNum index of edge property as optimization criterion
*/
static QgsGraph* shortestTree( const QgsGraph* source, int startVertexIdx, int criterionNum );
};
#endif //QGSGRAPHANALYZERH
51 changes: 51 additions & 0 deletions src/analysis/network/qgsgraphbuilder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/***************************************************************************
* 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 qgsgraphbuilder.cpp
* \brief implementation of QgsGraphBuilder
*/

#include "qgsgraphbuilder.h"
#include "qgsgraph.h"

// Qgis includes
#include <qgsfeature.h>
#include <qgsgeometry.h>

QgsGraphBuilder::QgsGraphBuilder( const QgsCoordinateReferenceSystem& crs, bool otfEnabled, double topologyTolerance, const QString& ellipsoidID ) :
QgsGraphBuilderInterface( crs, otfEnabled, topologyTolerance, ellipsoidID )
{
mGraph = new QgsGraph();
}

QgsGraphBuilder::~QgsGraphBuilder()
{
if ( mGraph != NULL )
delete mGraph;
}

void QgsGraphBuilder::addVertex( int, const QgsPoint& pt )
{
mGraph->addVertex( pt );
}

void QgsGraphBuilder::addArc( int pt1id, const QgsPoint&, int pt2id, const QgsPoint&, const QVector< QVariant >& prop )
{
mGraph->addArc( pt1id, pt2id, prop );
}

QgsGraph* QgsGraphBuilder::graph()
{
QgsGraph* res = mGraph;
mGraph = NULL;
return res;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
simplegraphbuilder.h
qgsgraphbuilder.h
--------------------------------------
Date : 2010-10-25
Copyright : (C) 2010 by Yakushev Sergey
Expand All @@ -12,11 +12,10 @@
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef ROADGRAPH_SIMPLEGRAPHBUILDER
#define ROADGRAPH_SIMPLEGRAPHBUILDER
#ifndef QGSGRAPHBUILDERH
#define QGSGRAPHBUILDERH

#include "graphbuilder.h"
#include "utils.h"
#include "qgsgraphbuilderintr.h"

//QT4 includes

Expand All @@ -26,35 +25,38 @@
//forward declarations
class QgsDistanceArea;
class QgsCoordinateTransform;
class QgsGraph;

/**
* \class RgSimpleGraphBuilder
* \brief This class making the simple graph
* \ingroup networkanalysis
* \class QgsGraphBuilder
* \brief This class making the QgsGraph object
*/

class RgSimpleGraphBuilder : public RgGraphBuilder
class ANALYSIS_EXPORT QgsGraphBuilder : public QgsGraphBuilderInterface
{
public:
/**
* default constructor
*/
RgSimpleGraphBuilder( const QgsCoordinateReferenceSystem& crs, bool ctfEnabled, double topologyTolerance = 0.0 );
QgsGraphBuilder( const QgsCoordinateReferenceSystem& crs, bool otfEnabled = true, double topologyTolerance = 0.0, const QString& ellipsoidID = "WGS84" );

~QgsGraphBuilder();

/**
/*
* MANDATORY BUILDER PROPERTY DECLARATION
*/
QgsPoint addVertex( const QgsPoint& pt );
void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed, QgsFeatureId featureId );
virtual void addVertex( int id, const QgsPoint& pt );

virtual void addArc( int pt1id, const QgsPoint& pt1, int pt2id, const QgsPoint& pt2, const QVector< QVariant >& prop );

/**
* return Adjacecncy matrix;
* return QgsGraph result;
*/
AdjacencyMatrix adjacencyMatrix();
private:
AdjacencyMatrix mMatrix;

QgsSpatialIndex mPointIndex;
QgsGraph* graph();

private:

QMap< QgsFeatureId, QgsPoint> mPointMap;
QgsGraph *mGraph;
};
#endif //SIMPLEGRAPHBUILDER
#endif //QGSGRAPHBUILDERH
111 changes: 111 additions & 0 deletions src/analysis/network/qgsgraphbuilderintr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/***************************************************************************
qgsgraphbuilder.h
--------------------------------------
Date : 2010-10-22
Copyright : (C) 2010 by Yakushev Sergey
Email : 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. *
* *
***************************************************************************/
#ifndef QGSGRAPHBUILDERINTERFACE
#define QGSGRAPHBUILDERINTERFACE

//QT4 includes
#include <QVector>
#include <QVariant>

//QGIS includes
#include <qgspoint.h>
#include <qgscoordinatereferencesystem.h>
#include <qgsdistancearea.h>

//forward declarations

/**
* \ingroup networkanalysis
* \class QgsGraphBuilderInterface
* \brief Determine interface for creating a graph. Contains the settings of the graph. QgsGraphBuilder and QgsGraphDirector is a Builder pattern
*/
class ANALYSIS_EXPORT QgsGraphBuilderInterface
{
public:
/**
* QgsGraphBuilderInterface constructor
* @param crs Coordinate reference system for new graph vertex
* @param ctfEnabled enable coordinate transform from source graph CRS to CRS graph
* @param topologyTolerance sqrt distance between source point as one graph vertex
* @param ellipsoidID ellipsoid for edge measurement
*/
QgsGraphBuilderInterface( const QgsCoordinateReferenceSystem& crs, bool ctfEnabled = true, double topologyTolerance = 0.0, const QString& ellipsoidID = "WGS84" ) :
mCrs( crs ), mCtfEnabled ( ctfEnabled ), mTopologyTolerance( topologyTolerance )
{
mDa.setSourceCrs( mCrs.srsid() );
mDa.setEllipsoid( ellipsoidID );
mDa.setProjectionsEnabled( ctfEnabled );
}

//! Destructor
virtual ~QgsGraphBuilderInterface()
{ }

//! get destinaltion Crs
QgsCoordinateReferenceSystem& destinationCrs()
{
return mCrs;
}

//! get coordinate transformation enabled
bool coordinateTransformationEnabled()
{
return mCtfEnabled;
}

//! get topology tolerance
double topologyTolerance()
{
return mTopologyTolerance;
}

//! get measurement tool
QgsDistanceArea* distanceArea()
{
return &mDa;
}

/**
* add vertex
* @param id vertex identyficator
* @param pt vertex coordinate
* @note id and pt is a redundant interface. You can use coordinates or id for vertex identyfy
*/
virtual void addVertex( int id, const QgsPoint& pt )
{ }

/**
* add arc
* @param pt1id first vertex identificator
* @param pt1 first vertex coordinate
* @param pt2id second vertex identificator
* @param pt2 second vertex coordinate
* @param properties arc properties
* @note pt1id, pt1 and pt2id, pt2 is a redundant interface. You can use vertex coordinates or their identificators.
*/
virtual void addArc( int pt1id, const QgsPoint& pt1, int pt2id, const QgsPoint& pt2, const QVector< QVariant >& properties )
{ }

private:
QgsCoordinateReferenceSystem mCrs;

QgsDistanceArea mDa;

bool mCtfEnabled;

double mTopologyTolerance;

};
#endif //QGSGRAPHBUILDERINTERFACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
graphdirector.h
qgsgraphdirector.h
--------------------------------------
Date : 2010-10-18
Copyright : (C) 2010 by Yakushev Sergey
Expand All @@ -12,23 +12,27 @@
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef ROADGRAPH_GRAPHDIRECTOR
#define ROADGRAPH_GRAPHDIRECTOR
#ifndef QGSGRAPHDIRECTORH
#define QGSGRAPHDIRECTORH

//QT4 includes
#include <QObject>
#include <QVector>
#include <QList>

//QGIS includes
#include <qgsrectangle.h>
#include <qgspoint.h>
#include "qgsarcproperter.h"

//forward declarations
class RgGraphBuilder;
class QgsGraphBuilderInterface;

/**
* \class RgGraphDirector
* \brief Determine making the graph
* \ingroup networkanalysis
* \class QgsGraphDirector
* \brief Determine making the graph. QgsGraphBuilder and QgsGraphDirector is a builder patter.
*/
class RgGraphDirector : public QObject
class ANALYSIS_EXPORT QgsGraphDirector : public QObject
{
Q_OBJECT

Expand All @@ -38,7 +42,7 @@ class RgGraphDirector : public QObject

public:
//! Destructor
virtual ~RgGraphDirector() { };
virtual ~QgsGraphDirector() { };

/**
* Make a graph using RgGraphBuilder
Expand All @@ -51,13 +55,22 @@ class RgGraphDirector : public QObject
*
* @note if tiedPoints[i]==QgsPoint(0.0,0.0) then tied failed.
*/
virtual void makeGraph( RgGraphBuilder *builder,
virtual void makeGraph( QgsGraphBuilderInterface* builder,
const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint>& tiedPoints ) const = 0;

QVector< QgsPoint>& tiedPoints ) const
{}

void addProperter( QgsArcProperter* prop )
{
mProperterList.push_back( prop );
}

/**
* return Director name
*/
virtual QString name() const = 0;

protected:
QList<QgsArcProperter*> mProperterList;
};
#endif //GRAPHDIRECTOR
#endif //QGSGRAPHDIRECTORH
399 changes: 399 additions & 0 deletions src/analysis/network/qgslinevectorlayerdirector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,399 @@
/***************************************************************************
* 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 qgslinevectorlayerdirector.cpp
* \brief implementation of QgsLineVectorLayerDirector
*/

#include "qgslinevectorlayerdirector.h"
#include "qgsgraphbuilderintr.h"

// Qgis includes
#include <qgsvectorlayer.h>
#include <qgsvectordataprovider.h>
#include <qgspoint.h>
#include <qgsgeometry.h>
#include <qgsdistancearea.h>

// QT includes
#include <QString>
#include <QtAlgorithms>

//standard includes
#include <limits>
#include <algorithm>

class QgsPointCompare
{
public:
QgsPointCompare( double tolerance ) :
mTolerance( tolerance )
{ }

bool operator()( const QgsPoint& p1, const QgsPoint& p2 ) const
{
if ( mTolerance <= 0 )
return p1.x() == p2.x() ? p1.y() < p2.y() : p1.x() < p2.x();

double tx1 = ceil( p1.x()/mTolerance );
double tx2 = ceil( p2.x()/mTolerance );
if ( tx1 == tx2 )
return ceil( p1.y()/mTolerance ) < ceil( p2.y()/mTolerance );
return tx1 < tx2;
}

private:
double mTolerance;
};

template <typename RandIter, typename Type, typename CompareOp > RandIter my_binary_search( RandIter begin, RandIter end, Type val, CompareOp comp)
{
// result if not found
RandIter not_found = end;

while ( true )
{
RandIter avg = begin + (end-begin)/2;
if ( begin == avg || end == avg )
{
if ( !comp( *begin, val ) && !comp( val, *begin ) )
return begin;
if ( !comp( *end, val ) && !comp( val, *end ) )
return end;

return not_found;
}
if ( comp( val, *avg ) )
end = avg;
else if ( comp( *avg, val ) )
begin = avg;
else
return avg;
}

return not_found;
}

struct TiePointInfo
{
QgsPoint mTiedPoint;
double mLength;
QgsPoint mFirstPoint;
QgsPoint mLastPoint;
};

bool TiePointInfoCompare( const TiePointInfo& a, const TiePointInfo& b )
{
if ( a.mFirstPoint == b.mFirstPoint )
return a.mLastPoint.x() == b.mLastPoint.x() ? a.mLastPoint.y() < b.mLastPoint.y() : a.mLastPoint.x() < b.mLastPoint.x();

return a.mFirstPoint.x() == b.mFirstPoint.x() ? a.mFirstPoint.y() < b.mFirstPoint.y() : a.mFirstPoint.x() < b.mFirstPoint.x();
}

QgsLineVectorLayerDirector::QgsLineVectorLayerDirector( QgsVectorLayer *myLayer,
int directionFieldId,
const QString& directDirectionValue,
const QString& reverseDirectionValue,
const QString& bothDirectionValue,
int defaultDirection
)
{
mVectorLayer = myLayer;
mDirectionFieldId = directionFieldId;
mDirectDirectionValue = directDirectionValue;
mReverseDirectionValue = reverseDirectionValue;
mDefaultDirection = defaultDirection;
mBothDirectionValue = bothDirectionValue;
}

QgsLineVectorLayerDirector::~QgsLineVectorLayerDirector()
{

}

QString QgsLineVectorLayerDirector::name() const
{
return QString( "Vector line" );
}

void QgsLineVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint >& tiedPoint ) const
{
QgsVectorLayer *vl = mVectorLayer;

if ( vl == NULL )
return;

int featureCount = ( int ) vl->featureCount() * 2;
int step = 0;

QgsCoordinateTransform ct;
ct.setSourceCrs( vl->crs() );
if ( builder->coordinateTransformationEnabled() )
{
ct.setDestCRS( builder->destinationCrs() );
}else
{
ct.setDestCRS( vl->crs() );
}

tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint( 0.0, 0.0 ) );

TiePointInfo tmpInfo;
tmpInfo.mLength = std::numeric_limits<double>::infinity();

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

//Graph's points;
QVector< QgsPoint > points;

// begin: tie points to the graph
QgsAttributeList la;
vl->select( la );
QgsFeature feature;
while ( vl->nextFeature( feature ) )
{
QgsMultiPolyline mpl;
if ( feature.geometry()->wkbType() == QGis::WKBMultiLineString )
mpl = feature.geometry()->asMultiPolyline();
else if ( feature.geometry()->wkbType() == QGis::WKBLineString )
mpl.push_back( feature.geometry()->asPolyline() );

QgsMultiPolyline::iterator mplIt;
for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
{
QgsPoint pt1, pt2;
bool isFirstPoint = true;
QgsPolyline::iterator pointIt;
for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
{
pt2 = ct.transform( *pointIt );
points.push_back( pt2 );

if ( !isFirstPoint )
{
int i = 0;
for ( i = 0; i != additionalPoints.size(); ++i )
{
TiePointInfo info;
if ( pt1 == pt2 )
{
info.mLength = additionalPoints[ i ].sqrDist( pt1 );
info.mTiedPoint = pt1;
}else
{
info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(),
pt2.x(), pt2.y(), info.mTiedPoint );
}

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

pointLengthMap[ i ] = info;
tiedPoint[ i ] = info.mTiedPoint;
}
}
}
pt1 = pt2;
isFirstPoint = false;
}
}
emit buildProgress( ++step, featureCount );
}
// end: tie points to graph

// add tied point to graph
int i = 0;
for ( i = 0; i < tiedPoint.size(); ++i )
{
if ( tiedPoint[ i ] != QgsPoint( 0.0, 0.0 ) )
{
points.push_back( tiedPoint [ i ] );
}
}

QgsPointCompare pointCompare( builder->topologyTolerance() );

qSort( points.begin(), points.end(), pointCompare );
QVector< QgsPoint >::iterator tmp = std::unique( points.begin(), points.end() );
points.resize( tmp - points.begin() );


for (i=0;i<points.size();++i)
builder->addVertex( i, points[ i ] );

for ( i = 0; i < tiedPoint.size() ; ++i)
tiedPoint[ i ] = *(my_binary_search( points.begin(), points.end(), tiedPoint[ i ], pointCompare ) );

qSort( pointLengthMap.begin(), pointLengthMap.end(), TiePointInfoCompare );

{ // fill attribute list 'la'
QgsAttributeList tmpAttr;
if ( mDirectionFieldId != -1 )
{
tmpAttr.push_back( mDirectionFieldId );
}

QList< QgsArcProperter* >::const_iterator it;
QgsAttributeList::const_iterator it2;

for ( it = mProperterList.begin(); it != mProperterList.end(); ++it )
{
QgsAttributeList tmp = (*it)->requiredAttributes();
for ( it2 = tmp.begin(); it2 != tmp.end(); ++it2 )
{
tmpAttr.push_back( *it2 );
}
}
qSort( tmpAttr.begin(), tmpAttr.end() );

int lastAttrId = -1;
for ( it2 = tmpAttr.begin(); it2 != tmpAttr.end(); ++it2 )
{
if ( *it2 == lastAttrId )
{
continue;
}

la.push_back( *it2 );

lastAttrId = *it2;
}
} // end fill attribute list 'la'

// begin graph construction
vl->select( la );
while ( vl->nextFeature( feature ) )
{
QgsAttributeMap attr = feature.attributeMap();
int directionType = mDefaultDirection;
QgsAttributeMap::const_iterator it;
// What direction have feature?
for ( it = attr.constBegin(); it != attr.constEnd(); ++it )
{
if ( it.key() != mDirectionFieldId )
{
continue;
}
QString str = it.value().toString();
if ( str == mBothDirectionValue )
{
directionType = 3;
}
else if ( str == mDirectDirectionValue )
{
directionType = 1;
}
else if ( str == mReverseDirectionValue )
{
directionType = 2;
}
}

// begin features segments and add arc to the Graph;
QgsMultiPolyline mpl;
if ( feature.geometry()->wkbType() == QGis::WKBMultiLineString )
mpl = feature.geometry()->asMultiPolyline();
else if ( feature.geometry()->wkbType() == QGis::WKBLineString )
mpl.push_back( feature.geometry()->asPolyline() );

QgsMultiPolyline::iterator mplIt;
for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
{
QgsPoint pt1, pt2;

bool isFirstPoint = true;
QgsPolyline::iterator pointIt;
for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
{
pt2 = ct.transform( *pointIt );

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

TiePointInfo t;
t.mFirstPoint = pt1;
t.mLastPoint = pt2;
pointLengthIt = my_binary_search( pointLengthMap.begin(), pointLengthMap.end(), t, TiePointInfoCompare );

if ( pointLengthIt != pointLengthMap.end() )
{
QVector< TiePointInfo >::iterator it;
for ( it = pointLengthIt; it - pointLengthMap.begin() >= 0; --it )
{
if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 )
{
pointsOnArc[ pt1.sqrDist( it->mTiedPoint ) ] = it->mTiedPoint;
}
}
for ( it = pointLengthIt+1; it != pointLengthMap.end(); ++it )
{
if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 )
{
pointsOnArc[ pt1.sqrDist( it->mTiedPoint ) ] = it->mTiedPoint;
}
}
}

std::map< double, QgsPoint >::iterator pointsIt;
QgsPoint pt1;
QgsPoint pt2;
int pt1idx = -1, pt2idx = -1;
bool isFirstPoint = true;
for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
{
pt2 = pointsIt->second;
tmp = my_binary_search( points.begin(), points.end(), pt2, pointCompare );
pt2 = *tmp;
pt2idx = tmp - points.begin();

if ( !isFirstPoint && pt1 != pt2 )
{
double distance = builder->distanceArea()->measureLine( pt1, pt2 );
QVector< QVariant > prop;
QList< QgsArcProperter* >::const_iterator it;
for ( it = mProperterList.begin(); it != mProperterList.end(); ++it )
{
prop.push_back( (*it)->property( distance, feature ) );
}

if ( directionType == 1 ||
directionType == 3 )
{
builder->addArc( pt1idx, pt1, pt2idx, pt2, prop );
}
if ( directionType == 2 ||
directionType == 3 )
{
builder->addArc( pt2idx, pt2, pt1idx, pt1, prop );
}
}
pt1idx = pt2idx;
pt1 = pt2;
isFirstPoint = false;
}
} // if ( !isFirstPoint )
pt1 = pt2;
isFirstPoint = false;
} // for (it = pl.begin(); it != pl.end(); ++it)
}
emit buildProgress( ++step, featureCount );
} // while( vl->nextFeature(feature) )
} // makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints, QVector< QgsPoint >& tiedPoint )

Original file line number Diff line number Diff line change
Expand Up @@ -12,69 +12,60 @@
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef ROADGRAPH_LINEVECTORLAYERDIRECTOR
#define ROADGRAPH_LINEVECTORLAYERDIRECTOR
#ifndef QGSLINEVECTORLAYERDIRECTORH
#define QGSLINEVECTORLAYERDIRECTORH

//QT4 includes

//QGIS includes

// Road-graph plugin includes
#include "graphdirector.h"
#include "qgsgraphdirector.h"

//forward declarations
class RgGraphBuilder;
class QgsGraphBuilderInterface;
class QgsVectorLayer;

/**
* \class RgLineVectorLayerDirector
* \ingroup networkanalysis
* \class QgsLineVectorLayerDirector
* \brief Determine making the graph from vector line layer
*/
class RgLineVectorLayerDirector : public RgGraphDirector
class QgsLineVectorLayerDirector : public QgsGraphDirector
{
private:
struct TiePointInfo
{
QgsPoint mTiedPoint;
double mLength;
QgsPoint mFirstPoint;
QgsPoint mLastPoint;
};
public:
RgLineVectorLayerDirector( const QString& layerId,
int directionFiledId,
/**
* @param vl source vector layer
* @param directionFieldId feield contain road direction value
* @param directDirectionValue value for one-way road
* @param reverseDirectionValue value for reverse one-way road
* @param bothDirectionValue value for road
* @param defaultDirection 1 - direct direction, 2 - reverse direction, 3 - both direction
*/
QgsLineVectorLayerDirector( QgsVectorLayer* vl,
int directionFieldId,
const QString& directDirectionValue,
const QString& reverseDirectionValue,
const QString& bothDirectionValue,
int defaultDirection,
const QString& speedValueUnit = QString( "m/s" ),
int speedFieldId = -1,
double defaultSpeed = 1.0 );
int defaultDirection
);

//! Destructor
virtual ~RgLineVectorLayerDirector();
/**
virtual ~QgsLineVectorLayerDirector();

/*
* MANDATORY DIRECTOR PROPERTY DECLARATION
*/
void makeGraph( RgGraphBuilder *builder,
void makeGraph( QgsGraphBuilderInterface *builder,
const QVector< QgsPoint >& additionalPoints,
QVector< QgsPoint>& tiedPoints ) const;

QString name() const;

private:

QgsVectorLayer* myLayer() const;

private:

QString mLayerId;

int mSpeedFieldId;

double mDefaultSpeed;

QString mSpeedUnitName;
QgsVectorLayer *mVectorLayer;

int mDirectionFieldId;

Expand All @@ -87,4 +78,5 @@ class RgLineVectorLayerDirector : public RgGraphDirector
//FIXME: need enum
int mDefaultDirection;
};
#endif //GRAPHDIRECTOR

#endif //QGSLINEVECTORLAYERGRAPHDIRECTORH
10 changes: 4 additions & 6 deletions src/plugins/roadgraph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ SET (VRP_SRCS
roadgraphplugin.cpp
settingsdlg.cpp
units.cpp
utils.cpp
shortestpathwidget.cpp
linevectorlayersettings.cpp
linevectorlayerwidget.cpp
linevectorlayerdirector.cpp
simplegraphbuilder.cpp
exportdlg.cpp
graphbuilder.cpp
speedproperter.cpp
)

#SET ([pluginlcasename]_UIS [pluginlcasename]guibase.ui)

SET (VRP_MOC_HDRS
graphdirector.h
roadgraphplugin.h
settingsdlg.h
shortestpathwidget.h
Expand All @@ -32,8 +28,9 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_BINARY_DIR}
${GEOS_INCLUDE_DIR}
../../core
../../core/spatialindex/
../../core/spatialindex
../../gui
../../analysis/network
..
)
########################################################
Expand All @@ -49,6 +46,7 @@ ADD_LIBRARY (roadgraphplugin MODULE ${VRP_SRCS} ${VRP_MOC_SRCS} ${VRP_RCC_SRCS})
TARGET_LINK_LIBRARIES(roadgraphplugin
qgis_core
qgis_gui
qgis_networkanalysis
)


Expand Down
45 changes: 0 additions & 45 deletions src/plugins/roadgraph/graphbuilder.cpp

This file was deleted.

73 changes: 0 additions & 73 deletions src/plugins/roadgraph/graphbuilder.h

This file was deleted.

291 changes: 0 additions & 291 deletions src/plugins/roadgraph/linevectorlayerdirector.cpp

This file was deleted.

4 changes: 2 additions & 2 deletions src/plugins/roadgraph/linevectorlayerwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ RgLineVectorLayerSettingsWidget::RgLineVectorLayerSettingsWidget( RgLineVectorLa
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( layer_it.value() );
if ( !vl )
continue;
if ( vl->geometryType() != QGis::Line )
continue;
// if ( vl->geometryType() != QGis::Line )
// continue;
mcbLayers->insertItem( 0, vl->name() );
}

Expand Down
111 changes: 28 additions & 83 deletions src/plugins/roadgraph/roadgraphplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@
#include <qgsvectorlayer.h>
#include <qgsvectordataprovider.h>

#include <qgslinevectorlayerdirector.h>
#include <qgsgraphbuilder.h>
#include <qgsgraph.h>
#include <qgsdistancearcproperter.h>

// Road grap plugin includes
#include "roadgraphplugin.h"
#include "shortestpathwidget.h"
#include "settingsdlg.h"
#include "speedproperter.h"
#include "units.h"

#include "linevectorlayerdirector.h"
#include "linevectorlayersettings.h"
#include "simplegraphbuilder.h"

//
// Qt4 Related Includes
//
Expand All @@ -43,7 +49,6 @@
#include <QLabel>
#include <QLocale>
#include <QToolBar>
#include <QPainter>
#include <QPushButton>
#include <QDockWidget>
#include <QVBoxLayout>
Expand Down Expand Up @@ -96,31 +101,21 @@ void RoadGraphPlugin::initGui()

// Create the action for tool
mQSettingsAction = new QAction( QIcon( ":/roadgraph/road.png" ), tr( "Road graph settings" ), this );
mQShowDirectionAction = new QAction( QIcon( ":/roadgraph/showdirect.png" ), tr( "Show road's direction" ), this );
mInfoAction = new QAction( QIcon( ":/roadgraph/about.png" ), tr( "About" ), this );

// Set the what's this text
mQSettingsAction->setWhatsThis( tr( "Road graph plugin settings" ) );
mQShowDirectionAction->setWhatsThis( tr( "Roads direction viewer" ) );
mInfoAction->setWhatsThis( tr( "About Road graph plugin" ) );

mQShowDirectionAction->setCheckable( true );
mInfoAction->setWhatsThis( tr( "About Road graph plugin" ) );

setGuiElementsToDefault();

// Connect the action to slots
connect( mQSettingsAction, SIGNAL( triggered() ), this, SLOT( property() ) );
connect( mQShowDirectionAction, SIGNAL( triggered() ), this, SLOT( onShowDirection() ) );
connect( mInfoAction, SIGNAL( triggered() ), SLOT( about() ) );

// Add the icons to the toolbar
mQGisIface->addToolBarIcon( mQShowDirectionAction );

mQGisIface->addPluginToMenu( tr( "Road graph" ), mQSettingsAction );
mQGisIface->addPluginToMenu( tr( "Road graph" ), mQShowDirectionAction );
mQGisIface->addPluginToMenu( tr( "Road graph" ), mInfoAction );

connect( mQGisIface->mapCanvas(), SIGNAL( renderComplete( QPainter* ) ), this, SLOT( render( QPainter* ) ) );
connect( mQGisIface, SIGNAL( projectRead() ), this, SLOT( projectRead() ) );
connect( mQGisIface, SIGNAL( newProjectCreated() ), this, SLOT( newProject() ) );
connect( mQGisIface, SIGNAL( projectRead() ), mQShortestPathDock, SLOT( clear() ) );
Expand All @@ -135,18 +130,13 @@ void RoadGraphPlugin::unload()
{
// remove the GUI
mQGisIface->removePluginMenu( tr( "Road graph" ), mQSettingsAction );
mQGisIface->removePluginMenu( tr( "Road graph" ), mQShowDirectionAction );
mQGisIface->removePluginMenu( tr( "Road graph" ), mInfoAction );

mQGisIface->removeToolBarIcon( mQShowDirectionAction );


// disconnect
disconnect( mQGisIface->mapCanvas(), SIGNAL( renderComplete( QPainter* ) ), this, SLOT( render( QPainter* ) ) );
disconnect( mQGisIface->mainWindow(), SIGNAL( projectRead() ), this, SLOT( projectRead() ) );
disconnect( mQGisIface->mainWindow(), SIGNAL( newProject() ), this, SLOT( newProject() ) );

delete mQSettingsAction;
delete mQShowDirectionAction;
delete mQShortestPathDock;
} // RoadGraphPlugin::unload()

Expand Down Expand Up @@ -260,7 +250,7 @@ QgisInterface* RoadGraphPlugin::iface()
return mQGisIface;
}

const RgGraphDirector* RoadGraphPlugin::director() const
const QgsGraphDirector* RoadGraphPlugin::director() const
{
QString layerId;
QgsVectorLayer *layer = NULL;
Expand All @@ -270,79 +260,34 @@ const RgGraphDirector* RoadGraphPlugin::director() const
{
if ( it.value()->name() != mSettings->mLayer )
continue;
layerId = it.key();
layer = dynamic_cast< QgsVectorLayer* >( it.value() );
break;
}
if ( layer == NULL )
return NULL;

QgsVectorDataProvider *provider = dynamic_cast< QgsVectorDataProvider* >( layer->dataProvider() );
if ( provider == NULL )
return NULL;

RgLineVectorLayerDirector * director =
new RgLineVectorLayerDirector( layerId,
if ( layer->geometryType() == QGis::Line )
{
QgsVectorDataProvider *provider = dynamic_cast< QgsVectorDataProvider* >( layer->dataProvider() );
if ( provider == NULL )
return NULL;
SpeedUnit speedUnit = SpeedUnit::byName( mSettings->mSpeedUnitName );

QgsLineVectorLayerDirector * director =
new QgsLineVectorLayerDirector( layer,
provider->fieldNameIndex( mSettings->mDirection ),
mSettings->mFirstPointToLastPointDirectionVal,
mSettings->mLastPointToFirstPointDirectionVal,
mSettings->mBothDirectionVal,
mSettings->mDefaultDirection,
mSettings->mSpeedUnitName,
provider->fieldNameIndex( mSettings->mSpeed ),
mSettings->mDefaultSpeed );

return director;
mSettings->mDefaultDirection
);
director->addProperter( new QgsDistanceArcProperter() );
director->addProperter( new RgSpeedProperter( provider->fieldNameIndex( mSettings->mSpeed ),
mSettings->mDefaultSpeed, speedUnit.multipler() ) );
return director;
}
return NULL;
}
void RoadGraphPlugin::render( QPainter *painter )
{
if ( !mQShowDirectionAction->isChecked() )
return;

const RgGraphDirector *graphDirector = director();

if ( graphDirector == NULL )
return;

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

AdjacencyMatrix::iterator it1;
AdjacencyMatrixString::iterator it2;
for ( it1 = m.begin(); it1 != m.end(); ++it1 )
{
for ( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
{
QgsPoint p1 = mQGisIface->mapCanvas()->getCoordinateTransform()->transform( it1->first );
QgsPoint p2 = mQGisIface->mapCanvas()->getCoordinateTransform()->transform( it2->first );
double x1 = p1.x(),
y1 = p1.y(),
x2 = p2.x(),
y2 = p2.y();

double length = sqrt( pow( x2 - x1, 2.0 ) + pow( y2 - y1, 2.0 ) );
double Cos = ( x2 - x1 ) / length;
double Sin = ( y2 - y1 ) / length;
double centerX = ( x1 + x2 ) / 2;
double centerY = ( y1 + y2 ) / 2;
double r = mArrowSize;

QPointF pt1( centerX - Sin*r, centerY + Cos*r );
QPointF pt2( centerX + Sin*r, centerY - Cos*r );

QVector<QPointF> tmp;
tmp.resize( 3 );
tmp[0] = QPointF( centerX + Cos * r * 2, centerY + Sin * r * 2 );
tmp[1] = pt1;
tmp[2] = pt2;
painter->drawPolygon( tmp );
}
}
delete graphDirector;
}// RoadGraphPlugin::render()
QString RoadGraphPlugin::timeUnitName()
{
return mTimeUnitName;
Expand Down
11 changes: 2 additions & 9 deletions src/plugins/roadgraph/roadgraphplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class QgisInterface;
class QDockWidget;

//forward declarations RoadGraph plugins classes
class RgGraphDirector;
class QgsGraphDirector;
class RgShortestPathWidget;
class RgLineVectorLayerSettings;

Expand Down Expand Up @@ -59,7 +59,7 @@ class RoadGraphPlugin: public QObject, public QgisPlugin
/**
* return pointer to graph director
*/
const RgGraphDirector* director() const;
const QgsGraphDirector* director() const;

/**
* get time unit name
Expand Down Expand Up @@ -131,11 +131,6 @@ class RoadGraphPlugin: public QObject, public QgisPlugin
*/
QAction * mQSettingsAction;

/**
* pointer ot the direction show action
*/
QAction * mQShowDirectionAction;

/**
* pointer ot the about action
*/
Expand Down Expand Up @@ -166,8 +161,6 @@ class RoadGraphPlugin: public QObject, public QgisPlugin
*/
double mTopologyToleranceFactor;

private:
static const int mArrowSize = 5;
};

#endif //ROADGRAPHPLUGIN
102 changes: 57 additions & 45 deletions src/plugins/roadgraph/shortestpathwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@
#include <qgsapplication.h>
#include <qgsvectorlayer.h>

#include <qgsgraphdirector.h>
#include <qgsgraphbuilder.h>
#include <qgsgraph.h>
#include <qgsgraphanalyzer.h>

// roadgraph plugin includes
#include "roadgraphplugin.h"
#include "shortestpathwidget.h"
#include "utils.h"
#include "simplegraphbuilder.h"
#include "graphdirector.h"
#include "exportdlg.h"
#include "units.h"
#include "settings.h"
Expand Down Expand Up @@ -228,21 +230,20 @@ void RgShortestPathWidget::setBackPoint( const QgsPoint& pt )
mrbBackPoint->show();
}

bool RgShortestPathWidget::getPath( AdjacencyMatrix& matrix, QgsPoint& p1, QgsPoint& p2 )
bool RgShortestPathWidget::getPath( QgsGraph* shortestTree, QgsPoint& p1, QgsPoint& p2 )
{
if ( mFrontPointLineEdit->text().isNull() || mBackPointLineEdit->text().isNull() )
{
QMessageBox::critical( this, tr( "Point not selected" ), tr( "First, select start and stop points." ) );
return false;
}

RgSimpleGraphBuilder builder(
mPlugin->iface()->mapCanvas()->mapRenderer()->destinationCrs(),
mPlugin->iface()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled(),
QgsGraphBuilder builder(
mPlugin->iface()->mapCanvas()->mapRenderer()->destinationCrs(),
mPlugin->iface()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled(),
mPlugin->topologyToleranceFactor() );

{
const RgGraphDirector *director = mPlugin->director();
const QgsGraphDirector *director = mPlugin->director();
if ( director == NULL )
{
QMessageBox::critical( this, tr( "Plugin isn't configured" ), tr( "Plugin isn't configured!" ) );
Expand All @@ -256,14 +257,14 @@ bool RgShortestPathWidget::getPath( AdjacencyMatrix& matrix, QgsPoint& p1, QgsPo

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

director->makeGraph( &builder, points, tiedPoint );

p1 = tiedPoint[ 0 ];
p2 = tiedPoint[ 1 ];
// not need
delete director;
}

if ( p1 == QgsPoint( 0.0, 0.0 ) )
{
QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Start point doesn't tie to the road!" ) );
Expand All @@ -274,16 +275,23 @@ bool RgShortestPathWidget::getPath( AdjacencyMatrix& matrix, QgsPoint& p1, QgsPo
QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Stop point doesn't tie to the road!" ) );
return false;
}
AdjacencyMatrix m = builder.adjacencyMatrix();

DijkstraFinder::OptimizationCriterion criterion = DijkstraFinder::byCost;
if ( mCriterionName->currentIndex() == 1 )
criterion = DijkstraFinder::byTime;

DijkstraFinder f( m, criterion );

matrix = f.find( p1, p2 );
if ( matrix.find( p1 ) == matrix.end() )
QgsGraph *graph = builder.graph();

QVector< int > pointIdx(0,0);
QVector< double > pointCost(0,0.0);

int startVertexIdx = graph->findVertex( p1 );

int criterionNum = 0;
if ( mCriterionName->currentIndex() > 0 )
criterionNum = 1;

QgsGraphAnalyzer::shortestpath( graph, startVertexIdx, criterionNum, pointIdx, pointCost, shortestTree );

delete graph;

if ( shortestTree->findVertex( p2 ) == -1 )
{
QMessageBox::critical( this, tr( "Path not found" ), tr( "Path not found" ) );
return false;
Expand All @@ -294,29 +302,39 @@ bool RgShortestPathWidget::getPath( AdjacencyMatrix& matrix, QgsPoint& p1, QgsPo
void RgShortestPathWidget::findingPath()
{
QgsPoint p1, p2;
AdjacencyMatrix path;
if ( !getPath( path, p1, p2 ) )
QgsGraph path;

if ( !getPath( &path, p1, p2) )
return;

mrbPath->reset( false );
double time = 0.0;
double cost = 0.0;

AdjacencyMatrix::iterator it = path.find( p1 );
if ( it == path.end() )
return;
mrbPath->addPoint( it->first );

while ( it != path.end() )

int startVertexIdx = path.findVertex( p1 );
int stopVertexIdx = path.findVertex( p2 );
QList< QgsPoint > p;
while( startVertexIdx != stopVertexIdx )
{
AdjacencyMatrixString::iterator it2 = it->second.begin();
if ( it2 == it->second.end() )
QgsGraphArcIdList l = path.vertex( stopVertexIdx ).inArc();
if ( l.empty() )
break;
mrbPath->addPoint( it2->first );
time += it2->second.mTime;
cost += it2->second.mCost;
it = path.find( it2->first );
const QgsGraphArc& e = path.arc( l.front() );

cost += e.property(0).toDouble();
time += e.property(1).toDouble();

p.push_front( path.vertex( e.in() ).point() );

stopVertexIdx = e.out();
}
p.push_front( p1 );
QList< QgsPoint>::iterator it;
for ( it = p.begin(); it != p.end(); ++it )
{
mrbPath->addPoint( *it );
}

Unit timeUnit = Unit::byName( mPlugin->timeUnitName() );
Unit distanceUnit = Unit::byName( mPlugin->distanceUnitName() );

Expand All @@ -339,12 +357,12 @@ void RgShortestPathWidget::clear()

void RgShortestPathWidget::exportPath()
{
RgExportDlg dlg( this );
/* RgExportDlg dlg( this );
if ( !dlg.exec() )
return;
QgsPoint p1, p2;
AdjacencyMatrix path;
QgsGraph path;
if ( !getPath( path, p1, p2 ) )
return;
Expand All @@ -355,12 +373,6 @@ void RgShortestPathWidget::exportPath()
QgsCoordinateTransform ct( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationCrs(),
vl->crs() );
QVector< QgsPoint > points;
AdjacencyMatrix::iterator it = path.find( p1 );
if ( it == path.end() )
return;
points.append( ct.transform( it->first ) );

while ( it != path.end() )
{
AdjacencyMatrixString::iterator it2 = it->second.begin();
Expand All @@ -377,7 +389,7 @@ void RgShortestPathWidget::exportPath()
vl->updateExtents();
mPlugin->iface()->mapCanvas()->update();

*/
}

void RgShortestPathWidget::helpRequested()
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/roadgraph/shortestpathwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
#ifndef ROADGRAPHPLUGIN_SHORTESTPATHDLG_H
#define ROADGRAPHPLUGIN_SHORTESTPATHDLG_H

#include "utils.h"

// QT includes
#include <QDockWidget>

Expand All @@ -34,6 +32,8 @@ class QgsMapCanvas;

class RoadGraphPlugin;

class QgsGraph;

/**
@author Sergey Yakushev
*/
Expand Down Expand Up @@ -105,7 +105,7 @@ class RgShortestPathWidget : public QDockWidget
/**
* retrun path as a graph
*/
bool getPath( AdjacencyMatrix &m, QgsPoint& p1, QgsPoint& p2 );
bool getPath( QgsGraph *, QgsPoint& p1, QgsPoint& p2 );

/**
* This line edit show front points coordinates
Expand Down
64 changes: 0 additions & 64 deletions src/plugins/roadgraph/simplegraphbuilder.cpp

This file was deleted.

42 changes: 42 additions & 0 deletions src/plugins/roadgraph/speedproperter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/***************************************************************************
* Copyright (C) 2009 by Sergey Yakushev *
* yakushevs@list.ru *
* *
* This is file implements Units classes *
* *
* 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 "speedproperter.h"

RgSpeedProperter::RgSpeedProperter( int attributeId, double defaultValue, double toMetricFactor )
{
mAttributeId = attributeId;
mDefaultValue = defaultValue;
mToMetricFactor = toMetricFactor;
}

QVariant RgSpeedProperter::property( double distance, const QgsFeature& f ) const
{
const QgsAttributeMap& map = f.attributeMap();
QgsAttributeMap::const_iterator it = map.find( mAttributeId );

if ( it == map.end() )
return QVariant( distance/(mDefaultValue*mToMetricFactor) );

double val = distance/(it->toDouble()*mToMetricFactor);
if ( val <= 0.0 )
return QVariant( distance/(mDefaultValue/mToMetricFactor) );

return QVariant( val );
}

QgsAttributeList RgSpeedProperter::requiredAttributes() const
{
QgsAttributeList l;
l.push_back( mAttributeId );
return l;
}
34 changes: 34 additions & 0 deletions src/plugins/roadgraph/speedproperter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/***************************************************************************
* Copyright (C) 2011 by Sergey Yakushev *
* yakushevs@list.ru *
* *
* This is file define vrp plugins time, distance and speed units *
* classes *
* *
* 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. *
***************************************************************************/

#ifndef ROADGRAPH_SPEEDPROPERTER_H
#define ROADGRAPH_SPEEDPROPERTER_H

#include <qgsarcproperter.h>

class RgSpeedProperter : public QgsArcProperter
{
public:
RgSpeedProperter( int attributeId, double defaultValue, double toMetricFactor );

QVariant property( double distance, const QgsFeature& f ) const;

QgsAttributeList requiredAttributes() const;
private:
int mAttributeId;
double mDefaultValue;
double mToMetricFactor;

};

#endif
167 changes: 0 additions & 167 deletions src/plugins/roadgraph/utils.cpp

This file was deleted.

138 changes: 0 additions & 138 deletions src/plugins/roadgraph/utils.h

This file was deleted.