Index: src/plugins/roadgraph/utils.cpp =================================================================== --- src/plugins/roadgraph/utils.cpp (revision 0) +++ src/plugins/roadgraph/utils.cpp (revision 0) @@ -0,0 +1,166 @@ +/*************************************************************************** + * Copyright (C) 2009 by Sergey Yakushev * + * yakushevs list.ru * + * * + * This is a plugin generated from the QGIS plugin template * + * * + * 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 utils.cpp + * \brief implementation of Road-graph plugins utils + */ + +#include "utils.h" + +//qt includes + +// Qgis includes +#include + +// standart includes +#include +#include + +double infinity() +{ + return 1e12; +} + +// return distance between line of two points and center +double distance( const QgsPoint& p1, const QgsPoint& p2, const QgsPoint& p, QgsPoint& center ) +{ + + // first line + double A1,B1,C1; + A1 = p1.y() - p2.y(); + B1 = p2.x() - p1.x(); + C1 = p1.x()*(-A1) + p1.y()*(-B1); + + // second line. First and second line is perpendicular. + double A2,B2,C2; + A2 = B1; + B2 = -A1; + C2 = -p.x()*A2 - p.y()*B2; + + // union point + double x,y,det; + det = A1*B2 - B1*A2; + x = (C2*B1 - B2*C1)/det; + y = (-A1*C2 + C1*A2)/det; + + center = QgsPoint(x,y); + + det = sqrt(A1*A1+B1*B1); + A1 /= det; + B1 /= det; + C1 /= det; + if ( std::min( p1.x(), p2.x() ) <= x && std::max( p1.x(), p2.x() ) >= x && + std::min( p1.y(), p2.y() ) <= y && std::max( p1.y(), p2.y() ) >= y ) + return std::abs( A1*p.x()+B1*p.y()+C1 ); + + return infinity(); +}// RoadGraphPlugin::distance() + + +bool QgsPointCompare::operator()( const QgsPoint& a, const QgsPoint& b ) const +{ + return a.x() == b.x() ? a.y() < b.y() : a.x() < b.x(); +} + +ArcAttributes::ArcAttributes() +{ + mCost = infinity(); + mTime = infinity(); +} +ArcAttributes::ArcAttributes( double cost, double time, int featureId ) : + mCost( cost ), mTime( time ), mFeatureId( featureId ) +{ + +} + + +DijkstraFinder::DijkstraFinder( const AdjacencyMatrix& m, DijkstraFinder::OptimizationCriterion c ): + mAdjacencyMatrix (m), mCriterion(c) +{ +} + +std::map< QgsPoint , DijkstraFinder::DijkstraIterator, QgsPointCompare> DijkstraFinder::find( const QgsPoint& p ) +{ + CompareDijkstraIterator ci( mCriterion ); + std::set< DijkstraIterator, CompareDijkstraIterator > not_begin( ci ); + std::set< DijkstraIterator, CompareDijkstraIterator >::iterator it; + std::map< QgsPoint, DijkstraIterator, QgsPointCompare> res; + if (mAdjacencyMatrix.find( p ) == mAdjacencyMatrix.end() ) + { + return res; + } + + AdjacencyMatrixString::const_iterator arcIt; + AdjacencyMatrixString::const_iterator end = mAdjacencyMatrix.find( p )->second.end(); + + DijkstraIterator f; + f.mCost = 0; + f.mTime = 0; + f.mFrontPoint = p; + f.mBackPoint = p; + res[ p ] = f; + not_begin.insert( f ); + + while ( !not_begin.empty() ) + { + it = not_begin.begin(); + DijkstraIterator i = *it; + not_begin.erase( it ); + + if ( mAdjacencyMatrix.find( i.mBackPoint ) == mAdjacencyMatrix.end() ) + { + continue; + } + end = mAdjacencyMatrix.find( i.mBackPoint )->second.end(); + for (arcIt = mAdjacencyMatrix.find( i.mBackPoint )->second.begin(); arcIt != end; ++arcIt) + { + DijkstraIterator di = i; + di.mCost += arcIt->second.mCost; + di.mTime += arcIt->second.mTime; + + if ( ci(di, res[ arcIt->first ] ) ) + { + di.mFrontPoint = di.mBackPoint; + di.mBackPoint = arcIt->first; + not_begin.insert( di ); + res[ arcIt->first ] = di; + } + } + } + return res; +} // DijkstraFinder::find( const QgsPoint& p ) + +AdjacencyMatrix DijkstraFinder::find( const QgsPoint& frontPoint, const QgsPoint& backPoint ) +{ + std::map< QgsPoint , DijkstraFinder::DijkstraIterator, QgsPointCompare> r = find( frontPoint ); + std::map< QgsPoint , DijkstraFinder::DijkstraIterator, QgsPointCompare>::iterator it; + if ( r.find( backPoint ) == r.end() ) + { + return AdjacencyMatrix(); + } + + AdjacencyMatrix m; + QgsPoint nextPoint = backPoint; + QgsPoint firstPoint = backPoint; + while ( true ) + { + if ( firstPoint != nextPoint ) + m[ nextPoint ][ firstPoint ] = mAdjacencyMatrix.find( nextPoint )->second.find( firstPoint )->second; + + if ( r[ nextPoint ].mFrontPoint == r[ nextPoint ].mBackPoint ) + break; + firstPoint = nextPoint; + nextPoint = r[ nextPoint ].mFrontPoint; + } + return m; +} // DijkstraFinder::find( const QgsPoint& frontPoint, const QgsPoint& backPoint ) Index: src/plugins/roadgraph/shortestpathwidget.h =================================================================== --- src/plugins/roadgraph/shortestpathwidget.h (revision 0) +++ src/plugins/roadgraph/shortestpathwidget.h (revision 0) @@ -0,0 +1,179 @@ +/*************************************************************************** + * Copyright (C) 2009 by Sergey Yakushev * + * yakushevslist.ru * + * * + * This is file define vrp plugins settings * + * * + * 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 ROADGRAPHPLUGIN_SHORTESTPATHDLG_H +#define ROADGRAPHPLUGIN_SHORTESTPATHDLG_H + +#include "utils.h" + +// QT includes +#include + +// Qgis includes +#include + +// standart includes + +// forward declaration + +class QComboBox; +class QLineEdit; +class QPushButton; + +class QgsRubberBand; +class QgsMapToolEmitPoint; +class QgsMapCanvas; + +class RoadGraphPlugin; + +/** +@author Sergey Yakushev +*/ +/** + * \class VrpPluginShortestPathDlg + * \brief This class implement user interface for finding shortest path between two points. + */ +class RgShortestPathWidget : public QDockWidget +{ + Q_OBJECT +public: + /** + * Standart construct + */ + RgShortestPathWidget( QWidget * , RoadGraphPlugin *); + + /** + * destructor + */ + ~RgShortestPathWidget(); + +private slots: + /** + * export path + */ + void exportPath(); + + /** + * update rubberbands where extents changed + */ + void mapCanvasExtentsChanged(); + + /** + * on canvas click mouse button + */ + void setFrontPoint( const QgsPoint& ); + + /** + * on canvas click mouse button + */ + void setBackPoint( const QgsPoint& ); + + /** + * Activate map tool for coordinate capture + */ + void onSelectFrontPoint(); + + /** + * Activate map tool for coordinate capture + */ + void onSelectBackPoint(); + + /** + * finding path + */ + void findingPath(); + + /** + * clear + */ + void clear(); + + /** + * retrun path as a graph + */ + bool getPath(AdjacencyMatrix &m, QgsPoint& p1, QgsPoint& p2); +private: + /** + * This line edit show front points coordinates + */ + QLineEdit *mFrontPointLineEdit; + + /** + * This line edit show back points coordinates + */ + QLineEdit *mBackPointLineEdit; + + /** + * This combobox conteined criterion name + */ + QComboBox *mCriterionName; + + /** + * This line edit show length calculated path + */ + QLineEdit *mPathCostLineEdit; + + /** + * This line edit show time calculated path + */ + QLineEdit *mPathTimeLineEdit; + + /** + * this button called to find shortest path + */ + QPushButton *mCalculate; + + /** + * this button called to clear line edits and clar current path + */ + QPushButton *mClear; + + /** + * this map tool use for select coordinates + */ + QgsMapToolEmitPoint *mFrontPointMapTool; + + /** + * this map tool use for select coordinates + */ + QgsMapToolEmitPoint *mBackPointMapTool; + + /** + * pointer to Plugin + */ + RoadGraphPlugin *mPlugin; + + /** + * Front point + */ + QgsPoint mFrontPoint; + + /** + * Back point + */ + QgsPoint mBackPoint; + + /** + * show front point + */ + QgsRubberBand *mrbFrontPoint; + + /** + * show back point + */ + QgsRubberBand *mrbBackPoint; + + /** + * show shortest path + */ + QgsRubberBand *mrbPath; +}; +#endif Index: src/plugins/roadgraph/graphdirector.h =================================================================== --- src/plugins/roadgraph/graphdirector.h (revision 0) +++ src/plugins/roadgraph/graphdirector.h (revision 0) @@ -0,0 +1,53 @@ +/*************************************************************************** + graphdirector.h + -------------------------------------- + Date : 2010-10-18 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_GRAPHDIRECTOR +#define ROADGRAPH_GRAPHDIRECTOR + +//QT4 includes + +//QGIS includes +#include + +//forward declarations +class RgSettings; +class RgGraphBuilder; + +/** +* \class RgGraphDirector +* \brief Determine making the graph +* contained the settings +*/ +class RgGraphDirector +{ +public: + //! Destructor + virtual ~RgGraphDirector() { }; + + /** + * get adjacency matrix + */ + virtual void makeGraph( RgGraphBuilder * ) const = 0; + + /** + * return pointer to my Settings + */ + virtual RgSettings* settings() = 0; + + /** + * return Director name + */ + virtual QString name() const = 0; +}; +#endif //GRAPHDIRECTOR Index: src/plugins/roadgraph/units.cpp =================================================================== --- src/plugins/roadgraph/units.cpp (revision 0) +++ src/plugins/roadgraph/units.cpp (revision 0) @@ -0,0 +1,93 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ + +/** + * \file units.cpp + * \brief implementation of VRP plugins utils + */ + +#include "units.h" + + +Unit::Unit() +{ + mMultipler = 1.0; +} + +Unit::Unit(const QString& name, double multipler) : + mName(name), mMultipler(multipler) +{ +} + +QString Unit::name() const +{ + return mName; +} + +double Unit::multipler() const +{ + return mMultipler; +} +Unit Unit::byName( const QString& name) +{ + if ( name == "h" ) + return Unit( name, 60*60 ); + else if ( name == "km" ) + return Unit( name, 1000 ); + else if ( name == "s" ) + return Unit( name, 1 ); + else if ( name == "m" ) + return Unit( name, 1 ); + return Unit(); +} + +SpeedUnit::SpeedUnit() : + mTimeUnit("",1), mDistanceUnit("",1) +{ + +} + +SpeedUnit::SpeedUnit( const Unit& distanceUnit, const Unit& timeUnit) : + mTimeUnit( timeUnit ), mDistanceUnit( distanceUnit ) +{ +} + +QString SpeedUnit::name() const +{ + if ( mDistanceUnit.name().isNull() || mTimeUnit.name().isNull() ) + return QString(); + return mDistanceUnit.name() + QString("/") + mTimeUnit.name(); +} + +SpeedUnit SpeedUnit::byName( const QString& name ) +{ + if ( name=="km/h" ) + return SpeedUnit( Unit::byName("km"), Unit::byName("h") ); + else if ( name=="m/s" ) + return SpeedUnit( Unit::byName("m"), Unit::byName("s") ); + return SpeedUnit(); +} + +double SpeedUnit::multipler() const +{ + return mDistanceUnit.multipler()/mTimeUnit.multipler(); +} + +Unit SpeedUnit::timeUnit() const +{ + return mTimeUnit; +} + +Unit SpeedUnit::distanceUnit() const +{ + return mDistanceUnit; +} Index: src/plugins/roadgraph/linevectorlayerdirector.cpp =================================================================== --- src/plugins/roadgraph/linevectorlayerdirector.cpp (revision 0) +++ src/plugins/roadgraph/linevectorlayerdirector.cpp (revision 0) @@ -0,0 +1,153 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sergey Yakushev * + * 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. * + ***************************************************************************/ + +/** + * \file linevectorlayersettins.cpp + * \brief implementation of RgLineVectorLayerDirector + */ + +#include "linevectorlayersettings.h" +#include "linevectorlayerdirector.h" +#include "graphbuilder.h" +#include "units.h" + +// Qgis includes +#include +#include +#include +#include +#include + +// QT includes +#include + +//standard includes +#include + +RgLineVectorLayerDirector::RgLineVectorLayerDirector() +{ +} +RgLineVectorLayerDirector::~RgLineVectorLayerDirector() +{ +} +RgSettings* RgLineVectorLayerDirector::settings() +{ + return &mSettings; +} + +QString RgLineVectorLayerDirector::name() const +{ + return QString( "Vector line" ); +} + +void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const +{ + QgsVectorLayer *vl = NULL; + QMap< QString, QgsMapLayer*> m = QgsMapLayerRegistry::instance()->mapLayers(); + QMap< QString, QgsMapLayer*>::const_iterator it; + for ( it = m.constBegin(); it != m.constEnd(); ++it ) + { + if ( it.value()->name() == mSettings.mLayer ) + { + vl = dynamic_cast( it.value() ); + break; + } + } + if ( vl == NULL ) + return; + + QgsVectorDataProvider *provider = dynamic_cast( vl->dataProvider() ); + if ( provider == NULL ) + return; + + int directionFieldId = provider->fieldNameIndex( mSettings.mDirection ); + int speedFieldId = provider->fieldNameIndex( mSettings.mSpeed ); + + builder->setSourceCrs( vl->crs() ); + QgsAttributeList la; + if ( directionFieldId > -1 ) + la.push_back( directionFieldId ); + if ( speedFieldId > -1 ) + la.push_back( speedFieldId ); + + SpeedUnit su = SpeedUnit::byName( mSettings.mSpeedUnitName ); + + vl->select( la ); + QgsFeature feature; + while ( vl->nextFeature(feature) ) + { + QgsAttributeMap attr = feature.attributeMap(); + RgLineVectorLayerSettings::DirectionType directionType = mSettings.mDefaultDirection; + QgsAttributeMap::const_iterator it; + // What direction have feature? + for ( it = attr.constBegin(); it != attr.constEnd(); ++it ) + { + if ( it.key() != directionFieldId ) + { + continue; + } + QString str = it.value().toString(); + if ( str == mSettings.mBothDirectionVal ) + { + directionType = RgLineVectorLayerSettings::Both; + } + else if ( str == mSettings.mFirstPointToLastPointDirectionVal ) + { + directionType = RgLineVectorLayerSettings::FirstPointToLastPoint; + } + else if ( str == mSettings.mLastPointToFirstPointDirectionVal ) + { + directionType = RgLineVectorLayerSettings::LastPointToFirstPoint; + } + } + // What speed have feature? + double speed = 0.0; + for (it = attr.constBegin(); it != attr.constEnd(); ++it) + { + if ( it.key() != speedFieldId ) + { + continue; + } + speed = it.value().toDouble(); + } + if (speed <= 0.0) + { + speed = mSettings.mDefaultSpeed; + } + + // begin features segments and add arc to the Graph; + QgsPoint pt1, pt2; + + bool isFirstPoint=true; + QgsPolyline pl = feature.geometry()->asPolyline(); + QgsPolyline::iterator pointIt; + for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt ) + { + pt2 = *pointIt; + if ( !isFirstPoint ) + { + if ( directionType == RgLineVectorLayerSettings::FirstPointToLastPoint || + directionType == RgLineVectorLayerSettings::Both ) + { + builder->addArc(pt1, pt2, speed*su.multipler() ); + } + if (directionType == RgLineVectorLayerSettings::LastPointToFirstPoint || + directionType == RgLineVectorLayerSettings::Both ) + { + builder->addArc( pt2, pt1, speed*su.multipler() ); + } + } + pt1 = pt2; + isFirstPoint=false; + } // for (it = pl.begin(); it != pl.end(); ++it) + + } // while( vl->nextFeature(feature) ) +} // makeGraph( RgGraphBuilder *builder, const QgsRectangle& rt ) Index: src/plugins/roadgraph/settings.h =================================================================== --- src/plugins/roadgraph/settings.h (revision 0) +++ src/plugins/roadgraph/settings.h (revision 0) @@ -0,0 +1,59 @@ +/*************************************************************************** + settings.h + -------------------------------------- + Date : 2010-10-18 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_SETTINGS +#define ROADGRAPH_SETTINGS + +//QT4 includes + +//QGIS includes + +//forward declarations +class QWidget; +class QgsProject; + +/** +* \class RgGraphDirector +* \brief Determine making the graph +* contained the settings +*/ +class RgSettings +{ +public: + //! Destructor + virtual ~RgSettings() { }; + + /** + * write settings to the poject file + */ + virtual void write( QgsProject * ) = 0; + /** + * read settings form project file + */ + virtual void read( const QgsProject * ) = 0; + /** + * This function test settings and return true if setting correct + */ + virtual bool test() = 0; + /** + * Make settings widget + * use it for GUI setting + */ + virtual QWidget* getGui( QWidget* parent ) = 0; + /** + * Load settings from widget + */ + virtual void setFromGui( QWidget * ) = 0; +}; +#endif //ROADGRAPH_SETTIGNS Index: src/plugins/roadgraph/utils.h =================================================================== --- src/plugins/roadgraph/utils.h (revision 0) +++ src/plugins/roadgraph/utils.h (revision 0) @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (C) 2009 by Sergey Yakushev * + * yakushevs list.ru * + * * + * This is file define road-graph plugins utils * + * * + * 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 ROADGRAPHPLUGIN_UTILS_H +#define ROADGRAPHPLUGIN_UTILS_H + +// QT includes +#include + +// Qgis includes +#include "qgspoint.h" + +// standart includes +#include +#include + +// forward declaration Qgis-classes + +/** +@author Sergey Yakushev +*/ + +/** + * \function infinity() + * \brief return big const double value + */ +double infinity(); + +/** + * return distance from lenght to point or infinity() value + * in union point + */ +double distance( const QgsPoint& p1, const QgsPoint& p2, const QgsPoint& p, QgsPoint& center ); + +/** + * \class QgsPointCompare + * \brief This class implement operation "<", ">", "==" and etc. for use QgsPoint type in STL containers + * + */ +class QgsPointCompare +{ +public: + bool operator()( const QgsPoint& a, const QgsPoint& b ) const; +}; + +/** + * \class ArcAttributes + * \brief This class contained arcs attributes. + */ +class ArcAttributes +{ +public: + ArcAttributes(); + ArcAttributes( double cost, double time, int mFeatureId ); +public: + double mCost; + double mTime; + int mFeatureId; +}; + +typedef std::map< QgsPoint, ArcAttributes, QgsPointCompare > AdjacencyMatrixString; +typedef std::map< QgsPoint, AdjacencyMatrixString, QgsPointCompare > AdjacencyMatrix; + + +/** + * \class DijkstraFinder + * \brief This class find shortest path via two points using Dijkstra's algorithm + */ +class DijkstraFinder +{ +public: + enum OptimizationCriterion { byTime=1, byCost=2 }; +private: + class DijkstraIterator { + public: + DijkstraIterator() + { + mCost = infinity(); + mTime = infinity(); + } + double mCost; + double mTime; + QgsPoint mBackPoint; + QgsPoint mFrontPoint; + }; + class CompareDijkstraIterator { + public: + CompareDijkstraIterator( OptimizationCriterion criterion = byCost ) : + mCriterion( criterion ) + { } + bool operator()( const DijkstraIterator& a, const DijkstraIterator& b ) const + { + if ( mCriterion == byCost ) + { + return a.mCost < b.mCost; + } + return a.mTime < b.mTime; + } + bool operator==( const CompareDijkstraIterator& a ) const + { + return mCriterion == a.mCriterion; + } + private: + OptimizationCriterion mCriterion; + }; +public: + /** + * constructor. + * m is adjacency matrix of graph, criterion is a citerion of shortest path + */ + DijkstraFinder( const AdjacencyMatrix &m, OptimizationCriterion criterion ); + + /** + * find all shortest path from point frontPoint to all points of graph. + * return tree. + */ + std::map< QgsPoint , DijkstraIterator, QgsPointCompare > find( const QgsPoint& p ); + + /** + * return shortest path form point frontPoint to endPoint + */ + AdjacencyMatrix find( const QgsPoint& frontPoint, const QgsPoint& endPoint ); + +private: + const AdjacencyMatrix& mAdjacencyMatrix; + OptimizationCriterion mCriterion; +}; +#endif Index: src/plugins/roadgraph/units.h =================================================================== --- src/plugins/roadgraph/units.h (revision 0) +++ src/plugins/roadgraph/units.h (revision 0) @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 2010 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_UNITS_H +#define ROADGRAPH_UNITS_H + +//#include +// QT includes +#include + +// Qgis includes + +// forward declaration Qgis-classes + +/** +@author Sergey Yakushev +*/ +/** + * \class Unit + * \brief This class provide interface to access unit name and multipler. + * You can use it for convert units to metric system + */ +class Unit +{ +public: + /** + * default constructor + */ + Unit(); + + /** + * constructor + */ + Unit( const QString& name, double multipler ); + + /** + * return unit name + */ + QString name() const; + + /** + * return unit multipler. You can use multipler to conver unit to metric system + */ + double multipler() const; + + /** + * return unit by name + */ + static Unit byName( const QString& name ); +private: + + /** + * units name + */ + QString mName; + + /** + * units multipler + */ + double mMultipler; +}; + +class SpeedUnit +{ +public: + SpeedUnit(); + SpeedUnit( const Unit& distanceUnit, const Unit& timeUnit ); + + QString name() const; + double multipler() const; + + Unit timeUnit() const; + Unit distanceUnit() const; + + static SpeedUnit byName( const QString& name ); +protected: + Unit mTimeUnit; + Unit mDistanceUnit; +}; +#endif Index: src/plugins/roadgraph/linevectorlayerdirector.h =================================================================== --- src/plugins/roadgraph/linevectorlayerdirector.h (revision 0) +++ src/plugins/roadgraph/linevectorlayerdirector.h (revision 0) @@ -0,0 +1,53 @@ +/*************************************************************************** + linevectorlayerdirector.h + -------------------------------------- + Date : 2010-10-20 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_LINEVECTORLAYERDIRECTOR +#define ROADGRAPH_LINEVECTORLAYERDIRECTOR + +//QT4 includes + +//QGIS includes + +// Road-graph plugin includes +#include "graphdirector.h" +#include "linevectorlayersettings.h" + +//forward declarations +class RgGraphBuilder; + +/** +* \class RgLineVectorLayerDirector +* \brief Determine making the graph from vector line layer +*/ +class RgLineVectorLayerDirector : public RgGraphDirector +{ +public: + RgLineVectorLayerDirector(); + //! Destructor + virtual ~RgLineVectorLayerDirector(); + /** + * MANDATORY DIRECTOR PROPERTY DECLARATION + */ + void makeGraph( RgGraphBuilder * ) const; + + RgSettings* settings(); + + QString name() const; +private: + /** + * settings of this director + */ + RgLineVectorLayerSettings mSettings; +}; +#endif //GRAPHDIRECTOR Index: src/plugins/roadgraph/exportdlg.cpp =================================================================== --- src/plugins/roadgraph/exportdlg.cpp (revision 0) +++ src/plugins/roadgraph/exportdlg.cpp (revision 0) @@ -0,0 +1,112 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sergey Yakushev * + * 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. * + ***************************************************************************/ +#include "exportdlg.h" +#include + +//qt includes +#include +#include +#include +#include +#include +#include + + +// Qgis includes +#include +#include +#include +#include + +//standard includes + +RgExportDlg::RgExportDlg( QWidget* parent, Qt::WFlags fl ) + : QDialog( parent, fl ) +{ + // create base widgets; + setWindowTitle( tr("Export feature") ); + QVBoxLayout *v = new QVBoxLayout( this ); + + QHBoxLayout *h = new QHBoxLayout(); + QLabel *l = new QLabel( tr("Select destination layer:"), this); + h->addWidget(l); + mcbLayers = new QComboBox( this ); + h->addWidget(mcbLayers); + v->addLayout(h); + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + connect(bb, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()) ); + connect(bb, SIGNAL(rejected()), this, SLOT(on_buttonBox_rejected()) ); + v->addWidget(bb); + + //fill list of layers + mcbLayers->insertItem( 0, tr("new temporary layer"), QVariant("-1") ); + + QMap mapLayers = QgsMapLayerRegistry::instance()->mapLayers(); + QMap::iterator layer_it = mapLayers.begin(); + + for ( ; layer_it != mapLayers.end(); ++layer_it ) + { + QgsVectorLayer* vl = dynamic_cast( layer_it.value() ); + if ( !vl ) + continue; + if ( vl->geometryType() != QGis::Line ) + continue; + mcbLayers->insertItem( 0, vl->name(), QVariant( vl->getLayerID() ) ); + } + +} // RgSettingsDlg::RgSettingsDlg() + +RgExportDlg::~RgExportDlg() +{ +} + +QgsVectorLayer* RgExportDlg::mapLayer() const +{ + QgsVectorLayer* myLayer = NULL; + QString layerId = mcbLayers->itemData( mcbLayers->currentIndex() ).toString(); + + if ( layerId == QString("-1") ) + { + // create a temporary layer + myLayer = new QgsVectorLayer( "LineString", "shortest path", "memory" ); + + QgsVectorDataProvider *prov = myLayer->dataProvider(); + if ( prov == NULL) + return NULL; + + QList attrList; + attrList.append( QgsField("one", QVariant::Int) ); + prov->addAttributes( attrList ); + QgsMapLayerRegistry::instance()->addMapLayer( myLayer ); + + }else + { + // retrun selected layer + myLayer = dynamic_cast( QgsMapLayerRegistry::instance()->mapLayer( layerId ) ); + } + + return myLayer; +} // QgsVectorLayer* RgExportDlg::vectorLayer() const + +void RgExportDlg::on_buttonBox_accepted() +{ + accept(); +} // void RgExportDlg::on_buttonBox_accepted() + +void RgExportDlg::on_buttonBox_rejected() +{ + reject(); +} + +void RgExportDlg::on_buttonBox_helpRequested() +{ + QgsContextHelp::run( context_id ); +} Index: src/plugins/roadgraph/roadgraph.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: src/plugins/roadgraph/roadgraph.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: src/plugins/roadgraph/roadgraph.qrc =================================================================== --- src/plugins/roadgraph/roadgraph.qrc (revision 0) +++ src/plugins/roadgraph/roadgraph.qrc (revision 0) @@ -0,0 +1,8 @@ + + + roadgraph.png + showdirect.png + about.png + coordinate_capture.png + + Index: src/plugins/roadgraph/linevectorlayerwidget.cpp =================================================================== --- src/plugins/roadgraph/linevectorlayerwidget.cpp (revision 0) +++ src/plugins/roadgraph/linevectorlayerwidget.cpp (revision 0) @@ -0,0 +1,233 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sergey Yakushev * + * yakushevs@list.ru * + * * + * This is a plugin generated from the QGIS plugin template * + * * + * 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 "linevectorlayerwidget.h" +#include "linevectorlayersettings.h" + +//qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qgis includes +#include "qgsfield.h" +#include "qgsmaplayerregistry.h" +#include "qgsvectordataprovider.h" +#include "qgsvectorlayer.h" + +//standard includes + + +RgLineVectorLayerSettingsWidget::RgLineVectorLayerSettingsWidget( RgLineVectorLayerSettings *s, QWidget* parent ) + : QWidget( parent ) +{ + // create base widgets; + QTabWidget *tab = new QTabWidget(this); + QVBoxLayout *v= new QVBoxLayout(this); + v->addWidget(tab); + + // transportation layer + QFrame *frame = new QFrame(this); + tab->addTab( frame, tr("Transportation layer") ); + v = new QVBoxLayout(frame); + QLabel *l = new QLabel(tr("Layer"), frame); + mcbLayers = new QComboBox(frame); + QHBoxLayout *h = new QHBoxLayout(this); + + h->addWidget(l); + h->addWidget(mcbLayers); + v->addLayout(h); + + h = new QHBoxLayout(); + l = new QLabel( tr("Direction field"), frame ); + mcbDirection = new QComboBox(frame); + h->addWidget(l); + h->addWidget(mcbDirection); + v->addLayout(h); + + h = new QHBoxLayout(); + h->addWidget( new QLabel( tr("Direct direction"), frame) ); + mleFirstPointToLastPointDirection = new QLineEdit( s->mFirstPointToLastPointDirectionVal, frame ); + h->addWidget( mleFirstPointToLastPointDirection ); + v->addLayout(h); + + h = new QHBoxLayout(); + h->addWidget( new QLabel( tr("Reverse direction"), frame) ); + mleLastPointToFirstPointDirection = new QLineEdit( s->mLastPointToFirstPointDirectionVal, frame ); + h->addWidget( mleLastPointToFirstPointDirection ); + v->addLayout(h); + + h = new QHBoxLayout(); + h->addWidget( new QLabel( tr("Both direction"), frame) ); + mleBothDirection = new QLineEdit( s->mBothDirectionVal, frame ); + h->addWidget( mleBothDirection ); + v->addLayout(h); + + h = new QHBoxLayout(); + l = new QLabel( tr("Speed field"), frame ); + mcbSpeed = new QComboBox(frame); + h->addWidget(l); + h->addWidget(mcbSpeed); + v->addLayout(h); + + frame = new QFrame(tab); + tab->addTab( frame, tr("Default settings") ); + v = new QVBoxLayout(frame); + h = new QHBoxLayout(); + l = new QLabel( tr("Direction"), frame ); + mcbDirectionDefault = new QComboBox(frame); + mcbDirectionDefault->insertItem( 0, tr("Both direction") ); + mcbDirectionDefault->insertItem( 1, tr("Direct direction") ); + mcbDirectionDefault->insertItem( 2, tr("Reverse direction") ); + connect( mcbLayers, SIGNAL(currentIndexChanged(int)), this, SLOT(on_mcbLayers_selectItem()) ); + + h->addWidget(l); + h->addWidget(mcbDirectionDefault); + v->addLayout(h); + + h = new QHBoxLayout(frame); + l = new QLabel( tr("Cost"), frame ); + h->addWidget(l); + l = new QLabel( tr("lines length"), frame ); + h->addWidget(l); + v->addLayout(h); + + h = new QHBoxLayout(frame); + l = new QLabel( tr("Speed"), frame ); + msbSpeedDefault = new QSpinBox( frame ); + msbSpeedDefault->setMinimum( 1 ); + msbSpeedDefault->setMaximum( 10000000 ); + h->addWidget( l ); + h->addWidget( msbSpeedDefault ); + v->addLayout( h ); + + frame = new QFrame(tab); + tab->addTab( frame, tr("Units") ); + v = new QVBoxLayout( frame ); + h = new QHBoxLayout(); + l = new QLabel( tr("Unit of speed") ); + mcbUnitOfSpeed = new QComboBox(this); + h->addWidget(l); + h->addWidget( mcbUnitOfSpeed ); + v->addLayout( h ); + + mcbUnitOfSpeed->insertItem( 0, tr("km/h") ); + mcbUnitOfSpeed->insertItem( 0, tr("m/s") ); + if ( s->mSpeedUnitName == "km/h" ) + mcbUnitOfSpeed->setCurrentIndex( 1 ); + else if (s->mSpeedUnitName == "m/s" ) + mcbUnitOfSpeed->setCurrentIndex( 0 ); + + // fill list of layers + QMap mapLayers = QgsMapLayerRegistry::instance()->mapLayers(); + QMap::iterator layer_it = mapLayers.begin(); + + for ( ; layer_it != mapLayers.end(); ++layer_it ) + { + QgsVectorLayer* vl = dynamic_cast( layer_it.value() ); + if ( !vl ) + continue; + if ( vl->geometryType() != QGis::Line ) + continue; + mcbLayers->insertItem( 0, vl->name() ); + } + + //sets current settings + msbSpeedDefault->setValue( static_cast( s->mDefaultSpeed ) ); + + int idx = mcbLayers->findText( s->mLayer ); + if (idx != -1) + { + mcbLayers->setCurrentIndex( idx ); + } + + idx = mcbDirection->findText( s->mDirection ); + if (idx != -1) + mcbDirection->setCurrentIndex( idx ); + + idx = mcbSpeed->findText( s->mSpeed ); + if (idx != -1) + mcbSpeed->setCurrentIndex( idx ); + + + switch( s->mDefaultDirection ) + { + case RgLineVectorLayerSettings::Both: + mcbDirectionDefault->setCurrentIndex(0); + break; + case RgLineVectorLayerSettings::FirstPointToLastPoint: + mcbDirectionDefault->setCurrentIndex(1); + break; + case RgLineVectorLayerSettings::LastPointToFirstPoint: + mcbDirectionDefault->setCurrentIndex(2); + break; + } +} // RgLineVectorLayerSettingsWidget::RgLineVectorLayerSettingsWidget() + +QgsVectorLayer* RgLineVectorLayerSettingsWidget::selectedLayer() +{ + QMap mapLayers = QgsMapLayerRegistry::instance()->mapLayers(); + QMap::iterator layer_it = mapLayers.begin(); + + for ( ; layer_it != mapLayers.end(); ++layer_it ) + { + QgsVectorLayer* vl = dynamic_cast( layer_it.value() ); + if ( !vl ) + continue; + if ( vl->geometryType() != QGis::Line ) + continue; + if ( vl->name() == mcbLayers->currentText() ) + return vl; + } + + return NULL; +} // RgLineVectorLayerSettingsWidget::setlectedLayer() + +void RgLineVectorLayerSettingsWidget::on_mcbLayers_selectItem() +{ + mcbDirection->clear(); + mcbSpeed->clear(); + + mcbDirection->insertItem( 0, tr("Always use default") ); + mcbSpeed->insertItem( 0, tr("Always use default") ); + + QgsVectorLayer* vl = selectedLayer(); + if ( !vl ) + return; + + QgsVectorDataProvider* provider = vl->dataProvider(); + if ( !provider ) + return; + + const QgsFieldMap& fields = provider->fields(); + QgsFieldMap::const_iterator it; + for (it = fields.constBegin(); it != fields.constEnd(); ++it) + { + QgsField currentField = it.value(); + QVariant currentType = currentField.type(); + if ( currentType == QVariant::Int || currentType == QVariant::String ) + { + mcbDirection->insertItem(1, currentField.name()); + } + if ( currentType == QVariant::Int || currentType == QVariant::Double ) + { + mcbSpeed->insertItem(1, currentField.name()); + } + } + +} // RgDSettingsDlg::on_mcbLayers_selectItem() Index: src/plugins/roadgraph/coordinate_capture.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: src/plugins/roadgraph/coordinate_capture.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: src/plugins/roadgraph/about.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: src/plugins/roadgraph/about.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: src/plugins/roadgraph/graphbuilder.h =================================================================== --- src/plugins/roadgraph/graphbuilder.h (revision 0) +++ src/plugins/roadgraph/graphbuilder.h (revision 0) @@ -0,0 +1,69 @@ +/*************************************************************************** + graphbuilder.h + -------------------------------------- + Date : 2010-10-22 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_GRAPHBUILDER +#define ROADGRAPH_GRAPHBUILDER + +#include "utils.h" + +//QT4 includes + +//QGIS includes +#include +#include + +//forward declarations + +/** +* \class RgGraphDirector +* \brief Determine making the graph +* contained the settings +*/ +class RgGraphBuilder +{ +public: + //! Destructor + virtual ~RgGraphBuilder() + {}; + /** + * set source CRS + */ + virtual void setSourceCrs( const QgsCoordinateReferenceSystem& crs ) = 0; + + /** + * set destionation CRS + */ + virtual void setDestinationCrs( const QgsCoordinateReferenceSystem& crs ) = 0; + + /** + * add vertex + */ + virtual void addVertex( const QgsPoint& pt ) = 0; + + /** + * add arc + */ + virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed ) = 0; + + /** + * tie point + * @param pt maps point + * @param pt ok = false if tiePoint failed. + * @return Graph vertex corresponding pt. + * @note: graph can be modified + */ + virtual QgsPoint tiePoint( const QgsPoint &pt, bool &ok ) = 0; + +}; +#endif //GRAPHBUILDER Index: src/plugins/roadgraph/showdirect.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: src/plugins/roadgraph/showdirect.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: src/plugins/roadgraph/exportdlg.h =================================================================== --- src/plugins/roadgraph/exportdlg.h (revision 0) +++ src/plugins/roadgraph/exportdlg.h (revision 0) @@ -0,0 +1,54 @@ +/*************************************************************************** + exportdlg.h + -------------------------------------- + Date : 2010-11-29 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_EXPORTDLG_H +#define ROADGRAPH_EXPORTDLG_H + +#include + +// forward declaration QT-classes +class QComboBox; + +// forward declaration Qgis-classes + +//forward declaration RoadGraph plugins classes +class QgsVectorLayer; + +/** +@author Sergey Yakushev +*/ +/** +* \class RgSettingsDlg +* \brief implement of export dialog +*/ +class RgExportDlg : public QDialog +{ + Q_OBJECT +public: + RgExportDlg( QWidget* parent = 0, Qt::WFlags fl = 0 ); + ~RgExportDlg(); +public: + QgsVectorLayer* mapLayer() const; +private: + static const int context_id = 0; + +private slots: + void on_buttonBox_accepted(); + void on_buttonBox_rejected(); + void on_buttonBox_helpRequested(); + +private: + QComboBox *mcbLayers; +}; +#endif Index: src/plugins/roadgraph/linevectorlayerwidget.h =================================================================== --- src/plugins/roadgraph/linevectorlayerwidget.h (revision 0) +++ src/plugins/roadgraph/linevectorlayerwidget.h (revision 0) @@ -0,0 +1,97 @@ +/*************************************************************************** + roadgraphplugin.h + -------------------------------------- + Date : 2010-10-19 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_LINEVECTORLAYERSETTINGSWIDGET_H +#define ROADGRAPH_LINEVECTORLAYERSETTINGSWIDGET_H + +#include + +class RgLineVectorLayerSettings; + +// forward declaration QT-classes +class QComboBox; +class QLineEdit; +class QSpinBox; +class QLineEdit; + +// forward declaration Qgis-classes +class QgsVectorLayer; + +/** +@author Sergey Yakushev +*/ +/** +* \class RgLineVectorLayerSettingsWidget +* \brief +*/ +class RgLineVectorLayerSettingsWidget : public QWidget +{ + Q_OBJECT +public: + RgLineVectorLayerSettingsWidget( RgLineVectorLayerSettings *s, QWidget* parent = 0 ); + +private slots: + void on_mcbLayers_selectItem(); + +private: + QgsVectorLayer * selectedLayer(); + +public: + /** + * list of passible layers + */ + QComboBox *mcbLayers; + + /** + * list of possible fields for use as direction + */ + QComboBox *mcbDirection; + + /** + * + */ + QLineEdit *mleFirstPointToLastPointDirection; + + /** + * + */ + QLineEdit *mleLastPointToFirstPointDirection; + + /** + * + */ + QLineEdit *mleBothDirection; + + /** + * default direction value + */ + QComboBox *mcbDirectionDefault; + + /** + * list of possible fields for use as speed + */ + QComboBox *mcbSpeed; + + /** + * Default speed value + */ + QSpinBox *msbSpeedDefault; + + /** + * Unit of speed + */ + QComboBox *mcbUnitOfSpeed; +}; +#endif Index: src/plugins/roadgraph/simplegraphbuilder.cpp =================================================================== --- src/plugins/roadgraph/simplegraphbuilder.cpp (revision 0) +++ src/plugins/roadgraph/simplegraphbuilder.cpp (revision 0) @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sergey Yakushev * + * 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. * + ***************************************************************************/ + +/** + * \file simplegraphbuilder.cpp + * \brief implementation of RgSimpleGraphBuilder + */ + +#include "simplegraphbuilder.h" +#include "utils.h" + +// Qgis includes +#include +#include + +#include + +RgSimpleGraphBuilder::RgSimpleGraphBuilder() +{ + mCoordinateTransform = new QgsCoordinateTransform(); + mDistanceArea = new QgsDistanceArea(); + mDistanceArea->setProjectionsEnabled( true ); +} + +RgSimpleGraphBuilder::~RgSimpleGraphBuilder() +{ + delete mCoordinateTransform; + delete mDistanceArea; +} + +void RgSimpleGraphBuilder::setSourceCrs( const QgsCoordinateReferenceSystem& crs ) +{ + mCoordinateTransform->setSourceCrs( crs ); +} + +void RgSimpleGraphBuilder::setDestinationCrs( const QgsCoordinateReferenceSystem& crs ) +{ + mCoordinateTransform->setDestCRS( crs ); + mDistanceArea->setSourceCrs( crs.srsid() ); +} + +void RgSimpleGraphBuilder::addVertex( const QgsPoint& pt ) +{ + mMatrix[ mCoordinateTransform->transform(pt) ]; +} + +void RgSimpleGraphBuilder::addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed ) +{ + QgsPoint p1 = mCoordinateTransform->transform(pt1); + QgsPoint p2 = mCoordinateTransform->transform(pt2); + + double distance = mDistanceArea->measureLine( p1, p2 ); + double time = distance/speed; + mMatrix[ p1 ][ p2 ] = ArcAttributes(distance, time, 0); +} + +QgsPoint RgSimpleGraphBuilder::tiePoint( const QgsPoint &pt, bool &b ) +{ + b = false; + AdjacencyMatrix::iterator it1; + AdjacencyMatrixString::iterator it2; + + double min = infinity(); + QgsPoint minP1, minP2; + QgsPoint center; + for ( it1 = mMatrix.begin(); it1 != mMatrix.end(); ++it1 ) + { + for ( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 ) + { + QgsPoint c; + double d = distance(it1->first, it2->first, pt, c); + if (d < min) + { + minP1 = it1->first; + minP2 = it2->first; + min = d; + center = c; + } + } + } + if ( min >= infinity() ) + return center; + + double c = mMatrix[ minP1 ][ minP2 ].mCost; + double t = mMatrix[ minP1 ][ minP2 ].mTime; + + double newArcLength = mDistanceArea->measureLine( minP1, center ); + mMatrix[ minP1 ][ center ] = ArcAttributes( newArcLength, t*newArcLength/c, 0); + newArcLength = mDistanceArea->measureLine( center, minP2 ); + mMatrix[ center ][ minP2 ] = ArcAttributes( newArcLength, t*newArcLength/c, 0 ); + + if ( mMatrix[ minP2 ].find( minP1 ) != mMatrix[ minP2 ].end() ) + { + c = mMatrix[ minP2 ][ minP1 ].mCost; + t = mMatrix[ minP2 ][ minP1 ].mTime; + newArcLength = mDistanceArea->measureLine( center, minP1 ); + mMatrix[ center ][ minP1 ] = ArcAttributes( newArcLength, t*newArcLength/c, 0); + newArcLength = mDistanceArea->measureLine( minP2, center ); + mMatrix[ minP2 ][ center ] = ArcAttributes( newArcLength, t*newArcLength/c, 0); + } + + mMatrix[minP1].erase( minP2 ); + mMatrix[minP2].erase( minP1 ); + b = true; + return center; +} + +AdjacencyMatrix RgSimpleGraphBuilder::adjacencyMatrix() +{ + return mMatrix; +} Index: src/plugins/roadgraph/roadgraphplugin.cpp =================================================================== --- src/plugins/roadgraph/roadgraphplugin.cpp (revision 0) +++ src/plugins/roadgraph/roadgraphplugin.cpp (revision 0) @@ -0,0 +1,331 @@ +/*************************************************************************** + roadgraphplugin.cpp - implemention of plugin + -------------------------------------- + Date : 2010-10-10 + Copyright : (C) 2010 by Yakushev Sergey + 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. * +* * +***************************************************************************/ + + +// QGIS Specific includes +#include +#include +#include +#include +#include +#include +#include + +// Road grap plugin includes +#include "roadgraphplugin.h" +#include "shortestpathwidget.h" +#include "settingsdlg.h" +#include "graphdirector.h" +#include "linevectorlayerdirector.h" +#include "simplegraphbuilder.h" + +// +// Qt4 Related Includes +// + +#include +#include +#include +#include +#include +#include +#include +#include + +// standart includes + +static const char * const sIdent = "$Id: plugin.cpp 9327 2009-04-20 10:09:44Z YEKST $"; +static const QString sName = QObject::tr( "Road graph plugin" ); +static const QString sDescription = QObject::tr( "It solve shortest path poblem and etc." ); +static const QString sPluginVersion = QObject::tr( "Version 0.1" ); +static const QgisPlugin::PLUGINTYPE sPluginType = QgisPlugin::UI; + +////////////////////////////////////////////////////////////////////// +// +// THE FOLLOWING METHODS ARE MANDATORY FOR ALL PLUGINS +// +////////////////////////////////////////////////////////////////////// + +/** + * Constructor for the plugin. The plugin is passed a pointer + * an interface object that provides access to exposed functions in QGIS. + * @param theQGisInterface - Pointer to the QGIS interface object + */ +RoadGraphPlugin::RoadGraphPlugin( QgisInterface * theQgisInterface ): + QgisPlugin( sName, sDescription, sPluginVersion, sPluginType ), + mQGisIface( theQgisInterface ) +{ + + mQShortestPathDock = NULL; + mDirector = new RgLineVectorLayerDirector(); + mTimeUnitName = "h"; + mDistanceUnitName = "km"; +} + +RoadGraphPlugin::~RoadGraphPlugin() +{ + +} + +/* + * Initialize the GUI interface for the plugin - this is only called once when the plugin is + * added to the plugin registry in the QGIS application. + */ +void RoadGraphPlugin::initGui() +{ + // create shorttest path dock + mQShortestPathDock = new RgShortestPathWidget( mQGisIface->mainWindow() , this ); + mQGisIface->addDockWidget( Qt::LeftDockWidgetArea, mQShortestPathDock ); + + // 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 roads 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 ); + + 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() ) ); + // load settings + projectRead(); +} // RoadGraphPlugin::initGui() + +// Unload the plugin by cleaning up the GUI +void RoadGraphPlugin::unload() +{ + // remove the GUI + mQGisIface->removePluginMenu( tr("Road graph"), mQSettingsAction ); + mQGisIface->removePluginMenu( tr("Road graph"), mQShowDirectionAction ); + + 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() + +void RoadGraphPlugin::setGuiElementsToDefault() +{ + +} // RoadGraphPlugin::setGuiElementsToDefault() + +//method defined in interface +void RoadGraphPlugin::help() +{ + //implement me! +} // RoadGraphPlugin::help() + +void RoadGraphPlugin::onShowDirection() +{ + mQGisIface->mapCanvas()->refresh(); +} // RoadGraphPlugin::onShowDirection() + + +void RoadGraphPlugin::newProject() +{ + setGuiElementsToDefault(); +} + +void RoadGraphPlugin::property() +{ + RgSettingsDlg dlg(mDirector, mQGisIface->mainWindow(), QgisGui::ModalDialogFlags ); + + dlg.setTimeUnitName( mTimeUnitName ); + dlg.setDistanceUnitName( mDistanceUnitName ); + + if ( !dlg.exec() ) + return; + mTimeUnitName = dlg.timeUnitName(); + mDistanceUnitName = dlg.distanceUnitName(); + + mDirector->settings()->write( QgsProject::instance() ); + QgsProject::instance()->writeEntry( "roadgraphplugin", "/pluginTimeUnit", mTimeUnitName ); + QgsProject::instance()->writeEntry( "roadgraphplugin", "/pluginDistanceUnit", mDistanceUnitName ); + + setGuiElementsToDefault(); +} //RoadGraphPlugin::property() + +void RoadGraphPlugin::about() +{ + QDialog dlg( mQGisIface->mainWindow() ); + dlg.setWindowFlags( dlg.windowFlags() | Qt::MSWindowsFixedSizeDialogHint ); + dlg.setWindowFlags( dlg.windowFlags() &~ Qt::WindowContextHelpButtonHint ); + dlg.setWindowTitle( tr( "About RoadGraph" ) ); + QVBoxLayout *lines = new QVBoxLayout( &dlg ); + QLabel *title = new QLabel( "RoadGraph plugin" ); + title->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter ); + QLabel *version = new QLabel( sPluginVersion ); + version->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter ); + lines->addWidget( title ); + lines->addWidget( version ); + lines->addWidget( new QLabel( tr( "Find shortest path on roads graph" ) ) ); + lines->addWidget( new QLabel( tr( "Developers:" ) ) ); + lines->addWidget( new QLabel( " Sergey Yakushev" ) ); + lines->addWidget( new QLabel( tr( "Link:" ) ) ); + QLabel *link = new QLabel( tr( "http://gis-lab.info" ) ); + link->setOpenExternalLinks( true ); + lines->addWidget( link ); + + dlg.exec(); +} //RoadGraphPlugin::about() + +void RoadGraphPlugin::projectRead() +{ + mDirector->settings()->read( QgsProject::instance() ); + mTimeUnitName = QgsProject::instance()->readEntry( "roadgraphplugin", "/pluginTimeUnit", "h" ); + mDistanceUnitName = QgsProject::instance()->readEntry( "roadgraphplugin", "/pluginDistanceUnit", "km" ); + setGuiElementsToDefault(); +}// RoadGraphplguin::projectRead() + +QgisInterface* RoadGraphPlugin::iface() +{ + return mQGisIface; +} + +const RgGraphDirector* RoadGraphPlugin::director() const +{ + return mDirector; +} +void RoadGraphPlugin::render(QPainter *painter) +{ + if ( mDirector == NULL ) + return; + if ( !mQShowDirectionAction->isChecked() ) + return; + RgSimpleGraphBuilder builder; + builder.setDestinationCrs( mQGisIface->mapCanvas()->mapRenderer()->destinationSrs() ); + mDirector->makeGraph( &builder ); + 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 tmp; + tmp.resize(3); + tmp[0] = QPointF( centerX + Cos*r*2, centerY + Sin*r*2 ); + tmp[1] = pt1; + tmp[2] = pt2; + painter->drawPolygon(tmp); + } + } + +}// RoadGraphPlugin::render() +QString RoadGraphPlugin::timeUnitName() +{ + return mTimeUnitName; +} + +QString RoadGraphPlugin::distanceUnitName() +{ + return mDistanceUnitName; +} + +////////////////////////////////////////////////////////////////////////// +// +// +// THE FOLLOWING CODE IS AUTOGENERATED BY THE PLUGIN BUILDER SCRIPT +// YOU WOULD NORMALLY NOT NEED TO MODIFY THIS, AND YOUR PLUGIN +// MAY NOT WORK PROPERLY IF YOU MODIFY THIS INCORRECTLY +// +// +////////////////////////////////////////////////////////////////////////// + + +/** + * Required extern functions needed for every plugin + * These functions can be called prior to creating an instance + * of the plugin class + */ +// Class factory to return a new instance of the plugin class +QGISEXTERN QgisPlugin * classFactory( QgisInterface * theQgisInterfacePointer ) +{ + return new RoadGraphPlugin( theQgisInterfacePointer ); + +} +// Return the name of the plugin - note that we do not user class members as +// the class may not yet be insantiated when this method is called. +QGISEXTERN QString name() +{ + return sName; +} + +// Return the description +QGISEXTERN QString description() +{ + return sDescription; +} + +// Return the type (either UI or MapLayer plugin) +QGISEXTERN int type() +{ + return sPluginType; +} + +// Return the version number for the plugin +QGISEXTERN QString version() +{ + return sPluginVersion; +} + +// Delete ourself +QGISEXTERN void unload( QgisPlugin * thePluginPointer ) +{ + delete thePluginPointer; +} Index: src/plugins/roadgraph/settingsdlg.cpp =================================================================== --- src/plugins/roadgraph/settingsdlg.cpp (revision 0) +++ src/plugins/roadgraph/settingsdlg.cpp (revision 0) @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sergey Yakushev * + * 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. * + ***************************************************************************/ +//road-graph plugin includes +#include "settingsdlg.h" +#include + +//qt includes +#include +#include +#include +#include +#include +#include + + +// Qgis includes +#include "graphdirector.h" +#include "settings.h" + +//standard includes + +RgSettingsDlg::RgSettingsDlg( RgGraphDirector *director, QWidget* parent, Qt::WFlags fl ) + : mDirector(director), QDialog( parent, fl ) +{ + // create base widgets; + setWindowTitle( tr("Road graph plugins settings") ); + QVBoxLayout *v = new QVBoxLayout( this ); + + QHBoxLayout *h = new QHBoxLayout(); + QLabel *l = new QLabel( tr("Plugins time unit:"), this ); + h->addWidget( l ); + mcbPluginsTimeUnit = new QComboBox( this ); + h->addWidget( mcbPluginsTimeUnit ); + v->addLayout( h ); + + h = new QHBoxLayout(); + l = new QLabel( tr("Plugins distance unit:"), this ); + h->addWidget( l ); + mcbPluginsDistanceUnit = new QComboBox( this ); + h->addWidget( mcbPluginsDistanceUnit ); + v->addLayout( h ); + + /* + h = new QHBoxLayout(); + l = new QLabel( tr("Select graph source:"), this); + h->addWidget(l); + mcbGraphDirector = new QComboBox( this ); + h->addWidget(mcbGraphDirector); + v->addLayout(h); + */ + mSettingsWidget = director->settings()->getGui(this); + v->addWidget( mSettingsWidget ); + + QDialogButtonBox *bb = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); + connect( bb, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()) ); + connect( bb, SIGNAL(rejected()), this, SLOT(on_buttonBox_rejected()) ); + v->addWidget( bb ); + + mcbPluginsTimeUnit->addItem( tr("second"), QVariant( "s" ) ); + mcbPluginsTimeUnit->addItem( tr("hour"), QVariant( "h" ) ); + mcbPluginsDistanceUnit->addItem( tr("meter"), QVariant( "m" ) ); + mcbPluginsDistanceUnit->addItem( tr("kilometer"), QVariant( "km" ) ); + +} // RgSettingsDlg::RgSettingsDlg() + +RgSettingsDlg::~RgSettingsDlg() +{ +} + +void RgSettingsDlg::on_buttonBox_accepted() +{ + mDirector->settings()->setFromGui( mSettingsWidget ); + accept(); +} + +void RgSettingsDlg::on_buttonBox_rejected() +{ + reject(); +} + +void RgSettingsDlg::on_buttonBox_helpRequested() +{ + QgsContextHelp::run( context_id ); +} + +QString RgSettingsDlg::timeUnitName() +{ + return mcbPluginsTimeUnit->itemData( mcbPluginsTimeUnit->currentIndex() ).toString(); +} + +void RgSettingsDlg::setTimeUnitName( const QString& name) +{ + int i = mcbPluginsTimeUnit->findData( QVariant( name ) ); + if (i != -1) + { + mcbPluginsTimeUnit->setCurrentIndex( i ); + } +} + +QString RgSettingsDlg::distanceUnitName() +{ + return mcbPluginsDistanceUnit->itemData( mcbPluginsDistanceUnit->currentIndex() ).toString(); +} + +void RgSettingsDlg::setDistanceUnitName( const QString& name) +{ + int i = mcbPluginsDistanceUnit->findData( QVariant( name ) ); + if (i != -1) + { + mcbPluginsDistanceUnit->setCurrentIndex( i ); + } +} Index: src/plugins/roadgraph/simplegraphbuilder.h =================================================================== --- src/plugins/roadgraph/simplegraphbuilder.h (revision 0) +++ src/plugins/roadgraph/simplegraphbuilder.h (revision 0) @@ -0,0 +1,63 @@ +/*************************************************************************** + simplegraphbuilder.h + -------------------------------------- + Date : 2010-10-25 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_SIMPLEGRAPHBUILDER +#define ROADGRAPH_SIMPLEGRAPHBUILDER + +#include "graphbuilder.h" +#include "utils.h" + +//QT4 includes + +//QGIS includes + +//forward declarations +class QgsDistanceArea; +class QgsCoordinateTransform; + +/** +* \class RgSimpleGraphBuilder +* \brief This class making the simple graph for visualisation +* contained the settings +*/ + +class RgSimpleGraphBuilder : public RgGraphBuilder +{ +public: + /** + * default constructor + */ + RgSimpleGraphBuilder(); + /** + * MANDATORY DIRECTOR PROPERTY DECLARATION + */ + ~RgSimpleGraphBuilder(); + void setSourceCrs( const QgsCoordinateReferenceSystem& crs ); + void setDestinationCrs( const QgsCoordinateReferenceSystem& crs ); + void addVertex( const QgsPoint& pt ); + void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed ); + QgsPoint tiePoint( const QgsPoint& pt, bool& ok ); + + /** + * return Adjacecncy matrix; + */ + AdjacencyMatrix adjacencyMatrix(); +private: + AdjacencyMatrix mMatrix; + + QgsDistanceArea* mDistanceArea; + + QgsCoordinateTransform* mCoordinateTransform; +}; +#endif //SIMPLEGRAPHBUILDER Index: src/plugins/roadgraph/linevectorlayersettings.cpp =================================================================== --- src/plugins/roadgraph/linevectorlayersettings.cpp (revision 0) +++ src/plugins/roadgraph/linevectorlayersettings.cpp (revision 0) @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2009 by Sergey Yakushev * + * 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. * + ***************************************************************************/ + +/** + * \file linevectorlayersettins.cpp + * \brief implementation of RgLineVectorLayerSettings + */ + +#include "linevectorlayersettings.h" +#include "linevectorlayerwidget.h" + +// Qgis includes +#include + +// QT includes +#include +#include +#include + +//standard includes + +RgLineVectorLayerSettings::RgLineVectorLayerSettings() +{ + mLayer = ""; + mDirection = ""; + mDefaultDirection = Both; + mSpeed = ""; + mDefaultSpeed = 40; +} +RgLineVectorLayerSettings::~RgLineVectorLayerSettings() +{ + +} +bool RgLineVectorLayerSettings::test() +{ + // implement me + + // check default speed + if (mDefaultSpeed <= 0.0) + { + return false; + } + if (mLayer == "") + { + return false; + } + // implement me + + return true; +} // RgLineVectorLayerSettings::test() + +void RgLineVectorLayerSettings::read( const QgsProject *project ) +{ + int dd = project->readNumEntry( "roadgraphplugin", "/defaultDirection" ); + mDirection = project->readEntry( "roadgraphplugin", "/directionField" ); + mFirstPointToLastPointDirectionVal = + project->readEntry( "roadgraphplugin", "/FirstPointToLastPointDirectionVal" ); + mLastPointToFirstPointDirectionVal = + project->readEntry( "roadgraphplugin", "/LastPointToFirstPointDirectionVal" ); + mBothDirectionVal = project->readEntry( "roadgraphplugin", "/BothDirectionVal" ); + mSpeed = project->readEntry( "roadgraphplugin", "/speedField" ); + mDefaultSpeed = project->readDoubleEntry( "roadgraphplugin", "/defaultSpeed" ); + mLayer = project->readEntry( "roadgraphplugin", "/layer" ); + mSpeedUnitName= project->readEntry( "roadgraphplugin","/speedUnitName" ); + + if (dd == 1) + { + mDefaultDirection = FirstPointToLastPoint; + } + else if (dd == 2) + { + mDefaultDirection = LastPointToFirstPoint; + } + else if (dd == 3) + { + mDefaultDirection = Both; + } + +} // RgLineVectorLayerSettings::read( const QgsProject *project ) + +void RgLineVectorLayerSettings::write( QgsProject *project ) +{ + project->writeEntry( "roadgraphplugin", "/defaultDirection", mDefaultDirection ); + project->writeEntry( "roadgraphplugin", "/directionField", mDirection ); + project->writeEntry( "roadgraphplugin", "/FirstPointToLastPointDirectionVal", + mFirstPointToLastPointDirectionVal ); + project->writeEntry( "roadgraphplugin", "/LastPointToFirstPointDirectionVal", + mLastPointToFirstPointDirectionVal ); + project->writeEntry( "roadgraphplugin", "/BothDirectionVal", mBothDirectionVal ); + project->writeEntry( "roadgraphplugin", "/speedField", mSpeed ); + project->writeEntry( "roadgraphplugin", "/defaultSpeed", mDefaultSpeed ); + project->writeEntry( "roadgraphplugin", "/layer", mLayer ); + project->writeEntry( "roadgraphplugin", "/speedUnitName", mSpeedUnitName ); +} // RgLineVectorLayerSettings::write( QgsProject *project ) + +QWidget* RgLineVectorLayerSettings::getGui( QWidget *parent ) +{ + return new RgLineVectorLayerSettingsWidget( this, parent ); +} + +void RgLineVectorLayerSettings::setFromGui( QWidget *myGui ) +{ + RgLineVectorLayerSettingsWidget* w = dynamic_cast( myGui ); + if (w == NULL) + return; + + mFirstPointToLastPointDirectionVal = w->mleFirstPointToLastPointDirection->text(); + mLastPointToFirstPointDirectionVal = w->mleLastPointToFirstPointDirection->text(); + mBothDirectionVal = w->mleBothDirection->text(); + mDirection = w->mcbDirection->currentText(); + mLayer = w->mcbLayers->currentText(); + + if ( w->mcbDirectionDefault->currentIndex() == 0 ) + { + mDefaultDirection = Both; + } + else if ( w->mcbDirectionDefault->currentIndex() == 1 ) + { + mDefaultDirection = FirstPointToLastPoint; + } + else if ( w->mcbDirectionDefault->currentIndex() == 2 ) + { + mDefaultDirection = LastPointToFirstPoint; + } + + mSpeed = w->mcbSpeed->currentText(); + mDefaultSpeed = w->msbSpeedDefault->value(); + + if ( w->mcbUnitOfSpeed->currentIndex() == 0 ) + { + mSpeedUnitName = "m/s"; + } + else if ( w->mcbUnitOfSpeed->currentIndex() == 1 ) + { + mSpeedUnitName = "km/h"; + } +} Index: src/plugins/roadgraph/showdirect.svg =================================================================== --- src/plugins/roadgraph/showdirect.svg (revision 0) +++ src/plugins/roadgraph/showdirect.svg (revision 0) @@ -0,0 +1,85 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: src/plugins/roadgraph/roadgraphplugin.h =================================================================== --- src/plugins/roadgraph/roadgraphplugin.h (revision 0) +++ src/plugins/roadgraph/roadgraphplugin.h (revision 0) @@ -0,0 +1,160 @@ +/*************************************************************************** + roadgraphplugin.h + -------------------------------------- + Date : 2010-10-10 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPHPLUGIN +#define ROADGRAPHPLUGIN + +//QT4 includes +#include + +//QGIS includes +#include +#include + +//forward declarations +class QAction; +class QToolBar; +class QPainter; +class QgisInterface; +class QDockWidget; + +//forward declarations RoadGraph plugins classes +class RgGraphDirector; +class RgShortestPathWidget; + +/** +* \class RoadGraphPlugin +* \brief Road graph plugin for QGIS +* This plugin can solve the shotrest path problem and etc... +*/ +class RoadGraphPlugin: public QObject, public QgisPlugin +{ + Q_OBJECT +public: + /** + * Constructor for a plugin. The QgisInterface pointer is passed by + * QGIS when it attempts to instantiate the plugin. + * @param theInterface Pointer to the QgisInterface object. + */ + RoadGraphPlugin( QgisInterface * theInterface ); + //! Destructor + virtual ~RoadGraphPlugin(); + /** + * return pointer to my Interface + */ + QgisInterface *iface(); + + /** + * return pointer to my Graph director + */ + const RgGraphDirector* director() const; + + /** + * get time unit name + */ + QString timeUnitName(); + + /** + * get distance unit name + */ + QString distanceUnitName(); + +public slots: + void render(QPainter *painter); + //! init the gui + virtual void initGui(); + + //!set values onthe gui when a project is read or the gui first loaded + virtual void projectRead(); + + //!set default values for new project + void newProject(); + + //! Show the property dialog box + void property(); + + //! unload the plugin + void unload(); + + //! show the help document + void help(); + + //! show about window + void about(); +private slots: + /** + * set show roads direction + */ + void onShowDirection(); + +private: + /** + * set all gui elements to default status + */ + void setGuiElementsToDefault( ); + +private: + + //////////////////////////////////////////////////////////////////// + // + // MANDATORY PLUGIN PROPERTY DECLARATIONS ..... + // + //////////////////////////////////////////////////////////////////// + int mPluginType; + + //! Pointer to the QGIS interface object + QgisInterface *mQGisIface; + + //////////////////////////////////////////////////////////////////// + // ADD YOUR OWN PROPERTY DECLARATIONS AFTER THIS POINT..... + // + //////////////////////////////////////////////////////////////////// + /** + * on show settings + */ + QAction * mQSettingsAction; + + /** + * pointer ot the direction show action + */ + QAction * mQShowDirectionAction; + + /** + * pointer ot the about action + */ + QAction * mInfoAction; + /** + * GUI for use shortest path finder + */ + RgShortestPathWidget *mQShortestPathDock; + + /** + * My Graph Director + */ + RgGraphDirector *mDirector; + + /** + * time unit for results presentation + */ + QString mTimeUnitName; + + /** + * distance unit for results presentation + */ + QString mDistanceUnitName; +private: + static const int mArrowSize = 5; +}; + +#endif //ROADGRAPHPLUGIN Index: src/plugins/roadgraph/settingsdlg.h =================================================================== --- src/plugins/roadgraph/settingsdlg.h (revision 0) +++ src/plugins/roadgraph/settingsdlg.h (revision 0) @@ -0,0 +1,79 @@ +/*************************************************************************** + roadgraphplugin.h + -------------------------------------- + Date : 2010-10-10 + Copyright : (C) 2010 by Yakushev Sergey + 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 ROADGRAPH_SETTINGSDLG_H +#define ROADGRAPH_SETTINGSDLG_H + +#include + +// forward declaration QT-classes +class QComboBox; + +// forward declaration Qgis-classes + +//forward declaration RoadGraph plugins classes +class RgGraphDirector; + +/** +@author Sergey Yakushev +*/ +/** +* \class RgSettingsDlg +* \brief implement of settings dialog +*/ +class RgSettingsDlg : public QDialog +{ + Q_OBJECT + public: + RgSettingsDlg( RgGraphDirector *director, QWidget* parent = 0, Qt::WFlags fl = 0 ); + ~RgSettingsDlg(); + + QString timeUnitName(); + + void setTimeUnitName( const QString& ); + + QString distanceUnitName(); + + void setDistanceUnitName( const QString& ); + +private: + static const int context_id = 0; + +private slots: + void on_buttonBox_accepted(); + void on_buttonBox_rejected(); + void on_buttonBox_helpRequested(); + +private: + // futurame by used + QComboBox *mcbGraphDirector; + + /** + * current graph director + */ + RgGraphDirector *mDirector; + + QWidget *mSettingsWidget; + + /** + * plugin distance unit + */ + QComboBox *mcbPluginsDistanceUnit; + + /** + * plugin time unit + */ + QComboBox *mcbPluginsTimeUnit; +}; +#endif Index: src/plugins/roadgraph/shortestpathwidget.cpp =================================================================== --- src/plugins/roadgraph/shortestpathwidget.cpp (revision 0) +++ src/plugins/roadgraph/shortestpathwidget.cpp (revision 0) @@ -0,0 +1,334 @@ +/*************************************************************************** + * Copyright (C) 2009 by Sergey Yakushev * + * yakushevs@list.ru * + * * + * This is a plugin generated from the QGIS plugin template * + * * + * 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 shortestpahtwidget.cpp + * \brief implemetation UI for find shotest path + */ + +//qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +// Qgis includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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" + +//standard includes + +RgShortestPathWidget::RgShortestPathWidget( QWidget* theParent, RoadGraphPlugin *thePlugin ) : QDockWidget( theParent ), mPlugin( thePlugin ) +{ + setWindowTitle( tr("Shortest path") ); + setObjectName( "ShortestPathDock" ); + setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); + + QWidget *myWidget = new QWidget(this); + setWidget( myWidget ); + + QVBoxLayout *v = new QVBoxLayout( myWidget ); + QHBoxLayout *h = NULL; + QLabel *l = NULL; + + l = new QLabel(tr("Start:"), myWidget ); + v->addWidget( l ); + h = new QHBoxLayout(); + mFrontPointLineEdit = new QLineEdit( myWidget ); + mFrontPointLineEdit->setReadOnly( true ); + QToolButton *selectFrontPoint = new QToolButton( myWidget ); + selectFrontPoint->setCheckable( true ); + selectFrontPoint->setIcon( QPixmap(":/roadgraph/coordinate_capture.png") ); + h->addWidget( mFrontPointLineEdit ); + h->addWidget( selectFrontPoint ); + v->addLayout(h); + + l = new QLabel(tr("Stop:"), myWidget ); + v->addWidget( l ); + h = new QHBoxLayout(); + mBackPointLineEdit = new QLineEdit( myWidget ); + mBackPointLineEdit->setReadOnly( true ); + QToolButton *selectBackPoint = new QToolButton( myWidget ); + selectBackPoint->setCheckable( true ); + selectBackPoint->setIcon( QPixmap(":/roadgraph/coordinate_capture.png") ); + h->addWidget( mBackPointLineEdit ); + h->addWidget( selectBackPoint ); + v->addLayout( h ); + + h = new QHBoxLayout( this ); + l = new QLabel(tr("Criterion:"), myWidget ); + mCriterionName = new QComboBox( myWidget ); + mCriterionName->insertItem(0, tr("Length")); + mCriterionName->insertItem(1, tr("Time") ); + h->addWidget( l ); + h->addWidget( mCriterionName ); + v->addLayout( h ); + + h = new QHBoxLayout( myWidget ); + l = new QLabel( tr("Length:"), myWidget ); + mPathCostLineEdit = new QLineEdit( myWidget ); + mPathCostLineEdit->setReadOnly ( true ); + h->addWidget( l ); + h->addWidget( mPathCostLineEdit ); + v->addLayout( h ); + + h = new QHBoxLayout( myWidget ); + l = new QLabel( tr("Time:"), myWidget ); + mPathTimeLineEdit = new QLineEdit( myWidget ); + mPathTimeLineEdit->setReadOnly ( true ); + h->addWidget( l ); + h->addWidget( mPathTimeLineEdit ); + v->addLayout( h ); + + h = new QHBoxLayout( myWidget ); + mCalculate = new QPushButton( tr("Calculate"), myWidget ); + h->addWidget( mCalculate ); + QPushButton *pbExport = new QPushButton( tr("Export"), myWidget ); + h->addWidget( pbExport ); + + connect( pbExport, SIGNAL( clicked(bool) ), this, SLOT(exportPath()) ); + + mClear = new QPushButton( tr("Clear"), myWidget ); + h->addWidget( mClear ); + v->addLayout( h ); + v->addStretch(); + + mFrontPointMapTool = new QgsMapToolEmitPoint( mPlugin->iface()->mapCanvas() ); + mFrontPointMapTool->setButton ( selectFrontPoint ); + + mBackPointMapTool = new QgsMapToolEmitPoint( mPlugin->iface()->mapCanvas() ); + mBackPointMapTool->setButton ( selectBackPoint ); + + connect( selectFrontPoint, SIGNAL( clicked(bool) ), this, SLOT( onSelectFrontPoint() ) ); + connect( mFrontPointMapTool, SIGNAL( canvasClicked( const QgsPoint&, Qt::MouseButton ) ), + this, SLOT( setFrontPoint( const QgsPoint& ) ) ); + + connect( selectBackPoint, SIGNAL( clicked(bool) ), this, SLOT( onSelectBackPoint() ) ); + connect( mBackPointMapTool, SIGNAL( canvasClicked( const QgsPoint&, Qt::MouseButton ) ), + this, SLOT( setBackPoint( const QgsPoint& ) ) ); + + connect( mCalculate, SIGNAL(clicked(bool) ), this, SLOT( findingPath() ) ); + connect( mClear, SIGNAL(clicked(bool)), this, SLOT(clear()) ); + + mrbFrontPoint = new QgsRubberBand( mPlugin->iface()->mapCanvas(), true ); + mrbFrontPoint->setColor( Qt::green ); + mrbFrontPoint->setWidth( 2 ); + + mrbBackPoint = new QgsRubberBand( mPlugin->iface()->mapCanvas(), true ); + mrbBackPoint->setColor( Qt::red ); + mrbBackPoint->setWidth( 2 ); + + mrbPath = new QgsRubberBand( mPlugin->iface()->mapCanvas(), false ); + mrbPath->setWidth( 2 ); + + connect(mPlugin->iface()->mapCanvas(), SIGNAL( extentsChanged() ), this, SLOT( mapCanvasExtentsChanged() ) ); + +} //RgShortestPathWidget::RgShortestPathWidget() +RgShortestPathWidget::~RgShortestPathWidget() +{ + delete mFrontPointMapTool; + delete mBackPointMapTool; + + delete mrbFrontPoint; + delete mrbBackPoint; + delete mrbPath; +} //RgShortestPathWidget::~RgShortestPathWidget() + +void RgShortestPathWidget::mapCanvasExtentsChanged() +{ + // update rubberbands + if ( mFrontPointLineEdit->text().length() > 0 ) + setFrontPoint( mFrontPoint ); + if ( mBackPointLineEdit->text().length() > 0 ) + setBackPoint( mBackPoint ); +} + +void RgShortestPathWidget::onSelectFrontPoint() +{ + mPlugin->iface()->mapCanvas()->setMapTool( mFrontPointMapTool ); +} + +void RgShortestPathWidget::setFrontPoint( const QgsPoint& pt ) +{ + mPlugin->iface()->mapCanvas()->unsetMapTool( mFrontPointMapTool ); + mFrontPointLineEdit->setText( QString("(")+QString().setNum(pt.x()) + QString(",") + + QString().setNum(pt.y()) + QString(")") ); + mFrontPoint = pt; + + double mupp = mPlugin->iface()->mapCanvas()->getCoordinateTransform()->mapUnitsPerPixel()*2; + + mrbFrontPoint->reset(true); + mrbFrontPoint->addPoint( QgsPoint( pt.x()-mupp, pt.y()-mupp), false ); + mrbFrontPoint->addPoint( QgsPoint( pt.x()+mupp, pt.y()-mupp), false ); + mrbFrontPoint->addPoint( QgsPoint( pt.x()+mupp, pt.y()+mupp), false ); + mrbFrontPoint->addPoint( QgsPoint( pt.x()-mupp, pt.y()+mupp), true ); + mrbFrontPoint->show(); +} //RgShortestPathWidget::setFrontPoint( const QgsPoint& pt ) + +void RgShortestPathWidget::onSelectBackPoint() +{ + mPlugin->iface()->mapCanvas()->setMapTool( mBackPointMapTool ); +} + +void RgShortestPathWidget::setBackPoint( const QgsPoint& pt ) +{ + mPlugin->iface()->mapCanvas()->unsetMapTool( mBackPointMapTool ); + + mBackPoint = pt; + mBackPointLineEdit->setText( QString("(")+QString().setNum(pt.x()) + QString(",") + + QString().setNum(pt.y()) + QString(")") ); + + double mupp = mPlugin->iface()->mapCanvas()->getCoordinateTransform()->mapUnitsPerPixel()*2; + + mrbBackPoint->reset(true); + mrbBackPoint->addPoint( QgsPoint( pt.x()-mupp, pt.y()-mupp), false ); + mrbBackPoint->addPoint( QgsPoint( pt.x()+mupp, pt.y()-mupp), false ); + mrbBackPoint->addPoint( QgsPoint( pt.x()+mupp, pt.y()+mupp), false ); + mrbBackPoint->addPoint( QgsPoint( pt.x()-mupp, pt.y()+mupp), true ); + mrbBackPoint->show(); +} + +bool RgShortestPathWidget::getPath(AdjacencyMatrix& matrix, QgsPoint& p1, QgsPoint& p2) +{ + if ( mFrontPointLineEdit->text().isNull() || mBackPointLineEdit->text().isNull() ) + return false; + RgSimpleGraphBuilder builder; + builder.setDestinationCrs ( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() ); + mPlugin->director()->makeGraph(&builder); + bool ok; + + p1 = builder.tiePoint(mFrontPoint, ok); + if ( !ok ) + return false; + p2 = builder.tiePoint(mBackPoint, ok); + if ( !ok ) + 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 ); + + return true; +} + +void RgShortestPathWidget::findingPath() +{ + QgsPoint p1, p2; + AdjacencyMatrix 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() ) + { + AdjacencyMatrixString::iterator it2 = it->second.begin(); + if ( it2 == it->second.end() ) + break; + mrbPath->addPoint( it2->first ); + time += it2->second.mTime; + cost += it2->second.mCost; + it = path.find( it2->first ); + } + Unit timeUnit = Unit::byName( mPlugin->timeUnitName() ); + Unit distanceUnit = Unit::byName( mPlugin->distanceUnitName() ); + + mPathCostLineEdit->setText( QString().setNum( cost/distanceUnit.multipler() ) + distanceUnit.name() ); + mPathTimeLineEdit->setText( QString().setNum( time/timeUnit.multipler() ) + timeUnit.name() ); + + mrbPath->setColor( Qt::red ); +} + +void RgShortestPathWidget::clear() +{ + mFrontPointLineEdit->setText(QString()); + mrbFrontPoint->reset(true); + mBackPointLineEdit->setText(QString()); + mrbBackPoint->reset(true); + mrbPath->reset(); +} + +void RgShortestPathWidget::exportPath() +{ + RgExportDlg dlg(this); + if ( !dlg.exec() ) + return; + + QgsPoint p1,p2; + AdjacencyMatrix path; + if ( !getPath( path, p1, p2 ) ) + return; + + QgsVectorLayer *vl = dlg.mapLayer(); + if ( vl == NULL ) + return; + + QgsCoordinateTransform ct( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs(), + 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(); + if ( it2 == it->second.end() ) + break; + points.append( ct.transform( it2->first ) ); + it = path.find( it2->first ); + } + + vl->startEditing(); + QgsFeature f; + f.setGeometry( QgsGeometry::fromPolyline( points ) ); + vl->addFeature( f ); + vl->updateExtents(); + + mPlugin->iface()->mapCanvas()->update(); + +} Index: src/plugins/roadgraph/CMakeLists.txt =================================================================== --- src/plugins/roadgraph/CMakeLists.txt (revision 0) +++ src/plugins/roadgraph/CMakeLists.txt (revision 0) @@ -0,0 +1,57 @@ + +######################################################## +# Files + +SET (VRP_SRCS + roadgraphplugin.cpp + settingsdlg.cpp + units.cpp + utils.cpp + shortestpathwidget.cpp + linevectorlayersettings.cpp + linevectorlayerwidget.cpp + linevectorlayerdirector.cpp + simplegraphbuilder.cpp + exportdlg.cpp +) + +#SET ([pluginlcasename]_UIS [pluginlcasename]guibase.ui) + +SET (VRP_MOC_HDRS + roadgraphplugin.h + settingsdlg.h + shortestpathwidget.h + linevectorlayerwidget.h + exportdlg.h +) +SET (VRP_RCCS roadgraph.qrc) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR} + ../../core + ../../gui + .. + ) +######################################################## +# Build + +QT4_WRAP_CPP (VRP_MOC_SRCS ${VRP_MOC_HDRS}) + +QT4_ADD_RESOURCES(VRP_RCC_SRCS ${VRP_RCCS}) + +ADD_LIBRARY (roadgraphplugin MODULE ${VRP_SRCS} ${VRP_MOC_SRCS} ${VRP_RCC_SRCS}) + + +TARGET_LINK_LIBRARIES(roadgraphplugin + qgis_core + qgis_gui +) + + +######################################################## +# Install + +INSTALL(TARGETS roadgraphplugin + RUNTIME DESTINATION ${QGIS_PLUGIN_DIR} + LIBRARY DESTINATION ${QGIS_PLUGIN_DIR}) + Index: src/plugins/roadgraph/linevectorlayersettings.h =================================================================== --- src/plugins/roadgraph/linevectorlayersettings.h (revision 0) +++ src/plugins/roadgraph/linevectorlayersettings.h (revision 0) @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2010 by Sergey Yakushev * + * yakushevs list.ru * + * * + * This is file define Road graph plugins settings * + * * + * 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_LINEVECTOR_SETTINGS +#define ROADGRAPH_LINEVECTOR_SETTINGS + +#include "settings.h" + +// QT includes +#include + +// Qgis includes + +// standart includes + +// forward declaration Qgis-classes +class QWidget; + +/** +@author Sergey Yakushev +*/ +/** + * \class RgSettings + * \brief This class contained settings for RgLineVectorLayerDirector + */ + +class RgLineVectorLayerSettings: public RgSettings +{ +public: + /** + * \enum DirectionType + * \brief DirectionType enumeration discribe + */ + enum DirectionType { FirstPointToLastPoint=1, LastPointToFirstPoint=2, Both=3 }; + +public: + /** + * default constructor. + */ + RgLineVectorLayerSettings(); + + /** + * destructor + */ + ~RgLineVectorLayerSettings(); +public: + /* + * MANDATORY SETTINGS PROPERTY DECLARATIONS + */ + void write( QgsProject * ); + void read( const QgsProject * ); + bool test(); + QWidget *getGui( QWidget* Parent ); + void setFromGui( QWidget* ); +public: + + /** + * contained Layer name + */ + QString mLayer; + + /** + * contained direction field name + */ + QString mDirection; + + /** + * mDirection field value as first point to last point value + */ + QString mFirstPointToLastPointDirectionVal; + + /** + * mDirection field value as last point to first point value + */ + QString mLastPointToFirstPointDirectionVal; + + /** + * mDirection field value as both direction + */ + QString mBothDirectionVal; + + /** + * contained Default direction + */ + DirectionType mDefaultDirection; + + /** + * contained speed filed name + */ + QString mSpeed; + + /** + * сontained default speed value; + */ + double mDefaultSpeed; + + /* + * name of speed unit + */ + QString mSpeedUnitName; +}; +#endif Index: src/plugins/CMakeLists.txt =================================================================== --- src/plugins/CMakeLists.txt (revision 15052) +++ src/plugins/CMakeLists.txt (working copy) @@ -14,6 +14,7 @@ point_displacement_renderer spatialquery sqlanywhere + roadgraph ) IF (WITH_SPATIALITE)