29 #include <QtAlgorithms>
39 mTolerance( tolerance )
44 if ( mTolerance <= 0 )
45 return p1.
x() == p2.
x() ? p1.
y() < p2.
y() : p1.
x() < p2.
x();
47 double tx1 = ceil( p1.
x() / mTolerance );
48 double tx2 = ceil( p2.
x() / mTolerance );
50 return ceil( p1.
y() / mTolerance ) < ceil( p2.
y() / mTolerance );
58 template <
typename RandIter,
typename Type,
typename CompareOp > RandIter
my_binary_search( RandIter begin, RandIter end, Type val, CompareOp comp )
61 RandIter not_found = end;
65 RandIter avg = begin + ( end - begin ) / 2;
66 if ( begin == avg || end == avg )
68 if ( !comp( *begin, val ) && !comp( val, *begin ) )
70 if ( !comp( *end, val ) && !comp( val, *end ) )
75 if ( comp( val, *avg ) )
77 else if ( comp( *avg, val ) )
103 int directionFieldId,
104 const QString& directDirectionValue,
105 const QString& reverseDirectionValue,
106 const QString& bothDirectionValue,
110 mVectorLayer = myLayer;
111 mDirectionFieldId = directionFieldId;
112 mDirectDirectionValue = directDirectionValue;
113 mReverseDirectionValue = reverseDirectionValue;
114 mDefaultDirection = defaultDirection;
115 mBothDirectionValue = bothDirectionValue;
125 return QString(
"Vector line" );
129 QVector< QgsPoint >& tiedPoint )
const
150 tiedPoint = QVector< QgsPoint >( additionalPoints.size(),
QgsPoint( 0.0, 0.0 ) );
153 tmpInfo.
mLength = std::numeric_limits<double>::infinity();
155 QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo );
156 QVector< TiePointInfo >::iterator pointLengthIt;
159 QVector< QgsPoint > points;
174 QgsMultiPolyline::iterator mplIt;
175 for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
178 bool isFirstPoint =
true;
179 QgsPolyline::iterator pointIt;
180 for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
183 points.push_back( pt2 );
188 for ( i = 0; i != additionalPoints.size(); ++i )
193 info.
mLength = additionalPoints[ i ].sqrDist( pt1 );
198 info.
mLength = additionalPoints[ i ].sqrDistToSegment( pt1.
x(), pt1.
y(),
202 if ( pointLengthMap[ i ].mLength > info.
mLength )
208 pointLengthMap[ i ] = info;
214 isFirstPoint =
false;
223 for ( i = 0; i < tiedPoint.size(); ++i )
225 if ( tiedPoint[ i ] !=
QgsPoint( 0.0, 0.0 ) )
227 points.push_back( tiedPoint [ i ] );
233 qSort( points.begin(), points.end(), pointCompare );
234 QVector< QgsPoint >::iterator tmp = std::unique( points.begin(), points.end() );
235 points.resize( tmp - points.begin() );
237 for ( i = 0;i < points.size();++i )
240 for ( i = 0; i < tiedPoint.size() ; ++i )
241 tiedPoint[ i ] = *(
my_binary_search( points.begin(), points.end(), tiedPoint[ i ], pointCompare ) );
248 if ( mDirectionFieldId != -1 )
250 tmpAttr.push_back( mDirectionFieldId );
253 QList< QgsArcProperter* >::const_iterator it;
254 QgsAttributeList::const_iterator it2;
259 for ( it2 = tmp.begin(); it2 != tmp.end(); ++it2 )
261 tmpAttr.push_back( *it2 );
264 qSort( tmpAttr.begin(), tmpAttr.end() );
267 for ( it2 = tmpAttr.begin(); it2 != tmpAttr.end(); ++it2 )
269 if ( *it2 == lastAttrId )
274 la.push_back( *it2 );
284 int directionType = mDefaultDirection;
287 QString str = feature.
attribute( mDirectionFieldId ).toString();
288 if ( str == mBothDirectionValue )
292 else if ( str == mDirectDirectionValue )
296 else if ( str == mReverseDirectionValue )
308 QgsMultiPolyline::iterator mplIt;
309 for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
313 bool isFirstPoint =
true;
314 QgsPolyline::iterator pointIt;
315 for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
321 std::map< double, QgsPoint > pointsOnArc;
322 pointsOnArc[ 0.0 ] = pt1;
323 pointsOnArc[ pt1.
sqrDist( pt2 )] = pt2;
330 if ( pointLengthIt != pointLengthMap.end() )
332 QVector< TiePointInfo >::iterator it;
333 for ( it = pointLengthIt; it - pointLengthMap.begin() >= 0; --it )
335 if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 )
337 pointsOnArc[ pt1.
sqrDist( it->mTiedPoint )] = it->mTiedPoint;
340 for ( it = pointLengthIt + 1; it != pointLengthMap.end(); ++it )
342 if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 )
344 pointsOnArc[ pt1.
sqrDist( it->mTiedPoint )] = it->mTiedPoint;
349 std::map< double, QgsPoint >::iterator pointsIt;
352 int pt1idx = -1, pt2idx = -1;
353 bool isFirstPoint =
true;
354 for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
356 pt2 = pointsIt->second;
359 pt2idx = tmp - points.begin();
361 if ( !isFirstPoint && pt1 != pt2 )
364 QVector< QVariant > prop;
365 QList< QgsArcProperter* >::const_iterator it;
368 prop.push_back(( *it )->property( distance, feature ) );
371 if ( directionType == 1 ||
374 builder->
addArc( pt1idx, pt1, pt2idx, pt2, prop );
376 if ( directionType == 2 ||
379 builder->
addArc( pt2idx, pt2, pt1idx, pt1, prop );
384 isFirstPoint =
false;
388 isFirstPoint =
false;