Skip to content

Commit 464a949

Browse files
committed
fix: LineVectorLayerDirector work incorectly if vector layer contained WKBMultiPolyline geometry
1 parent 38aa771 commit 464a949

File tree

1 file changed

+100
-82
lines changed

1 file changed

+100
-82
lines changed

src/analysis/network/qgslinevectorlayerdirector.cpp

Lines changed: 100 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -147,44 +147,53 @@ void QgsLineVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, c
147147
QgsFeature feature;
148148
while ( vl->nextFeature( feature ) )
149149
{
150-
QgsPoint pt1, pt2;
151-
bool isFirstPoint = true;
152-
QgsPolyline pl = feature.geometry()->asPolyline();
153-
QgsPolyline::iterator pointIt;
154-
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
150+
QgsMultiPolyline mpl;
151+
if ( feature.geometry()->wkbType() == QGis::WKBMultiLineString )
152+
mpl = feature.geometry()->asMultiPolyline();
153+
else if ( feature.geometry()->wkbType() == QGis::WKBLineString )
154+
mpl.push_back( feature.geometry()->asPolyline() );
155+
156+
QgsMultiPolyline::iterator mplIt;
157+
for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
155158
{
156-
pt2 = ct.transform( *pointIt );
157-
points.push_back( pt2 );
158-
159-
if ( !isFirstPoint )
159+
QgsPoint pt1, pt2;
160+
bool isFirstPoint = true;
161+
QgsPolyline::iterator pointIt;
162+
for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
160163
{
161-
int i = 0;
162-
for ( i = 0; i != additionalPoints.size(); ++i )
164+
pt2 = ct.transform( *pointIt );
165+
points.push_back( pt2 );
166+
167+
if ( !isFirstPoint )
163168
{
164-
TiePointInfo info;
165-
if ( pt1 == pt2 )
166-
{
167-
info.mLength = additionalPoints[ i ].sqrDist( pt1 );
168-
info.mTiedPoint = pt1;
169-
}else
169+
int i = 0;
170+
for ( i = 0; i != additionalPoints.size(); ++i )
170171
{
171-
info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(),
172+
TiePointInfo info;
173+
if ( pt1 == pt2 )
174+
{
175+
info.mLength = additionalPoints[ i ].sqrDist( pt1 );
176+
info.mTiedPoint = pt1;
177+
}else
178+
{
179+
info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(),
172180
pt2.x(), pt2.y(), info.mTiedPoint );
173-
}
181+
}
174182

175-
if ( pointLengthMap[ i ].mLength > info.mLength )
176-
{
177-
info.mTiedPoint = info.mTiedPoint ;
178-
info.mFirstPoint = pt1;
179-
info.mLastPoint = pt2;
183+
if ( pointLengthMap[ i ].mLength > info.mLength )
184+
{
185+
info.mTiedPoint = info.mTiedPoint ;
186+
info.mFirstPoint = pt1;
187+
info.mLastPoint = pt2;
180188

181-
pointLengthMap[ i ] = info;
182-
tiedPoint[ i ] = info.mTiedPoint;
189+
pointLengthMap[ i ] = info;
190+
tiedPoint[ i ] = info.mTiedPoint;
191+
}
183192
}
184193
}
194+
pt1 = pt2;
195+
isFirstPoint = false;
185196
}
186-
pt1 = pt2;
187-
isFirstPoint = false;
188197
}
189198
emit buildProgress( ++step, featureCount );
190199
}
@@ -276,71 +285,80 @@ void QgsLineVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, c
276285
}
277286

278287
// begin features segments and add arc to the Graph;
279-
QgsPoint pt1, pt2;
280-
281-
bool isFirstPoint = true;
282-
QgsPolyline pl = feature.geometry()->asPolyline();
283-
QgsPolyline::iterator pointIt;
284-
for ( pointIt = pl.begin(); pointIt != pl.end(); ++pointIt )
288+
QgsMultiPolyline mpl;
289+
if ( feature.geometry()->wkbType() == QGis::WKBMultiLineString )
290+
mpl = feature.geometry()->asMultiPolyline();
291+
else if ( feature.geometry()->wkbType() == QGis::WKBLineString )
292+
mpl.push_back( feature.geometry()->asPolyline() );
293+
294+
QgsMultiPolyline::iterator mplIt;
295+
for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt )
285296
{
286-
pt2 = ct.transform( *pointIt );
287-
288-
if ( !isFirstPoint )
289-
{
290-
std::map< double, QgsPoint > pointsOnArc;
291-
pointsOnArc[ 0.0 ] = pt1;
292-
pointsOnArc[ pt1.sqrDist( pt2 )] = pt2;
297+
QgsPoint pt1, pt2;
293298

294-
for ( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
299+
bool isFirstPoint = true;
300+
QgsPolyline::iterator pointIt;
301+
for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt )
302+
{
303+
pt2 = ct.transform( *pointIt );
304+
305+
if ( !isFirstPoint )
295306
{
296-
if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
307+
std::map< double, QgsPoint > pointsOnArc;
308+
pointsOnArc[ 0.0 ] = pt1;
309+
pointsOnArc[ pt1.sqrDist( pt2 )] = pt2;
310+
311+
for ( pointLengthIt = pointLengthMap.begin(); pointLengthIt != pointLengthMap.end(); ++pointLengthIt )
297312
{
298-
QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
299-
pointsOnArc[ pt1.sqrDist( tiedPoint )] = tiedPoint;
313+
if ( pointLengthIt->mFirstPoint == pt1 && pointLengthIt->mLastPoint == pt2 )
314+
{
315+
QgsPoint tiedPoint = pointLengthIt->mTiedPoint;
316+
pointsOnArc[ pt1.sqrDist( tiedPoint )] = tiedPoint;
317+
}
300318
}
301-
}
302-
303-
std::map< double, QgsPoint >::iterator pointsIt;
304-
QgsPoint pt1;
305-
QgsPoint pt2;
306-
int pt1idx = -1, pt2idx = -1;
307-
bool isFirstPoint = true;
308-
for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
309-
{
310-
pt2 = pointsIt->second;
311-
tmp = my_binary_search( points.begin(), points.end(), pt2, pointCompare );
312-
pt2 = *tmp;
313-
pt2idx = tmp - points.begin();
314319

315-
if ( !isFirstPoint && pt1 != pt2 )
320+
std::map< double, QgsPoint >::iterator pointsIt;
321+
QgsPoint pt1;
322+
QgsPoint pt2;
323+
int pt1idx = -1, pt2idx = -1;
324+
bool isFirstPoint = true;
325+
for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt )
316326
{
317-
double distance = builder->distanceArea()->measureLine( pt1, pt2 );
318-
QVector< QVariant > prop;
319-
QList< QgsArcProperter* >::const_iterator it;
320-
for ( it = mProperterList.begin(); it != mProperterList.end(); ++it )
327+
pt2 = pointsIt->second;
328+
tmp = my_binary_search( points.begin(), points.end(), pt2, pointCompare );
329+
pt2 = *tmp;
330+
pt2idx = tmp - points.begin();
331+
332+
if ( !isFirstPoint && pt1 != pt2 )
321333
{
322-
prop.push_back( (*it)->property( distance, feature ) );
323-
}
334+
double distance = builder->distanceArea()->measureLine( pt1, pt2 );
335+
QVector< QVariant > prop;
336+
QList< QgsArcProperter* >::const_iterator it;
337+
for ( it = mProperterList.begin(); it != mProperterList.end(); ++it )
338+
{
339+
prop.push_back( (*it)->property( distance, feature ) );
340+
}
324341

325-
if ( directionType == 1 ||
326-
directionType == 3 )
327-
{
328-
builder->addArc( pt1idx, pt1, pt2idx, pt2, prop );
329-
}
330-
if ( directionType == 2 ||
331-
directionType == 3 )
332-
{
333-
builder->addArc( pt2idx, pt2, pt1idx, pt1, prop );
342+
if ( directionType == 1 ||
343+
directionType == 3 )
344+
{
345+
builder->addArc( pt1idx, pt1, pt2idx, pt2, prop );
346+
}
347+
if ( directionType == 2 ||
348+
directionType == 3 )
349+
{
350+
builder->addArc( pt2idx, pt2, pt1idx, pt1, prop );
351+
}
334352
}
353+
pt1idx = pt2idx;
354+
pt1 = pt2;
355+
isFirstPoint = false;
335356
}
336-
pt1idx = pt2idx;
337-
pt1 = pt2;
338-
isFirstPoint = false;
339-
}
340-
} // if ( !isFirstPoint )
341-
pt1 = pt2;
342-
isFirstPoint = false;
343-
} // for (it = pl.begin(); it != pl.end(); ++it)
357+
} // if ( !isFirstPoint )
358+
pt1 = pt2;
359+
isFirstPoint = false;
360+
} // for (it = pl.begin(); it != pl.end(); ++it)
361+
}
344362
emit buildProgress( ++step, featureCount );
345363
} // while( vl->nextFeature(feature) )
346364
} // makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints, QVector< QgsPoint >& tiedPoint )

0 commit comments

Comments
 (0)