2424#include < qgsvectordataprovider.h>
2525#include < qgspoint.h>
2626#include < qgsgeometry.h>
27+ #include < qgsdistancearea.h>
2728
2829// QT includes
2930#include < QString>
3031
3132// standard includes
32- #include < iostream>
3333
3434RgLineVectorLayerDirector::RgLineVectorLayerDirector ( const QString& layerId,
3535 int directionFieldId,
@@ -61,15 +61,64 @@ QString RgLineVectorLayerDirector::name() const
6161 return QString ( " Vector line" );
6262}
6363
64- void RgLineVectorLayerDirector::makeGraph ( RgGraphBuilder *builder ) const
64+ void RgLineVectorLayerDirector::makeGraph ( RgGraphBuilder *builder, const QVector< QgsPoint >& additionalPoints,
65+ QVector< QgsPoint >& tiedPoint ) const
6566{
6667 QgsVectorLayer *vl = myLayer ();
6768
6869 if ( vl == NULL )
6970 return ;
71+
72+ QgsCoordinateTransform ct ( vl->crs (), builder->destinationCrs () );
73+
74+ QgsDistanceArea da;
75+ da.setSourceCrs ( builder->destinationCrs ().srsid () );
76+ da.setProjectionsEnabled ( true );
7077
71- builder->setSourceCrs ( vl->crs () );
78+ tiedPoint = QVector< QgsPoint >( additionalPoints.size (), QgsPoint (0.0 , 0.0 ) );
79+ TiePointInfo tmpInfo;
80+ tmpInfo.mLength = infinity ();
81+
82+ QVector< TiePointInfo > pointLengthMap ( additionalPoints.size (), tmpInfo );
83+ QVector< TiePointInfo >::iterator pointLengthIt;
84+
85+ // begin: tie points to the graph
7286 QgsAttributeList la;
87+ vl->select ( la );
88+ QgsFeature feature;
89+ while ( vl->nextFeature ( feature ) )
90+ {
91+ QgsPoint pt1, pt2;
92+ bool isFirstPoint = true ;
93+ QgsPolyline pl = feature.geometry ()->asPolyline ();
94+ QgsPolyline::iterator pointIt;
95+ for ( pointIt = pl.begin (); pointIt != pl.end (); ++pointIt )
96+ {
97+ pt2 = ct.transform ( *pointIt );
98+ if ( !isFirstPoint )
99+ {
100+ int i=0 ;
101+ for ( i = 0 ; i != additionalPoints.size (); ++i )
102+ {
103+ TiePointInfo info;
104+ info.mLength = additionalPoints[ i ].sqrDistToSegment ( pt1.x (), pt1.y (), pt2.x (), pt2.y (), info.mTiedPoint );
105+
106+ if ( pointLengthMap[ i ].mLength > info.mLength )
107+ {
108+ info.mFirstPoint = pt1;
109+ info.mLastPoint = pt2;
110+
111+ pointLengthMap[ i ] = info;
112+ tiedPoint[ i ] = info.mTiedPoint ;
113+ }
114+ }
115+ }
116+ pt1 = pt2;
117+ isFirstPoint = false ;
118+ }
119+ }
120+ // end: tie points to graph
121+
73122 if ( mDirectionFieldId != -1 )
74123 {
75124 la.push_back ( mDirectionFieldId );
@@ -81,8 +130,8 @@ void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
81130
82131 SpeedUnit su = SpeedUnit::byName ( mSpeedUnitName );
83132
133+ // begin graph construction
84134 vl->select ( la );
85- QgsFeature feature;
86135 while ( vl->nextFeature ( feature ) )
87136 {
88137 QgsAttributeMap attr = feature.attributeMap ();
@@ -132,20 +181,48 @@ void RgLineVectorLayerDirector::makeGraph( RgGraphBuilder *builder ) const
132181 QgsPolyline::iterator pointIt;
133182 for ( pointIt = pl.begin (); pointIt != pl.end (); ++pointIt )
134183 {
135- pt2 = *pointIt;
136- if ( !isFirstPoint )
184+ pt2 = ct.transform ( *pointIt );
185+
186+ std::map< double , QgsPoint > pointsOnArc;
187+ pointsOnArc[ 0.0 ] = pt1;
188+ pointsOnArc[ pt1.sqrDist ( pt2 ) ] = pt2;
189+
190+ for ( pointLengthIt = pointLengthMap.begin (); pointLengthIt != pointLengthMap.end (); ++pointLengthIt )
137191 {
138- if ( directionType == 1 ||
139- directionType == 3 )
140- {
141- builder->addArc ( pt1, pt2, speed*su.multipler () );
142- }
143- if ( directionType == 2 ||
144- directionType == 3 )
192+ if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
145193 {
146- builder->addArc ( pt2, pt1, speed*su.multipler () );
194+ QgsPoint tiedPoint = pointLengthIt->mTiedPoint ;
195+ pointsOnArc[ pt1.sqrDist ( tiedPoint ) ] = tiedPoint;
147196 }
148197 }
198+
199+ if ( !isFirstPoint )
200+ {
201+ std::map< double , QgsPoint >::iterator pointsIt;
202+ QgsPoint pt1;
203+ QgsPoint pt2;
204+ bool isFirstPoint = true ;
205+ for ( pointsIt = pointsOnArc.begin (); pointsIt != pointsOnArc.end (); ++pointsIt )
206+ {
207+ pt2 = pointsIt->second ;
208+ if ( !isFirstPoint )
209+ {
210+ double cost = da.measureLine ( pt1, pt2 );
211+ if ( directionType == 1 ||
212+ directionType == 3 )
213+ {
214+ builder->addArc ( pt1, pt2, cost, speed*su.multipler () );
215+ }
216+ if ( directionType == 2 ||
217+ directionType == 3 )
218+ {
219+ builder->addArc ( pt2, pt1, cost, speed*su.multipler () );
220+ }
221+ }
222+ pt1 = pt2;
223+ isFirstPoint = false ;
224+ }
225+ } // if ( !isFirstPoint )
149226 pt1 = pt2;
150227 isFirstPoint = false ;
151228 } // for (it = pl.begin(); it != pl.end(); ++it)
0 commit comments