[QGIS Commit] r15122 - trunk/qgis/src/plugins/roadgraph

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu Feb 3 04:17:05 EST 2011


Author: stopa85
Date: 2011-02-03 01:17:05 -0800 (Thu, 03 Feb 2011)
New Revision: 15122

Added:
   trunk/qgis/src/plugins/roadgraph/graphbuilder.cpp
Modified:
   trunk/qgis/src/plugins/roadgraph/CMakeLists.txt
   trunk/qgis/src/plugins/roadgraph/graphbuilder.h
   trunk/qgis/src/plugins/roadgraph/graphdirector.h
   trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.cpp
   trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.h
   trunk/qgis/src/plugins/roadgraph/roadgraphplugin.cpp
   trunk/qgis/src/plugins/roadgraph/shortestpathwidget.cpp
   trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.cpp
   trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.h
Log:
roadgraph plugin refactoring. Step 1 of 3.

Modified: trunk/qgis/src/plugins/roadgraph/CMakeLists.txt
===================================================================
--- trunk/qgis/src/plugins/roadgraph/CMakeLists.txt	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/CMakeLists.txt	2011-02-03 09:17:05 UTC (rev 15122)
@@ -13,6 +13,7 @@
   linevectorlayerdirector.cpp
   simplegraphbuilder.cpp
   exportdlg.cpp
+  graphbuilder.cpp
 )
 
 #SET ([pluginlcasename]_UIS [pluginlcasename]guibase.ui)

Added: trunk/qgis/src/plugins/roadgraph/graphbuilder.cpp
===================================================================
--- trunk/qgis/src/plugins/roadgraph/graphbuilder.cpp	                        (rev 0)
+++ trunk/qgis/src/plugins/roadgraph/graphbuilder.cpp	2011-02-03 09:17:05 UTC (rev 15122)
@@ -0,0 +1,35 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Sergey Yakushev                                 *
+ *   yakushevs <at >list.ru                                                *
+ *                                                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+/**
+ * \file graphbuilder.cpp
+ * \brief implementation of RgGraphBuilder
+ */
+
+#include "graphbuilder.h"
+
+// Qgis includes
+
+RgGraphBuilder::RgGraphBuilder( const QgsCoordinateReferenceSystem& crs ) :
+  mCrs( crs )
+{
+
+}
+
+RgGraphBuilder::~RgGraphBuilder()
+{
+
+}
+
+QgsCoordinateReferenceSystem& RgGraphBuilder::destinationCrs()
+{
+  return mCrs;
+}

Modified: trunk/qgis/src/plugins/roadgraph/graphbuilder.h
===================================================================
--- trunk/qgis/src/plugins/roadgraph/graphbuilder.h	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/graphbuilder.h	2011-02-03 09:17:05 UTC (rev 15122)
@@ -32,20 +32,18 @@
 class RgGraphBuilder
 {
   public:
+    //! Constructor
+    RgGraphBuilder( const QgsCoordinateReferenceSystem& crs );
+
     //! Destructor
-    virtual ~RgGraphBuilder()
-    {};
+    virtual ~RgGraphBuilder();
+     
     /**
-     * set source CRS
+     * get destinaltion Crs
      */
-    virtual void setSourceCrs( const QgsCoordinateReferenceSystem& crs ) = 0;
-
+    QgsCoordinateReferenceSystem& destinationCrs();
+    
     /**
-     * set destionation CRS
-     */
-    virtual void setDestinationCrs( const QgsCoordinateReferenceSystem& crs ) = 0;
-
-    /**
      * add vertex
      */
     virtual void addVertex( const QgsPoint& pt ) = 0;
@@ -53,16 +51,9 @@
     /**
      * add arc
      */
-    virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed ) = 0;
+    virtual void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed ) = 0;
 
-    /**
-     * tie point
-     * @param pt maps point
-     * @param ok ok = false if tiePoint failed.
-     * @return Graph vertex corresponding pt.
-     * @note: graph can be modified
-     */
-    virtual QgsPoint tiePoint( const QgsPoint &pt, bool &ok ) = 0;
-
+  private:
+    QgsCoordinateReferenceSystem mCrs;
 };
 #endif //GRAPHBUILDER

Modified: trunk/qgis/src/plugins/roadgraph/graphdirector.h
===================================================================
--- trunk/qgis/src/plugins/roadgraph/graphdirector.h	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/graphdirector.h	2011-02-03 09:17:05 UTC (rev 15122)
@@ -21,14 +21,12 @@
 #include <qgsrectangle.h>
 
 //forward declarations
-class RgSettings;
 class RgGraphBuilder;
 
-/**
-* \class RgGraphDirector
-* \brief Determine making the graph
-* contained the settings
-*/
+/** 
+ * \class RgGraphDirector
+ * \brief Determine making the graph
+ */
 class RgGraphDirector
 {
   public:
@@ -36,9 +34,19 @@
     virtual ~RgGraphDirector() { };
 
     /**
-     * get adjacency matrix
+     * Make a graph using RgGraphBuilder
+     *
+     * @param builder   The graph builder
+     *
+     * @param additionalPoints  Vector of points that must be tied to the graph
+     *
+     * @param tiedPoints  Vector of tied points
+     *
+     * @note if tiedPoints[i]==QgsPoint(0.0,0.0) then tied failed.
      */
-    virtual void makeGraph( RgGraphBuilder * ) const = 0;
+    virtual void makeGraph( RgGraphBuilder *builder, 
+                            const QVector< QgsPoint >& additionalPoints, 
+                            QVector< QgsPoint>& tiedPoints ) const = 0;
 
     /**
      * return Director name

Modified: trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.cpp
===================================================================
--- trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.cpp	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.cpp	2011-02-03 09:17:05 UTC (rev 15122)
@@ -24,12 +24,12 @@
 #include <qgsvectordataprovider.h>
 #include <qgspoint.h>
 #include <qgsgeometry.h>
+#include <qgsdistancearea.h>
 
 // QT includes
 #include <QString>
 
 //standard includes
-#include <iostream>
 
 RgLineVectorLayerDirector::RgLineVectorLayerDirector( const QString& layerId,
     int directionFieldId,
@@ -61,15 +61,64 @@
   return QString( "Vector line" );
 }
 
-void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
+void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder, const QVector< QgsPoint >& additionalPoints, 
+    QVector< QgsPoint >& tiedPoint ) const
 {
   QgsVectorLayer *vl = myLayer();
 
   if ( vl == NULL )
     return;
+  
+  QgsCoordinateTransform ct( vl->crs(), builder->destinationCrs() );
+  
+  QgsDistanceArea da;
+  da.setSourceCrs( builder->destinationCrs().srsid() );
+  da.setProjectionsEnabled( true );
 
-  builder->setSourceCrs( vl->crs() );
+  tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint(0.0, 0.0) );
+  TiePointInfo tmpInfo;
+  tmpInfo.mLength = infinity();
+
+  QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
+  QVector< TiePointInfo >::iterator pointLengthIt;
+
+  // begin: tie points to the graph
   QgsAttributeList la;
+  vl->select( la );
+  QgsFeature feature;
+  while ( vl->nextFeature( feature ) )
+  {
+    QgsPoint pt1, pt2;
+    bool isFirstPoint = true;
+    QgsPolyline pl = feature.geometry()->asPolyline();
+    QgsPolyline::iterator pointIt;
+    for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
+    {
+      pt2 = ct.transform( *pointIt );
+      if ( !isFirstPoint )
+      {
+        int i=0;
+        for ( i = 0; i != additionalPoints.size(); ++i )
+        {
+          TiePointInfo info;
+          info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), info.mTiedPoint );
+          
+          if ( pointLengthMap[ i ].mLength > info.mLength )
+          {
+            info.mFirstPoint = pt1;
+            info.mLastPoint = pt2;
+
+            pointLengthMap[ i ] = info;
+            tiedPoint[ i ] = info.mTiedPoint;
+          }
+        }
+      }
+      pt1 = pt2;
+      isFirstPoint = false;
+    }
+  }
+  // end: tie points to graph
+
   if ( mDirectionFieldId != -1 )
   {
     la.push_back( mDirectionFieldId );
@@ -81,8 +130,8 @@
 
   SpeedUnit su = SpeedUnit::byName( mSpeedUnitName );
 
+  // begin graph construction
   vl->select( la );
-  QgsFeature feature;
   while ( vl->nextFeature( feature ) )
   {
     QgsAttributeMap attr = feature.attributeMap();
@@ -132,20 +181,48 @@
     QgsPolyline::iterator pointIt;
     for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
     {
-      pt2 = *pointIt;
-      if ( !isFirstPoint )
+      pt2 = ct.transform( *pointIt );
+      
+      std::map< double, QgsPoint > pointsOnArc;
+      pointsOnArc[ 0.0 ] = pt1;
+      pointsOnArc[ pt1.sqrDist( pt2 ) ] = pt2;
+
+      for( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
       {
-        if ( directionType == 1 ||
-             directionType  == 3 )
+        if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
         {
-          builder->addArc( pt1, pt2, speed*su.multipler() );
+          QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
+          pointsOnArc[ pt1.sqrDist( tiedPoint ) ] = tiedPoint;
         }
-        if ( directionType == 2 ||
-             directionType == 3 )
+      }
+
+      if ( !isFirstPoint )
+      {
+        std::map< double, QgsPoint >::iterator pointsIt;
+        QgsPoint pt1;
+        QgsPoint pt2;
+        bool isFirstPoint = true;
+        for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
         {
-          builder->addArc( pt2, pt1, speed*su.multipler() );
-        }
-      }
+          pt2 = pointsIt->second;
+          if ( !isFirstPoint )
+          {
+            double cost = da.measureLine( pt1, pt2 ); 
+            if ( directionType == 1 ||
+                 directionType == 3 )
+            {
+              builder->addArc( pt1, pt2, cost, speed*su.multipler() );
+            }
+            if ( directionType == 2 || 
+                 directionType == 3 )
+            {
+              builder->addArc( pt2, pt1, cost, speed*su.multipler() );
+            }
+          }
+          pt1 = pt2;
+          isFirstPoint = false;
+        }  
+      } // if ( !isFirstPoint )
       pt1 = pt2;
       isFirstPoint = false;
     } // for (it = pl.begin(); it != pl.end(); ++it)

Modified: trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.h
===================================================================
--- trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.h	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/linevectorlayerdirector.h	2011-02-03 09:17:05 UTC (rev 15122)
@@ -32,6 +32,14 @@
 */
 class RgLineVectorLayerDirector : public RgGraphDirector
 {
+  private:
+    struct TiePointInfo
+    {
+      QgsPoint mTiedPoint;
+      double mLength;
+      QgsPoint mFirstPoint;
+      QgsPoint mLastPoint;
+    };
   public:
     RgLineVectorLayerDirector( const QString& layerId,
                                int directionFiledId,
@@ -48,8 +56,10 @@
     /**
      * MANDATORY DIRECTOR PROPERTY DECLARATION
      */
-    void makeGraph( RgGraphBuilder * ) const;
-
+    void makeGraph( RgGraphBuilder *builder, 
+                    const QVector< QgsPoint >& additionalPoints,
+                    QVector< QgsPoint>& tiedPoints ) const;
+ 
     QString name() const;
 
   private:

Modified: trunk/qgis/src/plugins/roadgraph/roadgraphplugin.cpp
===================================================================
--- trunk/qgis/src/plugins/roadgraph/roadgraphplugin.cpp	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/roadgraphplugin.cpp	2011-02-03 09:17:05 UTC (rev 15122)
@@ -296,9 +296,9 @@
   if ( graphDirector == NULL )
     return;
 
-  RgSimpleGraphBuilder builder;
-  builder.setDestinationCrs( mQGisIface->mapCanvas()->mapRenderer()->destinationSrs() );
-  graphDirector->makeGraph( &builder );
+  RgSimpleGraphBuilder builder ( mQGisIface->mapCanvas()->mapRenderer()->destinationSrs() );
+  QVector< QgsPoint > null;
+  graphDirector->makeGraph( &builder , null, null );
   AdjacencyMatrix m = builder.adjacencyMatrix();
 
   AdjacencyMatrix::iterator it1;

Modified: trunk/qgis/src/plugins/roadgraph/shortestpathwidget.cpp
===================================================================
--- trunk/qgis/src/plugins/roadgraph/shortestpathwidget.cpp	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/shortestpathwidget.cpp	2011-02-03 09:17:05 UTC (rev 15122)
@@ -223,8 +223,7 @@
 {
   if ( mFrontPointLineEdit->text().isNull() || mBackPointLineEdit->text().isNull() )
     return false;
-  RgSimpleGraphBuilder builder;
-  builder.setDestinationCrs( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() );
+  RgSimpleGraphBuilder builder( mPlugin->iface()->mapCanvas()->mapRenderer()->destinationSrs() );
   {
     const RgGraphDirector *director = mPlugin->director();
     if ( director == NULL )
@@ -232,22 +231,25 @@
       QMessageBox::critical( this, tr( "Plugin isn't configured" ), tr( "Plugin isn't configured!" ) );
       return false;
     }
-    director->makeGraph( &builder );
+    QVector< QgsPoint > points;
+    QVector< QgsPoint > tiedPoint;
+    
+    points.push_back( mFrontPoint );
+    points.push_back( mBackPoint  );
 
+    director->makeGraph( &builder, points, tiedPoint );
+    p1 = tiedPoint[ 0 ];
+    p2 = tiedPoint[ 1 ];
     // not need
     delete director;
   }
 
-  bool ok;
-
-  p1 = builder.tiePoint( mFrontPoint, ok );
-  if ( !ok )
+  if ( p1 == QgsPoint(0.0, 0.0) )
   {
     QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Start point doesn't tie to the road!" ) );
     return false;
   }
-  p2 = builder.tiePoint( mBackPoint, ok );
-  if ( !ok )
+  if ( p1 == QgsPoint(0.0, 0.0) )
   {
     QMessageBox::critical( this, tr( "Tie point failed" ), tr( "Stop point doesn't tie to the road!" ) );
     return false;

Modified: trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.cpp
===================================================================
--- trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.cpp	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.cpp	2011-02-03 09:17:05 UTC (rev 15122)
@@ -1,6 +1,6 @@
 /***************************************************************************
  *   Copyright (C) 2010 by Sergey Yakushev                                 *
- *   yakushevs at list.ru                                                     *
+ *   yakushevs <at> list.ru                                                *
  *                                                                         *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -18,101 +18,22 @@
 #include "utils.h"
 
 // Qgis includes
-#include <qgscoordinatetransform.h>
-#include <qgsdistancearea.h>
 
-#include <iostream>
-
-RgSimpleGraphBuilder::RgSimpleGraphBuilder()
+RgSimpleGraphBuilder::RgSimpleGraphBuilder( const QgsCoordinateReferenceSystem& crs ) :
+  RgGraphBuilder( crs )
 {
-  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 )];
+  mMatrix[ pt ];
 }
 
-void RgSimpleGraphBuilder::addArc( const QgsPoint& pt1, const QgsPoint& pt2, double speed )
+void RgSimpleGraphBuilder::addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, 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 );
+  mMatrix[ pt1 ][ pt2 ] = ArcAttributes( cost, cost / speed, 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;

Modified: trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.h
===================================================================
--- trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.h	2011-02-02 21:11:36 UTC (rev 15121)
+++ trunk/qgis/src/plugins/roadgraph/simplegraphbuilder.h	2011-02-03 09:17:05 UTC (rev 15122)
@@ -37,26 +37,19 @@
     /**
      * default constructor
      */
-    RgSimpleGraphBuilder();
+    RgSimpleGraphBuilder( const QgsCoordinateReferenceSystem& crs );
+  
     /**
-     * MANDATORY DIRECTOR PROPERTY DECLARATION
+     * MANDATORY BUILDER 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 );
-
+    void addArc( const QgsPoint& pt1, const QgsPoint& pt2, double cost, double speed );
+    
     /**
      * return Adjacecncy matrix;
      */
     AdjacencyMatrix adjacencyMatrix();
   private:
     AdjacencyMatrix mMatrix;
-
-    QgsDistanceArea* mDistanceArea;
-
-    QgsCoordinateTransform* mCoordinateTransform;
 };
 #endif //SIMPLEGRAPHBUILDER



More information about the QGIS-commit mailing list