| 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; | ||
| }; | ||
|
|
| 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; | ||
| }; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| SUBDIRS( network ) | ||
|
|
||
| ############################################################# | ||
| # sources | ||
|
|
||
| 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}) |
| 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 |
| 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 ); | ||
| } |
| 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 |
| 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; | ||
| } |
| 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 |
| 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; | ||
| } |
| 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 |
| 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 |
|---|---|---|
| @@ -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 |
|---|---|---|
| @@ -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 |
|---|---|---|
| @@ -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; | ||
| } |
| 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 |